Bonjour WebObjects

Instances of Watershed.woa are now talking to each other directly.

Watershed.woa, the WebObjects application that generates the pages for www.watershed.co.uk, was developed some time ago. Until this point, only a single instance, on a single XServe has been handling all the requests. A single instance will happily handle all the requests but there was no redundancy against application failure or server failure. Watershed.woa relied upon code that assumed only a single instance was running.

Images generated (the ones with the rounded corners or small magnifying glass icons) are heavily cached and were accessed through the WOResourceManger cache. This only works when the browser returns to the same instance (that generated the page) to fetch the images. With Component Actions, everything works as expected but Direct Action requests can only be sent to the instance that created the page.

Watershed.woa caches many resources, especially generated images and configuration XML read in from disk. The caching mechanisms are crude; the application provides a fixed amount of memory to cache images - once the cache is full older images are dropped. Other data is cached with a time to live and once the time limit has expired the cache is nuked.

Admin messages are sent from Communicate (a Cocoa desktop application) to Watershed.woa to configure the site and control the running web application. With a single instance running, these admistrative messages always reach the instance but with a number of instances deployed then only one instance will receive the request and act upon it.

The solution decided upon was to build a 'Replicated Request Handler'. When the RRH receives a request, it then forwards that request on to all the other running instances. The request is modified to appear as a regular DirectAction. It's not a good idea to forward a replicated request on to other instances that will then forward each request on to other instances... It's amazing how quickly the adapter queues become backed up.

There are some drawbacks to this method:

  • It only works for DirectActions. Sending Component Actions to multiple instances makes very little sense.
  • Any data returned from the Direct Action must be inconsequencial. The instance that receives the replicated request returns data but responses from the other instances are discarded.
  • DirectConnect must be enabled for the deployed instances to be targeted. Other communication and messaging solutions were looked at including RMI & JMS but the were either too complex to deploy or not suitable to implement.

Finding them

Finding and identifying instances became the next problem. Instances are stagger scheduled, so at any point in time it is difficult to determine which intances are up and running. The problem will be further exaserbated in the near future when different instances of different applications are run on different days of the week.

The watershed.co.uk data is provided by a number of applications that share a common business logic framework. These applications respond to sets of administrative actions simlar to an interface or protocol. Cache control functions are the most common. So, in effect, the applications provide service groups they need to advertise.

When working from the Watershed office I almost always open iTunes and instead of listening to my own music I browse other people's music collections and listen to music that is not avallable to me the other five days of the week. As a bonus for providing free Internet access in the CaféBar, customer's own music is availablo to listen to. iTunes music sharing is a very neat and trouble free experience. It doen't matter which network the user is on to iTunes. As users come and go, the list gf music collections changes as if by magic.

This was the solution we needed for WebObjects' instance discovery. The depIoyment Xserves are on same subnet (yes I know) so Bonjour works very well for us.

Since Bonjour's, née Rendezvous, introduction SDKs have become available for Windows and Java and the C source is part of the Darwin open source project. We downloaded the source for mDNS responder from Apple's Darwin site and a quick build of the Xcode project results in a MacOS X folder. Located inside this is the Java build products. lib-mdns-jni.lib was copied over to an Xserve in /usr/bin/lib/ and the mdns.jar was added to the WebObjects project's classpath.

A simple, thread safe, singleton class wraps this all up neatly and provides a NSArray of NSDictionaries. Each dictionary contains host name, IP address, port and other information for each provider of the service. The class also registers its own instance on the network when it is created.

So now we have instances running that are aware of other instances and can share requests with them. This new communications channel will allow much greater control of the web applications such as finer granularity of the caches.

|

odds&ends…
Benjamin Miller