All Packages  Class Hierarchy  This Package  Previous  Next  Index

Class org.webmacro.broker.ResourceBroker

java.lang.Object
   |
   +----org.webmacro.broker.ResourceBroker

public final class ResourceBroker
extends Object
Resource Broker--connect up requests for a particular type of resource with a provider capable of obtaining it; and notify resource consumers when a resource becomes available. It also manages a cache of resources, frees them over time, and ensures that their Providers have an opportunity to save them.

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.

See Also:
ResourceEvent, ResourceConsumer, ResourceProvider, ResourceTracker

Variable Index

 o ASYNCHRONOUS
Use this constant as the boolean for getValue() to improve clarity
 o SYNCHRONOUS
Use this constant as the boolean for getValue() to improve clarity

Constructor Index

 o ResourceBroker()
Construct a new resource broker with default expire time.

Method Index

 o announce(ResourceEvent)
Let anyone interested in this type of resource know that it's arrived.
 o create(String, String)
Same as calling create(type,name,null)
 o create(String, String, Object)
Request that a resource be created.
 o delete(String, String)
Request that a resource be deleted, returning the instance of it if it existed.
 o get(String)
Get a resource map-like interface for the supplied type, meaning you can use get/put/remove as you would with a dictionary.
 o getValue(String, String)
Return the value of the contained resource.
 o isConsumer(String)
Return whether there is currently a consumer for the supplied type
 o isProvider(String)
Return whether there is currently a provider for the supplied type.
 o join(ResourceListener)
Adds a new resource producer and/or consumer to the Broker's internal lists of service providers/consumers.
 o leave(ResourceListener)
Remove a resource producer and/or consumer from the Broker's internal lists of service providers/consumers.
 o main(String[])
Test harness
 o request(String, String)
Equivalent to request(type,name,ASYNCHRONOUS)
 o request(String, String, boolean)
Request a resource from the Broker.
 o revoke(ResourceEvent)
Revoke a resource.
 o shutdown()
Shuts down the broker, removing all of its providers and consumers.

Variables

 o ASYNCHRONOUS
 public static final boolean ASYNCHRONOUS
Use this constant as the boolean for getValue() to improve clarity

 o SYNCHRONOUS
 public static final boolean SYNCHRONOUS
Use this constant as the boolean for getValue() to improve clarity

Constructors

 o ResourceBroker
 public ResourceBroker()
Construct a new resource broker with default expire time.

Methods

 o join
 public final synchronized void join(ResourceListener newListener)
Adds a new resource producer and/or consumer to the Broker's internal lists of service providers/consumers. After joining this broker newListener will be notified of resources as they become available (if it's a consumer), and used to locate resources as they are requested (if it's a provider). In either case newListener will only be used/notified when the resource requested or made available matchces one of the types returned by newListener.getTypes().

 o leave
 public final synchronized void leave(ResourceListener rmListener)
Remove a resource producer and/or consumer from the Broker's internal lists of service providers/consumers. After leaving this broker rmListener will no longer be notified of resources that become available, nor will it be used to allocate or find new resources.

 o getValue
 public Object getValue(String type,
                        String name) throws ResourceUnavailableException
Return the value of the contained resource. Throw an exception only if the resource is absolutely unavailable, and cannot be retrieved again. This method will block until the resource becomes available.

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.

Parameters:
type - the type of the resource being sought
name - the name of the resource beig sought
Throws: ResourceUnavailableException
invalid type/request
 o get
 public final ResourceMap get(String type) throws InvalidArgumentException
Get a resource map-like interface for the supplied type, meaning you can use get/put/remove as you would with a dictionary. (It's not a dictionary, but it's pretty similar.)

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).

Parameters:
type - the resource type this map should relate to
Returns:
a map that has a fixed type, where you supply the names
Throws: InvalidArgumentException
no provider for type
See Also:
ResourceMap
 o request
 public final ResourceEvent request(String type,
                                    String name) throws InvalidArgumentException, ResourceUnavailableException
Equivalent to request(type,name,ASYNCHRONOUS)

Parameters:
type - Tye type of service requested
name - A name/description of the desired item
Returns:
an event representing the submitted request
Throws: InvalidArgumentException
on null value or unknown type
Throws: ResourceUnavailableException
refused: invalid type/service
 o request
 public final ResourceEvent request(String type,
                                    String name,
                                    boolean asynchronous) throws InvalidArgumentException, ResourceUnavailableException
Request a resource from the Broker. This will result in the creation of a ResourceEvent, which will be returned. The ResourceEvent will asynchronously be passed to one or more Provider, if available.

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).

Parameters:
type - Tye type of service requested
name - A name/description of the desired item
asynchronous - either ASYNCHRONOUS (true) or SYNCHRONOUS (false)
Returns:
an event representing the submitted request
Throws: InvalidArgumentException
on null value or unknown type
Throws: ResourceUnavailableException
refused: invalid type/service
 o delete
 public final ResourceEvent delete(String type,
                                   String name) throws InvalidArgumentException, ResourceUnavailableException
Request that a resource be deleted, returning the instance of it if it existed. If it does not exist then the returned ResourceEvent will be revoked before a value becomes available. Any outstanding copy of the resource will be revoked before the deletion occurs.

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().

Throws: InvalidArgumentException
on null value or unknown type
Throws: ResourceUnavailableException
refused: invalid type/service
 o create
 public final ResourceEvent create(String type,
                                   String name,
                                   Object argument) throws InvalidArgumentException, ResourceUnavailableException
Request that a resource be created. This method will be fail if the resource already exists.

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.

Throws: InvalidArgumentException
on null value or unknown type
Throws: ResourceUnavailableException
refused: invalid type/service
 o create
 public final ResourceEvent create(String type,
                                   String name) throws InvalidArgumentException, ResourceUnavailableException
Same as calling create(type,name,null)

Parameters:
type - the type of resource this operation relates to
name - the name of the resource we wish to create
Returns:
a resource event representing an attempt to create the user
Throws: InvalidArgumentException
on null value or unknown type
Throws: ResourceUnavailableException
refused: invalid type/service
 o revoke
 public final void revoke(ResourceEvent revokeMe)
Revoke a resource. Provider can call this to revoke an item they previously returned. Consumers can call this to revoke a request that they are no longer interested in receiving.

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.

 o announce
 public final void announce(ResourceEvent newResource)
Let anyone interested in this type of resource know that it's arrived. Provider can call this method if they want to spontaneously announce the arrival of a new resource. It should NOT be called from ResourceProvider.resourceRequest(), since in that case announcements are done automatically by the ResourceBroker.

 o isProvider
 public final boolean isProvider(String type)
Return whether there is currently a provider for the supplied type.

 o isConsumer
 public final boolean isConsumer(String type)
Return whether there is currently a consumer for the supplied type

 o shutdown
 public final void shutdown()
Shuts down the broker, removing all of its providers and consumers.

 o main
 public static void main(String arg[])
Test harness


All Packages  Class Hierarchy  This Package  Previous  Next  Index