JXTA

net.jxta.impl.util
Class ResourceDispatcher

java.lang.Object
  extended by net.jxta.impl.util.ResourceDispatcher

public class ResourceDispatcher
extends Object

This class does not in itself allocate anything; it just does accounting. Its role is to make sure that resource consumers ("accounts") are guaranteed to be able to hold a pre-determined number of items, the extra being granted on a first-come-first-serve basis. It just replies yes/no to an account that wants to allocate an item. Synchronization is external.

Note that this is all essentially a limiter device. It assumes that the resources that are dispatched in that way are not otherwise in short supply.

The rules of the game are as follows:

At initialization, an absolute maximum authorized number of items is computed. All item reservations and authorizations are done within this budget.

At any given point in time, out of this maximum, a number of items are permanently reserved for the minimum guaranteed to each current account, a number of items are set aside for future accounts guarantee reservation, and the rest is open for dynamic attribution on a first come first serve basis.

The current strategy is as follows: The initialization parameters are:

We infer the number of items dedicated to reservation: reservedItems That is minReserve * minAccounts.

Accounts can ask for a commitment in excess of minReserve. Any reservation made by an account beyond the minimum is satisfied from extraItems limited by what's available and maxReserve. When minAccounts have registered, it is possible that reservedItems is exhausted. New accounts are then accepted on a best effort basis using extra items exclusively. This may cause such new accounts to be given a commitment inferior to minReserve, including zero. It is up to the account to reject the offer and give up by closing, or to go along with the offer. At this time, we do not try to raise the commitment made to an account while it is registered.

During the life of the account, items are allocated first from the set reserved by this account. If the account is out of reserved items, an attempt is made at getting the item from extraItems.

For each account we count the number of items reserved from reservedItems, reserved from extraItems, allocated from the local reserved items and allocated from extraItems separately. When an item is released, it is accounted to extraItems if the account had anything allocated from extra items, or to the local reserved items. When an account goes away, the number of items that were reserved from reserveItems go back to reserveItems and likewise for those coming from extraItems. This is done rather than giving priority to reserve items so that the system does not favor reservation beyond its initial parameters when an account goes away under load.

When resources are scarce, two modes of operations are available.

Unfair
each account keeps its items as long it has a use for them. If the allocation of a new item is denied for an account, the account just has to live with it and try again the next time more items are desired.
RoundRobin
Each account releases each item after one use. When allocation of a new item is denied for an account by reason of item shortage, the account is placed on a list of eligible accounts. Every time an item is released, it is re-assigned to the oldest eligible account.

From an API point of view the difference is not visible: account users are advised to release items after one use. Release returns the account to which the item has been re-assigned. If RoundRobin is not used, then the item is always re-assigned to the account that releases it unless it is not needed, in which case it returns to the available pool. So, with round-robin off the following is true:

 a.releaseItem() == (a.needs ? a : null);
 


Nested Class Summary
(package private)  class ResourceDispatcher.ClientAccount
           
 
Constructor Summary
ResourceDispatcher(long minAccounts, long minReservedPerAccount, long maxReservedPerAccount, long extraItems, long maxExtraPerAccount, long minExtraPoolSize, boolean roundRobin, String dispatcherName)
          Construct a Fair Resource Allocator with the given parameters:
 
Method Summary
 int getNbEligibles()
           
 ResourceAccount newAccount(long nbReq, long maxExtra, Object userObject)
          Creates and returns a new client account.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ResourceDispatcher

public ResourceDispatcher(long minAccounts,
                          long minReservedPerAccount,
                          long maxReservedPerAccount,
                          long extraItems,
                          long maxExtraPerAccount,
                          long minExtraPoolSize,
                          boolean roundRobin,
                          String dispatcherName)
Construct a Fair Resource Allocator with the given parameters:

Parameters:
minAccounts - The minimum number of client accounts that we want to guarantee we can handle. <0 means 0
minReservedPerAccount - The minimum reservation request that we will always grant to accounts as long as we have less than minAccounts <0 means 0.
maxReservedPerAccount - The maximum reservation request that we ever will grant to any given account. extraItems - The total number of items that we will authorize beyond what has been reserved. <0 means 0.
maxExtraPerAccount - The maximum number of extra items we will ever let any given account occupy. <0 or >extraItems means ==extraItems.
minExtraPoolSize - The number of extra items that can never be taken out of the extra pool to satisfy a reservation request.
roundRobin - If true, when there is no items available, all eligible accounts are put in a FIFO. Accounts release items often, and the oldest account in the FIFO will get it. If false, accounts always keep items for as long as they can use them, and there is no FIFO of eligible accounts. Accounts can obtain new resources only if available at the time they try to aquire it. RoundRobin is more fair but has more overhead. Neither mode will cause starvation as long as accounts reserve at least one item each. RoundRobin is most useful when allocating threads.
Method Detail

getNbEligibles

public int getNbEligibles()

newAccount

public ResourceAccount newAccount(long nbReq,
                                  long maxExtra,
                                  Object userObject)
Creates and returns a new client account.

Parameters:
nbReq - the number of reserved items requested (may not be always granted in full). A negative value is taken to mean 0.
maxExtra - the number of additional items that this account authorizes to be allocated in addition to the reserved ones. This is typically useful if the items are threads and if some accounts are not re-entrant. Then nbReq would be 1 and maxExtra would be 0. It is also permitted to have some accounts receive no items at all ever by setting nbReq and maxExtra both to zero. A negative maxExtra is taken as meaning no specified limit, in which case an actual limit may be set silently.
userObject - An opaque cookie that the account object will return when requested. This is useful to relate an account returned by ClientAccount.releaseItem() to an invoking code relevant object.
Returns:
ResourceAccount An account with this allocator.

JXSE