Tag: palmdev

Javascript Operation Queue

by on May.28, 2010, under Dev, Palm, Web Dev, webOS

When developing for a platform that relies on asynchronous APIs, such as webOS, the application logic frequently will need to block on a given operation prior to executing other dependent components. This may include anything from loading user data after authentication to saving data after initialization of a given data structure among others.

One method of handling this problem is to make the blocker component explicitly aware of the dependent components and the unique interface to each component, which works for simple cases or situations where the dependent to blocking relationship is one-to-one, but this quickly becomes complicated as a number of dependent components grows. In the extreme cases the blocker may have to be aware of significant portions of the system, leading to maintenance concerns.

Alternatively the blocker call can allow dependent components to register their interest in the completion of the operation and upon completion the blocker can simply notify the components on this list in a generic fashion. This allows that components to remain loosely coupled and has the added benefit of allowing for run-time conditional relationships without requiring that the blocker be aware of the state of the dependent.

Implementing such a notification system is fairly straightforward in Javascript: Simply collect waiting callbacks in an array or other structure then executing each upon completion of the blocking call.

Library

While simple to implement, my experience onFacebook for webOS has shown that a library to implement this behavior is worth the initial effort as manually writing nearly identical for loops over callbacks for the umpteenth time becomes tedious and error-prone.

To this end, we developed and open sourced the OperationQueue class which provides a common implementation that doesn’t require far too many for loops :)

Usage

To use the OperationQueue class you simply need to enqueue your dependent operations using the queue API.

queue can accept a single function which will be called upon successful completion.

    opQueue.queue(function(result) {
        // Do something with the data that we were waiting for!
        console.log("Blocking Operation Completed!");
    });
It also accepts an object with any combination of onSuccess and onFailure fields who will be called for each respective event.
    opQueue.queue({
        onSuccess: function(result) {
            // Do something with the data that we were waiting for!
            console.log("Blocking Operation Completed!");
        },
        onFailure: function(result) {
            console.log("Blocking Operation Failed");
        }
    });

These calls may occur at anytime. If the blocking operation has already completed then calls to queue will result in immediate execution of the queued operation. In this case the result object will not be included.

For the blocking call itself the getSuccessHandler and getFailureHandler generators will return callback functions that may be used to directly on completion or may be passed as callback handlers to the async API. These methods also accept a function parameter which will be called prior to their completion.

Used directly:
(opQueue.getSuccessHandler())();
As a callback:
ServiceRequestWrapper.request('palm://com.palm.preferences/systemProperties', {
        method:"Get",
        parameters:{"key": "com.palm.properties.nduid" },
        onSuccess: opQueue.getSuccessHandler(function(response) {
                Mojo.Log.info("Device ID: %j", response);
            }),
        onFailure: opQueue.getFailureHandler()
    });

For more complicated use cases, the reset function allows for enabling and disabling queuing at any time. For example, if you need to initially allow all operations to proceed and then block only while a given operation is in progress, the getSuccessHandler API may be called immediately after instantiation of the queue and then reset called prior to execution of the blocking operation.

Source:

Operation queue is available in the webos-samples repository on github, within the tipsAndTricks subproject.

One final note: While this was written for a webOS application, it does not depend on any webOS-specific constructs and may be used in any Javascript environment. To see it in action, check out the demo in any browser!

Comments Off on Javascript Operation Queue :, , , , more...

ServiceRequestWrapper Update

by on May.04, 2010, under Dev, Palm, webOS

This article is part of my Palm Dev Day summary series as well as a follow up to the original service request garbage collection post from last month.

After reexamining the original ServiceRequestWrapper implementation and the possible use cases, some improvements began to show through:

  • Subscribe requests were not protected from garbage collection after the initial complete callback (Thanks to Johan for pointing this out)
  • Requests were not being automatically cancelled on completion
  • The class did not need to be instantiatable as the 90% case can be handled by a singleton

With these issues in mind I decided that a rewrite was in order to make the class easier to use, as this is what the goal was in the first place :).

Non-Subscription Requests

Usage for non-subscription requests now involves a single call, ServiceRequestWrapper.request that is a “fire and forget” call meaning that cleanup is completely automated.

For example a call to determine the device ID can be done as follows:
    ServiceRequestWrapper.request('palm://com.palm.preferences/systemProperties', {
            method:"Get",
            parameters:{"key": "com.palm.properties.nduid" },
            onSuccess: function(response) {
                Mojo.Log.info("Device ID: %j", response);
            }
      });

Note that are no special requirements to cleanup the request object for these types of calls. Upon completion the request object will be cleaned from both the ServiceRequestWrapper data structures as well as any system level data structures.

Subscription Requests

The subscription case is not as simple as the framework can not reliably determine when the request is complete and future results are no longer desired. In order to reliably cleanup subscription requests ServiceRequestWrapper places the cleanup responsibility on the caller, via the cancel method, much in the same way as the Mojo.Service.Request API.

In practice this is not much harder than dealing with the single case. The following example monitors the system preferences for two changes to an arbitrary preference and then cancels any further action on that subscription.

var count = 0;
ServiceRequestWrapper.request('palm://com.palm.systemservice', {
    method:"getPreferences",
    parameters:{ keys: [ "food" ], subscribe: true },
    onSuccess: function(response, request) {
        Mojo.Log.info("Preference changed: %j", response);
        count++;
        if (count === 2) {
            request.cancel();
        }
    }
});

The request API also returns the a request object, which is identical to the 2nd parameter passed to callbacks, for those that need to cancel the request outside of the scope of a callback.

var subsRequest = ServiceRequestWrapper.request('palm://com.palm.systemservice', {
    method:"getPreferences",
    parameters:{ keys: [ "food" ], subscribe: true },
    onSuccess: function(response, request) {
        Mojo.Log.info("Preference changed: %j", response);
    }
});

// And then a miracle occurs

subRequest.cancel();

Source

The updated library is available on github in the palm/webos-samples repository.
Comments Off on ServiceRequestWrapper Update :, , , more...

Palm Dev Day: Adventures in Facebook

by on Apr.27, 2010, under Palm, webOS

Last Friday and Saturday Palm hosted their Dev Day event at their Sunnyvale campus, which I had the pleasure of presenting some of the techniques we learned while developing the Facebook for webOS application.

This presentation covered everything from our best practices to debugging and development tools to the common libraries we developed for the application. I would recommend webOS developers take a look as the topics covered deal with many common app development concerns.

As part of this presentation we have open sourced a collection of the libraries and tools that are used in the Facebook app development.

The slides from my presentation are available on slideshare and a video should be published in the near future. Additional presentations from the event have been made available under the palmdev slideshare tag

On a personal note, I would like to say that it was awesome to meet some of the developers who are using webOS, particularly in the Apps Lab breakout section!

Stay tuned for in depth posts on the topics discussed in my presentation.

Comments Off on Palm Dev Day: Adventures in Facebook :, , , more...

Visit our friends!

A few highly recommended friends...