The dRuby Book

9.5 Design Goals of the API

I designed the API of Drip to use with dRuby. dRuby has several weaknesses: it’s hard to manage the life span of objects on the server side, it’s hard to manage the mutex, and RMI is slow. It was important to design the API so that it doesn’t create objects that keep state on the server side and also to decrease the number of RMI calls.

Let’s think about the key of the read method once again. The key of read is equivalent to the concept of a cursor or pages inside a database. Often a database API hides a cursor inside the context.

For example, Ruby’s File object remembers the current offset in a file, and you can read from or write to the specific point. On the other hand, Drip doesn’t have any objects with state. A request to Drip is stateless just like a function is. It uses a cursor key instead of having an object to manage the context of the location. The reason I chose this API was to avoid creating a context-managing object inside the Drip server. Drip is designed to be used over RMI with dRuby in mind. If I introduce a context that generates and deletes an object (begin and end, open and close), then the server needs to manage the life span of the object. This will lead to the difficult problem of managing GC in a distributed environment. To avoid these problems, I designed the API such that you can interact only via Integer keys.

As shown in the preceding sections, you can simulate a recursive operation by using keys returned from read, instead of using an object to manage context. If you find this API interface cumbersome, then I suggest you write a wrapper to hide the key inside the context of the local process. Make sure you don’t provide context on the Drip server side.

When using a read operation, you can specify the minimum and maximum number of elements to return. This batch operation will decrease the number of RMI calls compared to retrieving them one by one. This method is effective when processing batch operations that require throughput over response time. By specifying “at least n elements,” you can avoid generating an RMI for every event. You can wait for the data to be accumulated in some amount before being transferred.

While creating prototypes prior to Drip, I learned the importance of not implementing too much. “Crafting” is such a fun thing that I tended to add more functionality whenever someone asked. When creating Drip, I made the concept of Drip very clear so that I could fight against the temptation of adding too much functionality.