Monthly Archives: November 2007

Announcements

Three announcements:

  1. The yet-to-be-officially-named Tampere Ruby User Group will meet for the second time this Thursday. The location is the office of Adalia at Hämeenkatu 3. For more information see the wiki page and the mailing list. (Unfortunately all the information is in Finnish. Mail me if you need a translation.) Newcomers are welcome!
  2. I am planning to organize a coding dojo in Tampere in January. Technology will be either Java/jUnit or Ruby/RSpec. I’ll post other details later. Leave a message if you are interested.
  3. The Spring 2008 OHJ-5100 at TUT is projected to have an optional Ruby on Rails course project. Petri Sirkkala lectures the course; I will tutor the Rails sessions. The Rails part will last three weeks, from 7th of April to 25th of April. It will be of intensive variety, requiring attendance from 9 to 17 each weekday. We will learn agile methods along with the web development skills. I have based the course project loosely on a one taught by Carsten Bormann at the University of Bremen.

Toggle buttons, idempotency and session state

A quick quiz.

The question

I write a web app to switch the workplace coffee machine on or off. (I leave to you the writing of the sibling application that fills the machine with coffee and water.) The user interface consists of just one page. It has a big label that says “ON” or “OFF” and a big button that says “Toggle”. When the user presses the button, the coffee machine switches on (or off) and the page is reloaded, with the ON/OFF status updated, of course. I implement the toggle button form like this:

<form method="post" action="toggle">
    <button>Toggle</button>
</form>

What is wrong with this?

The answer

The problem lies with the toggle action. It emerges from a combination of two things:

  • The presumed result of the action depends on the state of the user interface.
  • The actual result of the action depends on the state of the server.

Unfortunately, with web apps, there is no guarantee that the state of the user interface corresponds to the state of the server. For example, two people might be using the application at the same time. It would go like this:

  1. Alice surfs to the coffee page. The coffee machine is off.
  2. Bob surfs to the coffee page. The coffee machine is still off.
  3. Alice presses the toggle button. The coffee machine switches on.
  4. Bob’s page still shows that the machine is off. He presses the toggle button, thinking the machine will switch on. Instead, the coffee machine switches off.
  5. Nobody gets coffee and everybody blames Eve as usual.

Here’s the form fixed:

<form method="post" action="toggle">
    <input type="hidden" name="new_state" value="on" />
    <button>Switch on</button>
</form>

Now there is no ambiguity. “Switch on” means “Switch on”. If the coffee machine already happens to be on, it is just as fine.

Actions of this kind are called idempotent. The outcome of an idempotent action remains the same even when the action is repeated. Because of the disconnect between the UI and the server, action idempotency is very desirable in web applications.

Another teaching we can draw from the example regards session state. Session state consists of things like the location of the user in the user interface, and the paths he can take from there. Resource state, in contrast, is a more permanent variety of state that exists independently of sessions. In the coffee machine example:

  • Session state: The fact that the toggle button will turn the coffee machine on.
  • Resource state: The fact that the coffee machine is off.

The problem with the coffee app was saving the session state on the server, invisible to the user. The general guideline: Don’t hide session state on the server.