20.2. Case Study: A Stock Ticker Simulation
In this example, we assume that we have a server application that is making stock prices available to the network. Any client wanting to check the value of his thousand shares of Gizmonic Institute can contact this server.
We've added a twist to this, however. We don't just want to watch every little fluctuation in the stock price. We've implemented an Observer module that will let us subscribe to the stock feed; the client then watches the feed and warns us only when the price goes above or below a certain value.
First let's look at the DrbObservable module. This is a straightforward implementation of the Observer pattern from the excellent book Design Patterns, published by Addison-Wesley and authored by the so-called "Gang of Four" (Gamma, Helm, Johnson, and Vlissides). This is also known as the Publish-Subscribe pattern.
Listing 20.1 defines an observer as an object that responds to the update method call. Observers are added (by the server) at their own request and are sent information via the notify_observers call.
Listing 20.1. The drb Observer Module
The server (or feed) in Listing 20.2 simulates the stock price by a sequence of pseudorandom numbers. (This is as good a simulation of the market as I have ever seen, if you will pardon the irony.) The stock symbol identifying the company is used only for cosmetics in the simulation and has no actual purpose in the code. Every time the price changes, the observers are all notified.
Listing 20.2. The drb Stock Price Feed (Server)
If you are on a Windows platform, you may have difficulty with the exit idiom used here. The gets on Windows tends to hang the main thread. If you experience this, you should use a DRb.thread.join instead (and use a control-C to kill it).
Not surprisingly, the client (in Listing 20.3) begins by contacting the server. It gets a reference to the stock ticker object and sets its own desired values for the high and low marks. Then the client will print a message for the user every time the stock price goes above the high end or below the low end.
Listing 20.3. The drb Stock Price Watcher (Client)
You may wonder about the DRbUndumped module referenced in Listing 20.3. This is included in any object that is not intended to be marshalled. Basically, the mere presence of this module among the ancestors of an object is sufficient to tell drb not to marshal that object. In fact, I recommend you look at the code of this module. Here it is in its entirety:
module DRbUndumped def _dump(dummy) raise TypeError, "can't dump" end end
The stock watcher application we saw in this section is long enough to be meaningful but short enough to understand. There are other ways to approach such a problem. But this is a good solution that demonstrates the simplicity and elegance of distributed Ruby.