Saturday, 8 October 2011

the websocket api spec doesn't like you

I like the look of the W3C WebSockets client specification but it's a bit short-sighted given its inevitable ubiquity.

Unlike the IETF WebSocket protocol, it doesn't have something close to the order of 100 prior revisions with varying levels of implementation across different browsers and browser versions. The client specification is simple and hasn't changed much between revisions but it suffers the flaw of being a specification that can't be implemented in most languages without deviation.

Let's look at an example:

var socket = new WebSocket('ws://websocket.site.local/');

socket.onopen = function () {
    socket.send('Hello World!');
};

This example is pretty straightforward to understand. The browser connects out, handshakes with the server and then sends back a message if there are no problems. In an event-driven language like JavaScript the process looks something like this:

  1. Enter the WebSocket constructor
  2. Call an asynchronous IO function for connecting to the server
  3. Exit the WebSocket constructor
  4. Assign the "Hello World" callback to onopen
  5. Exit the above code block
  6. At some undetermined point in the future, the event loop will run the callback for the IO operation in stage 2
  7. If the callback thinks the IO succeeded, it will call the onopen function

If you don't have an event loop processing asynchronous IO callbacks then the above code does this:

  1. Enter the WebSocket constructor
  2. Connect to the server using blocking IO
  3. Call the onopen function if it's set (it isn't)
  4. Exit the WebSocket constructor
  5. Assign the "Hello World" callback to onopen
  6. Exit the above code block

So onopen will never actually be called.

JavaScript works fine because under the cooperative multitasking scheme only one function executes at a time and ultimately has the responsibility of giving up the CPU to the next function: background threads might perform tasks in parallel but from the perspective of the programmer the current function rules supreme.

So how do you have the same sequence of events when there isn't an event loop? You could try to implement the blocking IO part on a separate thread but then whether onopen is called or not is determined by who wins the race: the original thread making the assignment or the IO thread completing its handshake. Clearly another solution is needed.

The solution

When I was writing a PHP WebSocket client I didn't have time to reprogram the entire language to use an event loop (I'll do that next weekend) so I had to deviate from the specification that I was becoming quite fond of. There was a simple solution that involved removing the responsibility of connecting to the server from the constructor and instead putting it in to separate method that explicitly needs to be called after the socket has been fully prepared.

$socket = new WebSocket('ws://websocket.site.local');

$socket->onopen = function () use ($socket) {
    $socket->send('Hello World!');
};

$socket->connect();

This rebuilds the chain of causation the JavaScript implementation gives us but leaves me wishing the W3C had come up with something a bit more universal. Event-driven programming might be the current hot topic and might prove itself to be superior to multi-threading, but for the forseeable future most programmers wont be using an event loop.

For the same reasons that HTTP became the lingua franca of APIs and SOAs, WebSockets will likely also find themselves playing a large role in the future. Too bad we wont be able to stick to the spec!

Is there a better way? Should the W3C look beyond the browser?

Friday, 7 October 2011

php references and some unexpected behaviour

I had some functions that would iterate over a tree that was several levels deep and augment it with new fields before it was passed to a view. This seemed like a pretty nice idea since it meant I could easily add new functions with their own customisations later.

Everything worked well for a while but then someone noticed the final row looked a bit strange.

It's best demonstrated with this contrived example:

protected function wtf()
{
    $array = array(10, 10, 10);

    foreach($array as &$value) {
        $value++;
    }
  
    foreach($array as $value) {
        $value++;
    }

    var_dump($array);
}

There's no real reason for using a reference in the above example but you might expect a result similar to this:

array
  0 => int 12
  1 => int 12
  2 => int 12

What you'll get is the following:

array
  0 => int 11
  1 => int 11
  2 => &int 13

I showed my boss and his response was "Didn't you read the Zend Certification Guide? It has a whole chapter about this.."

Tuesday, 27 September 2011

mvc widgets

how did my controllers get so messy?

Some of the code that I've been working with is suffering from two problems that I imagine are endemic amongst web applications built upon MVC frameworks: controllers bloated by complex logic and controller logic that has crept in to templates.

Clearly as programmers we should strive for reusability, but the two most widely known and practised forms of MVC code reuse are globally accessible helper functions and partial views. Sadly neither of these approaches allow appropriate reuse of controller logic. If you add controller logic to your partial you're combining the view and controller aspects of your program and if you use a global helper for anything more than simple formatting then you're no longer writing MVC code.

isn't there a better way?

In order to tackle this problem I've been experimenting with the idea of using composite controllers that can be created and used within any other controller.

With a conventional controller, typically a router or front controller script would instantiate a controller and pass it information about the user's request, such as their post or get variables. The action method of the controller would then be called and this would either render the output of the page or return enough information to the caller for the code in charge of the controller to be able to render the page. Our composite controller works a bit differently.

In a simple example, consider a LoginWidget that uses a model that provides authorization services and a template consisting of a login form and some javascript includes. You could initialise this widget within a controller action for any page and render it at a place determined within the view loaded by the host controller.

The hosting controller needs to instantiate the widget in its action. In its most simplistic form this means binding it to a variable that the view can make reference to later and passing configuration values to the widget.

// Create a login widget. It will access our request and response
// objects
$this->loginWidget = new LoginWidget($this);
// We might want to set up a form prefix so that our form fields
// don't conflict with others
$this->loginWidget->setFormPrefix('login');
// We act as the router for this controller. The action name could
// be anything, in this case checkLogin(), etc.
$this->postAction(); 

The widget implements controller actions just as if it was a normal controller. A bit of extra care needs to be taken to ensure that it wont accidentally read the form fields of other controllers on the page. A prefix works fine for this.

function postAction()
{
 // map fields from the login form using the prefix
 $this->model = new AuthorizationForm();
 $this->model->mapFields(
  $this->request->getPost(), 
  $this->getFormPrefix()
 );



 // ensure it's this widget we're actually submitting
 if($this->getPostPrefixed('submit')) {
  // try to use a service to log us in and pass any 
  // validation errors to the view
  try {
   $service = new AuthorizationService();
   $service->authorize($model);
  } catch (ValidationException $ex) {
   $this->validation = $ex;
  } 

  // if there were no validation errors we have 
  // logged in. don't show any text
  if(!$this->validation) {
   $this->setTemplate(null);
  }
 }
}

Inside your template you can then do this somewhere in the markup:

<?php $loginWidget->render(); ?>

This is pretty straightforward and means that any page which needs login functionality doesn't need to explicitly implement this behaviour.

wow this could change the course of human history

This is no new idea. In fact, reusable widgets have long been a part of desktop application development and lively communities of independent widget makers once sprung up as part of the software ecosystems of major operating systems. It seems to just be the case that web developers haven't quite caught on yet, or don't mind being frustrated.

What's interesting is that major web MVC frameworks already have this concept it's just nobody I know uses it:

  • Zend Framework has Action Helpers
  • Symfony has Custom Widgets
  • ASP.NET MVC has Component Controllers