com.bigdata.jini.start
Class MonitorCreatePhysicalServiceLocksTask

java.lang.Object
  extended by com.bigdata.jini.start.MonitorCreatePhysicalServiceLocksTask
All Implemented Interfaces:
Callable<Void>

public class MonitorCreatePhysicalServiceLocksTask
extends Object
implements Callable<Void>

This task notices when a new lock node is created and creates and runs a MonitorCreatePhysicalServiceLocksTask.CreatePhysicalServiceTask to handle that lock node. The lock node represents a specific logical service instance which is short at least one physical service instance. The data of the lock node contains the zpath of the logical service instance.

Note: A single instance of this task is started by AbstractServicesManagerService.start(). Further, this task serializes service creations events using a lock. If only a single ServicesManagerServer is run per host, then this allows IServiceConstraints to be specified that restrict the mixture of services running a host.

Version:
$Id$
Author:
Bryan Thompson

Nested Class Summary
 class MonitorCreatePhysicalServiceLocksTask.CreatePhysicalServiceTask
          Task contends for the ZLock.
 
Field Summary
protected  ReentrantLock lock
          Used to serialize physical service creates on a given host.
protected static org.apache.log4j.Logger log
           
 
Constructor Summary
MonitorCreatePhysicalServiceLocksTask(JiniFederation fed, IServiceListener listener)
           
 
Method Summary
 Void call()
          Start monitoring the BigdataZooDefs.LOCKS_CREATE_PHYSICAL_SERVICE znode.
protected static net.jini.core.lookup.ServiceID getServiceID(net.jini.core.entry.Entry[] attributes)
          Return the ServiceID by finding the ServiceUUID Entry in the given attributes and converting it to a ServiceID.
protected  boolean isLocalService(net.jini.core.entry.Entry[] attributes)
          Figure out if the service lives on this host.
protected  boolean restartIfNotRunning(ManagedServiceConfiguration serviceConfig, String logicalServiceZPath, String physicalServiceZPath, net.jini.core.entry.Entry[] attributes)
          Restarts the service if it is not running.
protected  boolean restartPhysicalService(ManagedServiceConfiguration serviceConfig, String logicalServiceZPath, String physicalServiceZPath, net.jini.core.entry.Entry[] attributes)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

log

protected static final org.apache.log4j.Logger log

lock

protected final ReentrantLock lock
Used to serialize physical service creates on a given host. This is important in order for constaints on the maximum #of service instances on a single host to be respected (and assumes only a single services manager per host).

Consider: A new ServicesManagerServer starts on a host. It sees a demand for 10 data services. For each one, it tests a constraint on the maximum #of data service instances (LTE 2) and finds that it has NO data services running, so for each one it creates a data service and then it has 10. By synchronizing here we force this to single thread the service creates and in order to avoid this problem.

Note: this assumes one MonitorCreatePhysicalServiceLocksTask per ServicesManagerServer, which should be true. See the startup logic in AbstractServicesManagerService.

Note: This assumes that there is one ServicesManagerServer per host. We are not enforcing that constraint.

Note: This is also used to serialize service restarts. This prevents the possiblity of a service restart for a service which is concurrently starting. See RestartPersistentServices and restartPhysicalService(ManagedServiceConfiguration, String, String, Entry[])

Constructor Detail

MonitorCreatePhysicalServiceLocksTask

public MonitorCreatePhysicalServiceLocksTask(JiniFederation fed,
                                             IServiceListener listener)
Method Detail

call

public Void call()
          throws Exception
Start monitoring the BigdataZooDefs.LOCKS_CREATE_PHYSICAL_SERVICE znode.

Note: If the znode does not exist or ZooKeeper is not connected, then the task will keep trying to establish it watch until the znode is created.

Note: This task runs until cancelled.

Specified by:
call in interface Callable<Void>
Throws:
Exception

restartIfNotRunning

protected boolean restartIfNotRunning(ManagedServiceConfiguration serviceConfig,
                                      String logicalServiceZPath,
                                      String physicalServiceZPath,
                                      net.jini.core.entry.Entry[] attributes)
                               throws InterruptedException
Restarts the service if it is not running.

There is a small window within which a new service which is starting could qualify for restart. The physical service znode is created by the service itself. We depend on the existence of that znode to identify services for restart. If the physical service creates the ephemeral znode in the BigdataZooDefs.MASTER_ELECTION container after it creates its physical service znode and before it is registered with a ServiceRegistrar that we are also joined with then the service would qualify for "restart".

If FileLock is supported for the OS and the volume on which the serviceDir lives (NFS does not support FileLock), then the service obtains a FileLock and concurrent starts will be disallowed (an exception will be thrown by the process which does not get the FileLock). Where supported, FileLock will prevent the service from being started manually if it is already running.

The window is closed for automatic restarts by internally acquiring the same lock that is used to serialize service starts.

Parameters:
serviceConfig -
logicalServiceZPath -
physicalServiceZPath -
attributes -
Returns:
true iff the service is known to have been restarted. false will be returned if a timeout occurred while attempting to restart the service, if the service is already running, etc.
Throws:
InterruptedException - if interrupted while awaiting the lock or while re-starting the service.

getServiceID

protected static net.jini.core.lookup.ServiceID getServiceID(net.jini.core.entry.Entry[] attributes)
Return the ServiceID by finding the ServiceUUID Entry in the given attributes and converting it to a ServiceID.

Returns:
The ServiceID -or- null if no ServiceUUID Entry was found.

restartPhysicalService

protected boolean restartPhysicalService(ManagedServiceConfiguration serviceConfig,
                                         String logicalServiceZPath,
                                         String physicalServiceZPath,
                                         net.jini.core.entry.Entry[] attributes)
                                  throws InterruptedException,
                                         ExecutionException,
                                         TimeoutException,
                                         Exception
Parameters:
serviceConfig -
logicalServiceZPath -
physicalServiceZPath -
attributes -
Throws:
Exception - if the task to start the service could not be created.
TimeoutException - if the service does not start within the ServiceConfiguration.timeout
ExecutionException - if the task starting the service fails.
InterruptedException - if the task starting the service is interrupted.
IllegalMonitorStateException - if the current thread does not hold the lock.

isLocalService

protected boolean isLocalService(net.jini.core.entry.Entry[] attributes)
                          throws UnknownHostException
Figure out if the service lives on this host.

Returns:
true if the service lives on this host.
Throws:
UnknownHostException


Copyright © 2006-2009 SYSTAP, LLC. All Rights Reserved.