Showing posts with label subscribe. Show all posts
Showing posts with label subscribe. Show all posts

Friday, July 3, 2009

Subscribing To Event Subscritions In Python

New in the latest version of the boduch Python library is the Subscription class. This abstraction is used to represent active event subscriptions to event handles. A Subscription instance ties together the Event class and the Handle class. The Handle providing the callback functionality that is executed when a given event takes place that the handle as a subscription to. As with previous versions, the event handle still uses the subscribe() function to subscribe to particular events. However, in previous versions, this function didn't actually return anything. The function will now return a Subscription instance. This functionality was added so that developers can have an easier method in which to reference which events will cause a given behavior to take place. The following is an example of a Subscription instance being returned.
#Example; Subscribing to a boduch Set event.

#Import required objects.
from boduch.event import subscribe, EventSetPush
from boduch.handle import Handle
from boduch.data import Set

#Simple handle.
class MyHandle(Handle):
def __init__(self, *args, **kw):
Handle.__init__(self, *args, **kw)

def run(self):
print "Running my handle."

if __name__=="__main__":
#Create a new subscription instance by subscribing to the event.
print "Subscribing"
sub=subscribe(EventSetPush, MyHandle)
print "Subscribed", sub

#Make sure the simple handle works.
Set().push("data")
In the example above, we define a simple event handle called MyHandle. We then subscribe this handle to the EventSetPush event to instantiate a new Subscription instance. Each Subscription instance holds a reference to both the handle and the event that the handle has subscribed to. Additionally, Subscription instances also define behavior. Since a Subscription instance holds a reference to the given event, we can use this instance hold build further subscriptions for this event. The core event handles inside the library already define and expose Subscription instances and can be used to create subscriptions for new event handles as the example below illustrates.
#Example; Subscribing to a boduch Set event via subscription.

#Import required objects.
from boduch.subscription import SubSetPush
from boduch.handle import Handle
from boduch.data import Set

#Simple handle.
class MyHandle(Handle):
def __init__(self, *args, **kw):
Handle.__init__(self, *args, **kw)

def run(self):
print "Running my handle."

if __name__=="__main__":
#Create a new subscription instance by subscribing to the event.
print "Subscribing"
sub=SubSetPush.subscribe(MyHandle)
print "Subscribed", sub

#Make sure the simple handle works.
Set().push("data")

Tuesday, March 24, 2009

Why we need a thread-safe publish/subscribe event system

Publish-subscribe event systems are a fairly common design pattern in modern computing. The concept becomes increasingly powerful in distributed systems where many nodes can subscribe to an event or topic emitted from a single node. The name publish-subscribe, or pub-sub, is used because it has a tight analogue in the real world. People with magazine or newspaper subscriptions receive updates when something is published. Because of this analogue, developers are more easily able to reason about events and why they occurred in complex software systems. In any given software system, some code will need to react to one or more events. These events can range from anything as simple as a mouse click to a complete database failure. The publish-subscribe pattern is infinitely extensible because any number of observers may subscribe to a single event. Subscriptions can also be canceled to as to offer architectural scalability in both directions; up and down. One bottleneck in a publish-subscribe framework can occur while the publishing object needs to wait until all subscribers have finished reacting to the event. In some cases, this is unavoidable such as when the publisher is expecting a value to be returned from one of the subscribers. In other cases, however, the publisher doesn't care about the subscribers or how they react to a published event. In a localized publish-subscribe system, that is, not a distributed publish-subscribe system, we could use threads for subscribers. If we were to build and use a framework such as this, where subscriptions react to events in separate threads of control, we would also need the ability to turn threading off and use the framework in the same way and have it still be functional. This is because threading is simply not an option in every scenario.

The boduch Python library offers a publish-subscribe event system such as this. The library is still in it's infancy but has the ability to run subscription event handles in new threads on control. The threading capability can also be switched on and off. The same code using the library can be run in either mode. Events are declared by specializing a base "Event" class. Likewise, event handles, or subscriptions, are declared by specializing a base "Handle" class. Developers can then subscribe to an event by passing an event class and a handle class to the subscribe function. Multiple handles may be listening to a given event type and if running in threaded mode, each handle will start a new thread of control. There are limits on the number of threads that are allowed to be run at a given time but this can be adjusted either manually or pragmatically. When running in threaded mode, or non-threaded mode for that matter, published events may be specified as atomic. This really only as an effect when the event system is running in threaded mode because it forces all handles for that particular event to run in the publisher's thread. When running in non-threaded mode, atomic publications are idempotent.

As mentioned earlier, there are several limitations to the boduch library since it is still in its infancy as a project. For instance, there is no way to specify a filter for event subscriptions. Subscribers may want to react to event types based on data contained within the event instance. In turn, there is no way to tack the source object that emitted the event. Finally, there is no real guarantee that proper ordering will be preserved when running in threaded mode. However, this can be worked-around. I haven't actually encountered a scenario where the ordering of instructions have been defective when running in threaded mode. This doesn't mean it is possible. I actually hope I do some day so I can incorporate more built in safety in the library.

Monday, December 1, 2008

Inside zope.event

The zope.event Python package is extremely straightforward. Which is why I like it. It provides a publish-subscribe mechanism that is sufficient for most applications. The entire zope.event package consists of a list for storing subscribers and a single notify function to publish events. Here is what the module looks like.
#zope.event

subscribers = []

def notify(event):
for subscriber in subscribers:
subscriber(event)
Very handy functionality and very easy to understand. This could event be implemented within an application should the zope.event module not be available because of its' simplicity.

Wednesday, July 30, 2008

Python publish subscribe

In keeping with the theme of my previous post, I'd like to mention that the publish-subscribe event pattern can also be used in Python. The zope.event package provides this functionality. For example, If I want to publish a topic when Blog objects in my application are updated, I could do something like:

import zope.event

class Blog:
def update(self):
self._update()
zope.event.notify('blogupdate')

This will send a notification to anyone in my application that has a subscription to blogupdate. To subscribe to this topic, we could do something like:

import zope.event

def sub_blogupdate():
log('Blog updated.')
zope.event.subscribers.append(sub_blogupdate)

The subscription would obviously do something more important but this serves well to illustrate the general concept. Publish-subscribe comes in handy when there is a chain of complex events. The zope.event package, although very simplistic, allows us to produce higher quality code.

Tuesday, July 29, 2008

Dojo publish subscribe

The dojotoolkit provides a powerful publish-subscribe event system. In fact, I have yet to see a javascript toolkit that offers this functionality.

In dojo, this system allows developers to write objects that can publish or broadcast events. You can also write objects that subscribe to events. The reason this is so powerful is that it allows you to write code that is maximally decoupled. What does maximally decoupled mean? It means that your separation of concerns is largely taken care of.

For example, suppose I have three components in my javascript application (yes, a javascript application), model, view, controller. In view, I have a dialog widget that I want to reuse in several cases. I don't want to create 25 dialog widgets that only have subtle differences. If this were the case, I would need to also create 25 different events for the OK action of the dialog.

Using the publish-subscribe pattern with dojo, I can pass a topic to the dialog when it is displayed. The dialog then only has one event. This event publishes the topic. Then, any objects that subscribe to the topic in model, view, or controller, can then fulfill their responsibilities.

Another reason to employ this dojo system in your javascript application is for extensibility considerations. Future components simply need to subscribe to the existing topics accordingly.