All Packages Class Hierarchy This Package Previous Next Index
java.lang.Object | +----org.webmacro.broker.ResourceBroker
A "resource" is an object which can be uniquely identified by a string type and a string name.
The ResourceBroker is strongly related to the Java InfoBus. The InfoBus was intended to be used in applets, and has many Applet specific properties. Like the InfoBus a ResourceBroker is intended to allow you to exchange data by name, between providers and consumers--enabling you to change providers/consumers at runtime, have multiple providers for the same kind of information, and allow multiple consumers of information to share the same copy of the data. Though the ResourceBroker and InfoBus differ in many other ways, one intent of the ResourceBroker design is that it could make use of an InfoBus internally, proxying requests so transparently that clients of the ResourceBroker would not know they were using an InfoBus. This is important because many useful classes may be written for the InfoBus in the near future.
Unlike the InfoBus, the ResourceBroker handles requests asynchronously, starting a new thread for each request. It also manages a simple cache, and automatically revokes objects that have not been accessed (according to a strict definition of "accessed") within a fixed period of time.
The ResourceBroker attempts some simple thread scheduling. The thread spawned off to do the work happens at less than the default thread priority. If a thread blocks waiting for it to complete in the ResourceEvent.getValue() method, the priority of the worker thread trying to acquire the resource is raised to be greater than the default priority.
The broker also manages a resource cache. If two consumers request the same resource (identical name and type) then they get back the same resource. To accomplish this, the broker maintains a cache of outstanding objects.
The ResourceBroker runs a reaper thread in the background for each resource type, to revoke resources which have not been used recently. You can specify what "recently" means as an argument to the constructor. You can override that choice for each specific type when you register the FIRST provider of that type.
Please note that revoking does NOT mean the underlying objects are freed--only that the ResourceBroker will not permit any new accesses to them, ask their provider to save them, and cause their corresponding ResourceEvents to throw a ResourceRevokedException whenever an attempt is made to access its value. You could still go and get a NEW reference to it by calling request() and have a fresh working copy. The object will not be freed by the JVM until the last reference to it is lost by its client--but this will be convenient in many instances, such as threaded servlets, * where references are lost quite quickly.
An object is revoked if it has not been touched since the last time the reaper looked at it. A resource is "touched" when you call a method on its ResourceEvent (eg: getValue, isAvailable, etc.). This policy can be extended by the ResourceProvider, since a ResourceEvent supports both the Observer and PropertyChangeListener interfaces: A provider could supply resource objects that support the complementary interfaces and register them with the ResourceEvent when setting them.
Some segments of code may find it inconvenient that a resource can be revoked at any time. To make life easier for these applications, there is a getValue(type,name) method available which blocks until the object becomes available, and attempts to deal with the fact that it has been revoked.
Thread policy: NEVER lock this object.
You MAY lock on ResourceEvents under limited conditions--in particular if you hold a lock on an event, you MUST NOT use the broker at all while you have that lock, nor may you call any method which will use the broker. The broker will lock ResourceEvents under a variety of conditions; this policy ensures that locks are always acquired in the same order: Broker lock first, lock ResourceEVent second.
NOTE: While the ResourceBroker takes steps to ensure that a ResourceEvent is saved before it is revoked, it has no way of detecting activity on the underlying object, nor can it prevent consumers from extracting the underlying resource from a ResourceEvent and holding copies of it after it has been revoked.
public static final boolean ASYNCHRONOUS
public static final boolean SYNCHRONOUS
public ResourceBroker()
public final synchronized void join(ResourceListener newListener)
public final synchronized void leave(ResourceListener rmListener)
public Object getValue(String type, String name) throws ResourceUnavailableException
If the resource is marked as revoked, getValue() will wait for it to disappear and request it again. This is not guaranteed to succeed, but it would be a pretty pathalogical situation where it failed--so pathalogical that any other method of retreiving the value would be unlikely to succeed either.
If the resource cannot be retrieved, despite a really good try, then a ResourceUnavailableException will be thrown. Though it's possible a second request may succeed in retrieving the value, trying again is not recommended unless you have specific knowledge that circumstances have changed in a way that makes this likely.
public final ResourceMap get(String type) throws InvalidArgumentException
This is recommended if you are going to repeatedly access the same type of information, as it is slightly more efficient than calling the equilvalent methods on the ResourceBroker (it saves resolving the type name for each request).
public final ResourceEvent request(String type, String name) throws InvalidArgumentException, ResourceUnavailableException
public final ResourceEvent request(String type, String name, boolean asynchronous) throws InvalidArgumentException, ResourceUnavailableException
Note that this method operates asynchronously and may spawn multiple threads. This behavior should be transparent to both the Consumer and the Provider, but it is worth remembering. Although this method will return immediately, calls to toString() and getValue() will block until the Resource is actually made available by a Provider.
You can specify whether you want the resource to be resolved in its own thread (ASYNCHRONOUS) or in this thread (SYNCHRONOUS).
public final ResourceEvent delete(String type, String name) throws InvalidArgumentException, ResourceUnavailableException
ResourceProviders are not required to support the delete operation, and may simply return a revoked item.
Note that this method operates asynchronously and is subject to exactly the same conditions as request().
public final ResourceEvent create(String type, String name, Object argument) throws InvalidArgumentException, ResourceUnavailableException
ResourceProviders are not required to suppor the create operation, and may simply return a revoked item.
Note that this method operates asynchronously and is subject to exactly the same conditions as request().
The returned value will be saved once it expires or is revoked.
public final ResourceEvent create(String type, String name) throws InvalidArgumentException, ResourceUnavailableException
public final void revoke(ResourceEvent revokeMe)
Revoking a resource does not delete it, it simply invalidates the current copy. Whether that deletes it depends on whether the provider maintains a persistent copy or not--most providers probably do.
Resources are automatically saved when they are revoked, unless they have been deleted.
public final void announce(ResourceEvent newResource)
public final boolean isProvider(String type)
public final boolean isConsumer(String type)
public final void shutdown()
public static void main(String arg[])
All Packages Class Hierarchy This Package Previous Next Index