All Packages Class Hierarchy This Package Previous Next Index
Resources are described by types and names. A type represents a domain of service: for example "user", "template", "config". The type information is used by the broker to choose which ResourceProviders may be able to service a request for information.
You can consider a name to be a sort of URL within a type domain. A name must uniquely describe a single object or concept that would be identical across multiple calls to the ResourceBroker within the same process. If you wish to serve up non-unique, transient, or changing objects it is suggested that the resource you return be a unique, intransient and unchanging wrapper capable of retreiving the desired, volatile information.
An example: If you wish to override the default kind of User provided by WebMacro, you could implement your own "user" type and register it in place of the WebMacro "user" provider. Your provider would then be used to look up and return users instead. You may also invent your own domains of information and register arbitrary providers for them, so as to make their resources available to any handler that asks.
Note that the intent of the Broker service is to parallelize processing, as well as separate requests for services from their implementations. Your provider must be threadsafe, and any data returned in a ResourceRequest must be threadsafe as well. Each method has a corresponding thread policy which you should observe so as to avoid deadlock, lockout, livelock, and other synchronization problems.
See the ResourceListener interface for details on the types that a Provider can service.
public static final int NEVER_CACHE
Warning: This refers only to the resource brokers cache and resource management abilities. In one sense your objects will never expire: Since the ResourceBroker will not be managing them, they will only be saved/deleted/revoked when the client code explicitly calls revoke().
This setting would be useful for resources which are simply delivered to the client and then forgotten--it is not important whether resourceSave() is ever called.
public static final int INFINITE_CACHE
Warning: Do not use this unless you are sure there are a finite number of resources that could be requested, and that they all fit into memory.
Also, this does not guarantee that your resources will survive for the lifespan of the ResourceBroker--the broker may still decide to shut down your entire ResourceProvider from time to time. At that point your objects will be revoked and returned to you for save/delete.
public abstract void resourceRequest(RequestResourceEvent request) throws ResourceUnavailableException, InterruptedException
Find an object matching the supplied description and type. If the value can be obtained, set it with request.setResource() and return. If it cannot be obtained, simply return without calling request.setResource().
No further action is required. The ResourceBroker will look after notifying threads appropriately.
Note that this method MAY execute in its own thread, and that the requestor MAY cancel the event at any time, or another Provider MAY have already obtained the resource and set it before you have a chance to. If any of those situations occur, then this ResourceEvent will not be settable and the work done by this method will be ignored by the ResourceBroker.
In these cases your thread will be interrupted, its priority downgraded, and the supplied event will throw an exception if you attempt to set it. You MAY wish to test ResourceEvent.isSettable() prior to starting an expensive procedure in order to avoid wasting computing resources.
Also note that more than one thread may receive the objects that you return, therefore any content put into the ResourceEvent MUST be thread safe. See the thread policy below.
Thread policy: You will not be called twice for the same object without at least one intervening resourceSave() on that object unless you have set the cache to NEVER_CACHE.
Be aware that several threads may be blocked waiting for you to return a value. (You can detect this: If your thread priority is raised from ResourceBroker.NORMAL_WORKER to ResourceBroker.CRITICAL_WORKER, then someone is already waiting for you to return.
You MAY call the ResourceBroker and you MAY lock other ResourceEvent objects. But beware of deadlock: Other threads may be blocked waiting for ResourceEvents that you provide. It is up to you to arrange a thread policy for your ResourceEvents and ResourceConsumers such that providers don't block waiting for consumers who are waiting for you.
This sounds complicated and it is. A simpler course of action is to follow an "inner most lock" policy for all your objects: Do not synchronize on any object that is reachable outside the methods in your instance.
You may throw a ResourceUnavailableException to indicate that you do service the requested object, but for some reason it is not currently available. The ResourceBroker will stop searching for it.
You may throw InterruptedException if your thread was interrupted because the work it is doing is no longer wanted. In this case be sure and clean up any allocated resources prior to throwing the exception. Calling wait(0) will throw this exception if you have been interrupted.
public abstract void resourceCreate(CreateResourceEvent create) throws ResourceUnavailableException, InterruptedException
Exactly the same semantics as resourceRequest, except that the resource is to be created. Throw a ResourceUnavailableException if you do not want to create the resource, and you don't want other Providers to create it either--this may be because the resource already exists, or has been deleted, etc.
If you simply don't allow resource creation it might be better to do nothing and let the broker locate a different provider of the same type that does.
public abstract boolean resourceDelete(ResourceEvent delete)
Exactly the same semantics as save. The resource may or may not have been previously allocated--this is a request to delete it.
This method may be called instead of resourceSave(). You can choose to save the resource and throw an exception if you want to deny deletions.
You can throw a ResourceUnavailableException if you refuse to allow deletion of the named resource--because you don't allow deletion, the resource has already been deleted, etc. If the resource simply does not exist you should do nothing, to let the broker try other providers to see if they have it.
public abstract boolean resourceSave(ResourceEvent save)
This method is called by the ResourceBroker when a previously allocated resource is about to be revoked. It will not be called if the resource was allocated as part of a resourceDelete operation--deleted resources will simply be discarded.
If the resource allocated has any persistent information which needs to be stored on disk, or written out, etc. If you handle the request, return true. If you did not handle it (and the Broker should keep looking to see if a different provider owns the object) return false.
This method (or resourceDelete) will be called once for each ResourceEvent previously allocated by this ResourceProvider, but only if the ResourceProvider is still registered with the ResourceBroker when the resource gets revoked. (ie: if you deregister your broker, the ResourceBroker will not know how to find you anymore.)
Thread Policy: Do not synchronize on any external objects.
WARNING: This method will already have been synchronized on the supplied ResourceEvent by the ResourceBroker, to ensure that consumers do not interfere with the save and revoke procedure. This implies some fairly draconian restrictions on what this method can do safely:
public abstract int resourceThreads()
NOTE: This is advisory information only and may not be used by the broker under all circumstances. In particular, other providers of the same type may have specified a different value.
public abstract int resourceExpireTime()
You can use the constants INFINITE_CACHE and NEVER_CACHE, but be warned that these values will only be used if your provider is the first one registered against the broker--therefore it is recommended that all providers of the same type registered with the ResourceBroker return the same cache control information.
All Packages Class Hierarchy This Package Previous Next Index