All Packages  Class Hierarchy  This Package  Previous  Next  Index

Interface org.webmacro.broker.ResourceProvider

public interface ResourceProvider
extends ResourceListener
Implement this to provide a category of service for WebMacro.

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.

See Also:
ResourceListener, ResourceConsumer, ResourceBroker, ResourceEvent

Variable Index

 o INFINITE_CACHE
Use this when setting expire times to indicate that the ResourceBroker should cache resources returned by this provider forever.
 o NEVER_CACHE
Use this when setting expire times to indicate that the ResourceBroker should never cache resources returned by this provider.

Method Index

 o resourceCreate(CreateResourceEvent)
Allocate a resource that did not previously exist, possibly storing it for future reference as well.
 o resourceDelete(ResourceEvent)
Delete a resource that already exists, possibly removing it from permanent storage.
 o resourceExpireTime()
Return, in milliseconds, the preferred maximum amount of time the broker should cache the results of this resource provider.
 o resourceRequest(RequestResourceEvent)
Find a resource that already exists and make it available for use.
 o resourceSave(ResourceEvent)
Save a previously allocated resource, on permanent storage if necessary.
 o resourceThreads()
Return the desired amount of concurrency for this provider: The broker will start up to this many threads to service requests.

Variables

 o NEVER_CACHE
 public static final int NEVER_CACHE
Use this when setting expire times to indicate that the ResourceBroker should never cache resources returned by this provider.

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.

 o INFINITE_CACHE
 public static final int INFINITE_CACHE
Use this when setting expire times to indicate that the ResourceBroker should cache resources returned by this provider forever.

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.

Methods

 o resourceRequest
 public abstract void resourceRequest(RequestResourceEvent request) throws ResourceUnavailableException, InterruptedException
Find a resource that already exists and make it available for use.

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.

Parameters:
ResourceUnavailableException - you refuse to allow retrieval
request - the interface between you and your many consumers
Throws: ResourceUnavailableException
request refused
Throws: InterruptedException
your thread was interrupted
 o resourceCreate
 public abstract void resourceCreate(CreateResourceEvent create) throws ResourceUnavailableException, InterruptedException
Allocate a resource that did not previously exist, possibly storing it for future reference as well.

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.

Parameters:
create - container for the resource which is to be created
Throws: ResourceUnavailableException
you refuse to allow creation
Throws: InterruptedException
thread interrupted (requested abort)
 o resourceDelete
 public abstract boolean resourceDelete(ResourceEvent delete)
Delete a resource that already exists, possibly removing it from permanent storage.

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.

Parameters:
delete - the resource to be deleted
 o resourceSave
 public abstract boolean resourceSave(ResourceEvent save)
Save a previously allocated resource, on permanent storage if necessary.

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:

Please obey, or you may deadlock!

Returns:
true if you handled it, false if the broker should try elsewhere
 o resourceThreads
 public abstract int resourceThreads()
Return the desired amount of concurrency for this provider: The broker will start up to this many threads to service requests. Specifying zero implies no concurrency at all, meaning requests will be resolved in the consumers request thread. Zero is recommended for resource providers which are CPU intensive, since they do not benefit from added concurrency, and will suffer degraded performance and liveness as a result of the thread overhead. Resource providers which are disk or network bound may benefit from concurrency and can specify the desired number of threads.

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.

 o resourceExpireTime
 public abstract int resourceExpireTime()
Return, in milliseconds, the preferred maximum amount of time the broker should cache the results of this resource provider. Note that this is advisory information only, and may not be used by the broker under all circumstances.

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