org.apache.derby.impl.services.daemon
Class BasicDaemon

java.lang.Object
  extended by org.apache.derby.impl.services.daemon.BasicDaemon
All Implemented Interfaces:
java.lang.Runnable, DaemonService

public class BasicDaemon
extends java.lang.Object
implements DaemonService, java.lang.Runnable

A BasicDaemon is a background worker thread which does asynchronous I/O and general clean up. It should not be used as a general worker thread for parallel execution. One cannot count on the order of request or count on when the daemon will wake up, even with serviceNow requests. Request are not persistent and not recoverable, they are all lost when the system crashes or is shutdown. System shutdown, even orderly ones, do not wait for daemons to finish its work or empty its queue. Furthermore, any Serviceable subscriptions, including onDemandOnly, must tolerate spurious services. The BasicDaemon will setup a context manager with no context on it. The Serviceable object's performWork must provide useful context on the context manager to do its work. The BasicDaemon will wrap performWork call with try / catch block and will use the ContextManager's error handling to clean up any error. The BasicDaemon will guarentee serviceNow request will not be lost as long as the jbms does not crash - however, if N serviceNow requests are made by the same client, it may only be serviced once, not N times. Many Serviceable object will subscribe to the same BasicDaemon. Their performWork method should be well behaved - in other words, it should not take too long or hog too many resources or deadlock with anyone else. And it cannot (should not) error out. The BasicDaemon implementation manages the DaemonService's data structure, handles subscriptions and enqueues requests, and determine the service schedule for its Serviceable objects. The BasicDaemon keeps an array (Vector) of Serviceable subscriptions it also keeps 2 queues for clients that uses it for one time service - the 1st queue is for a serviceNow enqueue request, the 2nd queue is for non serviceNow enqueue request. This BasicDaemon services its clients in the following order: 1. any subscribed client that have made a serviceNow request that has not been fulfilled 2. serviceable clients on the 1st queue 3. all subscribed clients that are not onDemandOnly 4. serviceable clients 2nd queue


Field Summary
private  boolean awakened
           
protected  ContextManager contextMgr
           
protected  ContextService contextService
           
private  int earlyWakeupCount
           
private  java.util.List highPQ
          Queues for the work to be done.
private  boolean inPause
           
private  long lastServiceTime
           
private  int nextService
          which subscribed clients to service next?
private  java.util.List normPQ
           
private  int numClients
           
private static int OPTIMAL_QUEUE_SIZE
           
private  boolean running
           
private  boolean stopped
           
private  boolean stopRequested
           
private  java.util.Vector subscription
           
private  boolean waiting
          true if I'm waiting, if this is false then I am running and a notify is not required.
 
Fields inherited from interface org.apache.derby.iapi.services.daemon.DaemonService
DaemonOff, DaemonTrace, TIMER_DELAY
 
Constructor Summary
BasicDaemon(ContextService contextService)
          make a BasicDaemon
 
Method Summary
 void clear()
          Get rid of all queued up Serviceable tasks.
 boolean enqueue(Serviceable newClient, boolean serviceNow)
          Request a one time service from the Daemon.
private  boolean inPause()
           
protected  ServiceRecord nextAssignment(boolean urgent)
           
 void pause()
          Pause.
private  boolean rest()
          Returns true if awakened by some notification, false if wake up by timer
 void resume()
          Resume service after a pause
 void run()
           
protected  void serviceClient(ServiceRecord clientRecord)
           
 void serviceNow(int clientNumber)
          Service this subscription ASAP.
 void stop()
          Finish what we are doing and at the next convenient moment, get rid of the thread and make the daemon object goes away if possible.
private  boolean stopRequested()
           
 int subscribe(Serviceable newClient, boolean onDemandOnly)
          Add a new client that this daemon needs to service
 void unsubscribe(int clientNumber)
          Removes a client from the list of subscribed clients.
 void waitUntilQueueIsEmpty()
           
protected  void wakeUp()
           
private  void work(boolean urgentOnly)
           
private  void yield()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

numClients

private int numClients

OPTIMAL_QUEUE_SIZE

private static final int OPTIMAL_QUEUE_SIZE
See Also:
Constant Field Values

subscription

private final java.util.Vector subscription

contextService

protected final ContextService contextService

contextMgr

protected final ContextManager contextMgr

highPQ

private final java.util.List highPQ
Queues for the work to be done. These are synchronized by this object.


normPQ

private final java.util.List normPQ

nextService

private int nextService
which subscribed clients to service next? only accessed by daemon thread


awakened

private boolean awakened

waiting

private boolean waiting
true if I'm waiting, if this is false then I am running and a notify is not required.


inPause

private boolean inPause

running

private boolean running

stopRequested

private boolean stopRequested

stopped

private boolean stopped

lastServiceTime

private long lastServiceTime

earlyWakeupCount

private int earlyWakeupCount
Constructor Detail

BasicDaemon

public BasicDaemon(ContextService contextService)
make a BasicDaemon

Method Detail

subscribe

public int subscribe(Serviceable newClient,
                     boolean onDemandOnly)
Description copied from interface: DaemonService
Add a new client that this daemon needs to service

Specified by:
subscribe in interface DaemonService
Parameters:
newClient - a Serviceable object this daemon will service from time to time
onDemandOnly - only service this client when it ask for service with a serviceNow request
Returns:
a client number that uniquely identifies this client (this subscription)

unsubscribe

public void unsubscribe(int clientNumber)
Removes a client from the list of subscribed clients. The call does not wait for the daemon to finish the work it is currently performing. Therefore, the client must tolerate that its performWork() method could be invoked even after the call to unsubscribe() has returned (but not more than once).

Specified by:
unsubscribe in interface DaemonService
Parameters:
clientNumber - client identifier

serviceNow

public void serviceNow(int clientNumber)
Description copied from interface: DaemonService
Service this subscription ASAP. When this method is called, the subscriber's performWork() method is guaranteed to be invoked at some point in the future. However, there is no guarantee that a subscriber's performWork() is called the same number of times as the subscriber calls this method. More precisely, if a subscriber is waiting for this daemon service to invoke its performWork() method, the daemon service may, but is not required to, ignore requests from that subscriber until the performWork() method has been invoked.

Specified by:
serviceNow in interface DaemonService
Parameters:
clientNumber - the number that uniquely identifies the client

enqueue

public boolean enqueue(Serviceable newClient,
                       boolean serviceNow)
Description copied from interface: DaemonService
Request a one time service from the Daemon. Unless performWork returns REQUEUE (see Serviceable), the daemon will service this client once and then it will get rid of this client. Since no client number is associated with this client, it cannot request to be serviced or be unsubscribed. The work is always added to the deamon, regardless of the state it returns.

Specified by:
enqueue in interface DaemonService
Parameters:
newClient - the object that needs a one time service
serviceNow - if true, this client should be serviced ASAP, as if a serviceNow has been issued. If false, then this client will be serviced with the normal scheduled.
Returns:
true if the daemon indicates it is being overloaded, false it's happy.

clear

public void clear()
Get rid of all queued up Serviceable tasks.

Specified by:
clear in interface DaemonService

nextAssignment

protected ServiceRecord nextAssignment(boolean urgent)

serviceClient

protected void serviceClient(ServiceRecord clientRecord)

run

public void run()
Specified by:
run in interface java.lang.Runnable

pause

public void pause()
Description copied from interface: DaemonService
Pause. No new service is performed until a resume is issued.

Specified by:
pause in interface DaemonService

resume

public void resume()
Description copied from interface: DaemonService
Resume service after a pause

Specified by:
resume in interface DaemonService

stop

public void stop()
Finish what we are doing and at the next convenient moment, get rid of the thread and make the daemon object goes away if possible. remember we are calling from another thread

Specified by:
stop in interface DaemonService

waitUntilQueueIsEmpty

public void waitUntilQueueIsEmpty()
Specified by:
waitUntilQueueIsEmpty in interface DaemonService

stopRequested

private boolean stopRequested()

inPause

private boolean inPause()

wakeUp

protected void wakeUp()

rest

private boolean rest()
Returns true if awakened by some notification, false if wake up by timer


work

private void work(boolean urgentOnly)

yield

private void yield()

Built on Thu 2011-03-10 11:54:14+0000, from revision ???

Apache Derby V10.6 Internals - Copyright © 2004,2007 The Apache Software Foundation. All Rights Reserved.