Web Application Ideals

My ideal philosophy for Web application design is as follows:

The entire application exists on a single page, which loads once after the user logs in. All HTML is sent to the client at this point. All further interaction between the user (client) and the server is in the form of JSON data which is sent back and forth. This data generally doesn’t contain HTML or any specific formatting information; that was already sent over either in the form of HTML templates, or else rendered dynamically by Javascript code, which constructs specific widgets. For example, a textual screen with fields in specific places is sent as an HTML template, and the data for the template’s fields are sent as a separate JSON data block. Javascript on the client side is responsible for rendering the template and putting it up on screen. Certain fields in the template may reference sub-templates or more advanced widgets, such as sortable data tables, and the data, which was received through JSON, is rendered into the appropriate presentation and inserted into the template as needed.

As the user navigates from screen to screen, the hash portion of the URL is updated, enabling the browser’s Back button and bookmark functionality.

For an application with many screens, where loading all screens at the beginning before showing anything to the user would cause too much of a wait, the application can load sets of screens in the background once the initial set of screens is loaded and displayed.

A screen template may include more than just HTML with fields denoted; it may include Javascript code which is specific to rendering that screen. The code can then be eval’ed in order to add the requisite functions to the app’s codebase.

As a user is editing data, the browser should frequently send save-state information to the server, so as to prevent data loss in the event of a browser crash or connection-lost condition. On subsequent login, the user’s data should always be recoverable.

On the server side, the server is very data-centric and knows very little about the application’s UI structure. It just handles requests for data, and responds with it, given that the authenticated user has the relevant permissions. It has handlers which can respond with many forms of data. The server’s handlers are flexible and can respond to a single request which requires data gathered from many sources: this way, the UI’s data needs don’t need to be tied too closely to the handlers which satisfy them. In fact the term source would be better than handler. A true handler, on the other hand, may handle requests to update data.

To be continued…

Firefox Cruft

Over time, as I’ve added and removed extensions, it seems that Firefox (which wasn’t all that fast to begin with) has been getting slower and slower. Windows users (myself included) are familiar with the effect, where garbage builds up in the registry, since most uninstallers are far from perfect. What’s the incentive for a software creator to write a good solid uninstall program, anyway? Or to debug their uninstall utility beyond the minimum? Perhaps many do (and most software uses generic installer/uninstaller systems, anyway), like the Nullsoft Install System (used by Google), or IntelliShield (you used to see that one a lot), but that doesn’t mean that the software vendor’s configured the (un)installer system properly with the correct list of files and keys to remove, etc. (This is why I maintain that it should be the OS’s responsibility to manage installation and removal of software in an automated way, like a neutral third party, tracking exactly what is added and changed in an installation, so that those same things can be uninstalled completely later. And if it’s one of those “easier said than done” things, it certainly shouldn’t be left to the whim of random software vendors.) Maybe most software uninstalls itself completely, but over an OS’s lifecycle there are plenty of instances where something goes wrong and useless files, registry keys and other junk gets left around. Same thing with Firefox. A clean profile, like a clean Windows install, is lean and fast. But if I take my existing profile and uninstall all of the extensions, I still get those odd half-second-long freeze-ups every 10 seconds or so (despite having disabled session/crash protection and history), and creating a new tab with Ctrl+T induces a several-second freeze, and so on. Tolerable, but could be better.

Just like the Windows registry problem, when I type “about:config” into the browser’s location bar, I see tons of preferences listed for extensions which are long gone, but there’s no interface in the browser to remove said preferences from the list. Instead, you can open prefs.js in your profile folder, and delete unnecessary items. I got rid of about half the stuff in my prefs.js file, and Firefox seems a bit faster, but it’s still freezing every once in a while as I type. Oh well.

The Internet is My Playground

I recently had Cable Internet installed, which clocks in between 3 and 4 mbps on the download side. Much better than DSL, which would randomly stop working for 1-minute intervals at least a few times a night. This is Comcast’s RoadRunner service, which I’m pretty happy with so far. Six month introductory period at $20 per month, after which it gets expensive, but I’ll deal with that later. It’s been my experience, then, that Cable technology (ignoring the price) is very much superior to DSL.

The installation itself was a highly participatory experience, since the technician couldn’t even type on my computer (good old Dvorak layout), let alone figure out how to decrease Internet Explorer’s security settings so that the “account activation software” could run. Really, all that did was figure out my computer’s MAC address and enter that into the server’s database to allow the cable modem to pull an IP address. This could have been done through a simple Web form, or even over the phone.

DHTML Grid

I’m not that impressed with this DHTML grid widget: It’s intended as a generic editable table which shows data in a Web browser, using JavaScript to control all user interaction client-side. I’m working on something similar which allows easy form generation straight out of a MySQL database, gathering as much data as possible from the database itself (by querying MySQL for column data type, keys, etc.). Anyway, I’ve given a lot of thought to how the interface should work, and what I like to provide the most efficient and logical “data editing experience”. Problems with this demo are:

  1. I don’t like having to double-click to edit a cell. What’s wrong with single click?
  2. The cell type is not clear before clicking on it. For example, the Book Title column is apparently a text field since it’s editable in-cell. But the Author column opens a small text-area, however without a visible cursor.
  3. The Shipping dropdown does not render as a true drop-down box (one row high, with a drop-down showing the excell options), rather a list box (overlayed on top of the other elements). This is a problem I ran into as well, though: apparently there is no DHTML function which will tell a list box to open up; it has to be manually clicked by the user. Maybe it’s possible to simulate a “click” event and send it to the list box element.
  4. If I open a list box by double-clicking one of the cells under Shipping, and then scroll the whole table from side to side usings its scrollbar, the list box showing the shipping options stays in place relative to the browser window, not the frame in which the table is shown. You can end up with a dropdown box not positioned over the element whose choices it’s showing.
  5. Why does clicking in a cell with a checkbox not check the box? Instead one needs to click exactly in the checkbox. Clicking in the rest of the cell area just moves the current row highlight, which is not useful.
  6. It’s not possible to edit the Date of Publication field. I would think that showing off a date-editing widget is an important piece of functionality, since there are so many ways to go about this. For example, I could be given a cursor to edit the text of the date directly, or separate dropdowns for year/month/day, or a small pop-up calendar overlay, and so on.
  7. Tab functionality doesn’t work properly. Half of the time, Tab will take me to the next element, but ofter it will start moving the focus to other links on the page or browser menu options.
  8. The current row is highlighted, but the focused cell is not.

On the other hand, their Tree and Tab-bar widgets seem pretty nice. It’s just the grid that’s poorly designed.

Writely So

“Writely”:http://www.writely.com is incredible. I’m not sure if I’m doing myself a tiny disservice by posting this here, because the servers can’t possibly remain as fast as they are after the site catches on like wildfire and their userbase (all your userbase are belong to us) explodes. This is combined with the fact that while editing a document, it auto-saves itself back to the server every ten seconds, which must generate a gazillion (not quite a googol, although note that Google recently bought Writely) hits. Anyway, in the span of a couple days, I’m now keeping track of almost everything in Writely documents. For work, I can create a document for each project we’re working on and type notes related to the project; my coworkers can read and maintain their own notes simultaneously. Finding and opening documents is also much faster than doing so within the operating system, since they’re all just right there in one place and there’s no Word-like startup time; a document just loads in a new window/tab right away. There’s no Word-like concept of a printed page or page-width forced on you; the default typing mode is much like opening a blank Notepad.exe instance and typing in it. Although unlike Notepad, Writely saves often and makes it easy to manage files. I haven’t relied much on the automatic revision tracking feature yet, but I’m sure that’ll come in handy down the line, too.

Incidentally, I just noticed something interesting. I’m typing this, you might imagine, in Writely itself. I’m using Firefox and happen to have Firebug enabled. So I see the periodic POST requests being sent to the server to support the ten-second autosave. Instead of saving my whole document, each request sends just the text I’ve added or changed since last autosave. Of course you know it has to work that way when you think about it, but I wouldn’t have thought to think about something like that in the first place.

Testing the Rails, Part II

(Still not seeing the world through ruby-tinted glasses.)

Argh. Killed another few hours on the below problem with no progress. Or rather, maybe a miniscule bit of progress. It seems that after I start the WEBrick server, the very first page load sees the database, but no additional hits do. I can connect to the “new” function in my test controller and see a “create” button there along with fields it’s pulled out of the database. However on refreshing the page or selecting anything, the same old error (mysql.o can’t be found) comes back, and persists until I restart the server. After poring over page after web-page of Q&A issues/solutions with RoR’s MySQL connectivity, reinstalling MySQL and trying 15 other things, I’m going to say that… I’m sure with enough effort I could track down a solution, but for the time being I’m laying this to rest. My next step might be to bite the bullet and just download Instant Rails and see if I can pull pieces out of that, but I get the sense after reading all those pages that parts of this framework are a bit immature, like that database connector. The programming model at least sounds solid.

Testing the Rails, Part I

(The train hasn’t quite left the station.)

Last night I was feeling brave and decided to take the plunge and learn a little about “Ruby on Rails”:http://www.rubyonrails.com/. First step, of course, was to install the needed components.

Following the directions on the RoR homepage, everything went smoothly until I tried to get MySQL hooked up. Although there’s the “Instant Rails”:http://rubyforge.org/projects/instantrails/ package which includes everything preconfigured (Ruby, Rails, MySQL, some Web server or other), I already had MySQL and Apache running (with a live “testbed” site — didn’t want to damage anything here) so I opted for the “manual” install. Besides, it shouldn’t be too hard. After installing various versions of PHP+Apache+MySQL on at least 5 machines, getting everything to work together is sometimes tricky and takes a little troubleshooting, but I’m familiar with the process.

I was able to create and run a “Hello World” app and understand more about what Rails does. Basically, Ruby is just a programming language. I’m not familiar with it so I can’t comment too much about the feel of it yet, but by ASP standards (where by default you have the choice of Visual Basic or JScript), it’s more like Visual Basic: line endings have meaning, you won’t find braces or semicolons lying around anywhere, and also Like Python, indentation level also has meaning. But enough about the language itself; hopefully I’ll be able to comment more about that at a later date.

Rails is simply a set of scripts (written in Ruby, of course) which creates folders and writes out a whole slew of source code and configuration files which form your Web application’s framework. So by the time you start developing, you’re running on a nice framework of code which abstracts routine database operations (typically done tediously through SQL queries) into simple language constructs. Instead of SQL, you just deal with objects in the language.

So in the above sense, there’s no reason for it to be _Ruby_ on Rails. It could have been PHP on Rails or C++ on Rails. It seems the Rails developers had a “thing” for Ruby, and who knows, maybe it _is_ more elegant than other languages out there. I can’t tell you about that yet.

Anyhow, the Ruby interpreter is the same sort of thing as the PHP interpreter. You invoke it from the command prompt with a script as input, and it runs the script. Unlike PHP, it seems that there currently is no Apache module for Ruby. If you want to use it with Apache, it has to get invoked in CGI mode, and you need FastCGI to make that efficient.

Installing Ruby was easy. Next I installed RubyGems, which is a tool written in Ruby for automatically downloading and installing packages (sort of like PEAR from the PHP world, but seemingly more feature-rich.) I issued a command to tell Gems to downloaded and installed Rails, and another command to download and install the MySQL adapter. That’s where something must have gone wrong… since no matter what I did, my application would not connect to the database. It printed this error:

no such file to load -- ./mysql.o

Uninstalling and re-installing the MySQL adapter did not work. Attempting to install different versions of the adapter did not work, since something went wrong during the installation.

This version’s installation worked:

C:\ruby>gem install mysql
Select which gem to install for your platform (i386-mswin32)
 1. mysql 2.7.1 (mswin32)
 2. mysql 2.7 (ruby)
 3. mysql 2.6 (ruby)
 4. mysql 2.5.1 (ruby)
 5. Cancel installation
> 1
Successfully installed mysql-2.7.1-mswin32
Installing ri documentation for mysql-2.7.1-mswin32...
Installing RDoc documentation for mysql-2.7.1-mswin32...
C:\ruby>

All other versions did not work:

Building native extensions.  This could take a while...
 *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.
Check the mkmf.log file for more details.
You may need configuration options.
...
ERROR:  While executing gem ... (RuntimeError)
    ERROR: Failed to build gem native extension.
Gem files will remain installed in c:/ruby/lib/ruby/gems/1.8/gems/mysql-2.7 for
inspection.

The folder mentioned immediately above needed to be manually deleted whenever this occurred.

Anyway, that’s as far as I got in a few hours last night. I’ll go fight with this some more, later.

Deviation

I’ve joined “DeviantArt”:http://www.deviantart.com/ with the intention of creating and showcasing some new pieces and the hope of selling a couple on the side. I’m not exactly sure how the system works, yet. Is it like “Zazzle”:http://www.zazzle.com/, where they handle printing and distributing the artwork you create, and where you’ll simply upload a super-high-resolution version to them? Or is it like Ebay, where users handle production and shipping, and Deviant simply sets up the connection between creators and potential buyers? If the former, I’m always concerned about the quality of the service’s version. Will the colors come out as intended? Can I upload a high-enough-resolution file? If on the other hand I “get” to do the printing, then although I personally am confident about the quality outcome of my own prints from my nice little Epson inkjet (which takes 10 minutes to print a page at its highest quality setting and chews through ink cartridges faster than Kobayashi eats hot dogs (doubtful whether he chews)), this could be a liability for Deviant and sets up a system where they depend on user reputation and quality of prints would be highly variable from one artist to another. So… I doubt it works that way. Back when I did try Zazzle, I had used the service to order a poster-size print of one of my own images, which I was very dissatisfied with. The colors were horribly muddy (whereas output from my printer was nice and bright); the image was blocky and the dithering very visible (as if printed at 300 dpi). I’m sure mass printing technology (with far less than 10 minutes to dedicate per image) has improved considerably over the last few years, though, and I’m sure that the quality standard which customers expect from an online art service has increased. I could, I’m sure, resolve the topic of this speculation with about two minutes-worth of reading, but that wouldn’t be any fun. More importantly, I have to dedicate much more time to art, again, and I’m looking forward to that.

Unknown Firefox Bug

From an e-mail I wrote:

Is this the problem you are having? I’ve had it ever since I’ve installed Firefox, but whenever I mention it to anyone they have no idea what I’m talking about and apparently don’t experience it:

Firefox problem: Sometimes I’ll put my mouse into a textarea or a textbox and start typing, but instead of entering text into the text area, it starts searching for what I type within the page. I can re-click inside the text field as many times as I want and try to type some more, but Ff always jumps to text-search mode. Even when I have turned OFF the “find as you type” search, Ff ignores my textbox input in those instances. I find that the fix is, when this is happening, to minimize and then restore/maximize Ff, which causes the problem to go away for that window as I can then type into text boxes.

Anyway, if that’s the problem you’re having, that’s also the workaround for it. It doesn’t happen that often, now, but when it does it’s irritating since the behavior is randomly different and doesn’t seem to be connected to anything logical, on the surface.

Spam Sink

http://members.hostedscripts.com/antispam.html?26426“>This is a nice idea but rather silly, since if I were a spammer I’d just manually identify and ignore this page. If I were writing a bot to gather e-mail addresses I’d limit it to no more than, say, ten addresses per page, crawl on, and not visit the same URL again. I’d validate the domain names I gather via whois lookup, so these garbage domain names aren’t useful for anything.