@Singleton @Visibility(value=LOCAL) public class ImmediateHelper extends Object implements DynamicConfigurationListener, Runnable, ValidationService, ErrorService, Validator, ImmediateController
Service
This implementation uses a lot of facilities of hk2, so lets explain each one.
The thing that makes Immediate services immediate is that they are started as soon as they are noticed. This is done by implementing the DynamicConfigurationListener, as it will get notified when a configuration has changed. However, since the creation of user services can take an arbitrarily long time it is better to do that work on a separate thread, which is why we implement Runnable. The run method is the method that will pull from the queue of work and instantiate (and destroy) the immediate services.
However, there is also a desire to be highly efficient. This means we should not be creating this thread if there is no work for the thread to do. For this to work we need to know which configuration changes have added or removed an Immediate service. To know this we have implemented the Validation service and Validator. The validation service records the thread id of a configuration operation that is adding or removing services. This thread id goes into a map. But we have to be sure that the map does not grow without bound. To do this we clear the map both when the configuration service has succeeded (in the DynamicConfigurationListener) and when the configuration service has failed (in the ErrorService). This is why we have implemented the ErrorService.
ImmediateController.ImmediateServiceState
Modifier and Type | Method and Description |
---|---|
void |
configurationChanged()
This method is called when the set of descriptors
in this service locator has been changed.
|
Executor |
getExecutor()
Returns the executor that is currently in use by the Immediate subsystem
|
ImmediateController.ImmediateServiceState |
getImmediateState()
Returns the state the system is currently running under
|
Filter |
getLookupFilter()
This filter will be run at least once per descriptor at the point that the descriptor
is being looked up, either with the
ServiceLocator API or due to
an @Inject resolution. |
long |
getThreadInactivityTimeout()
Returns the time in milliseconds a thread will wait for new Immediate
services before dying
|
Validator |
getValidator()
Returns the
Validator that will be run whenever
a Descriptor that passed the filter is to be looked up with the API
or injected into an injection point, or on any bind or unbind operation. |
void |
onFailure(ErrorInformation errorInformation)
This method is called when a failure occurs in the system.
|
void |
run()
This thread will wait twenty seconds for new work to come in, and then
kill itself
|
void |
setExecutor(Executor executor)
Sets the executor to be used by the Immediate subsystem.
|
void |
setImmediateState(ImmediateController.ImmediateServiceState state)
Sets the state the system is currently running under
|
void |
setThreadInactivityTimeout(long timeInMillis)
Sets the time in milliseconds a thread will wait for new Immediate
services before dying
|
boolean |
validate(ValidationInformation info)
This method is called whenever it has been determined that a validating
class is to be injected into an injection point, or when a descriptor
is being looked up explicitly with the API, or a descriptor is being
bound or unbound into the registry.
|
public void configurationChanged()
DynamicConfigurationListener
DynamicConfiguration.commit()
so care should be taken
to do any work quickly. Any exception thrown from this method
will be ignored. A commit that failed will not be reported to
this methodconfigurationChanged
in interface DynamicConfigurationListener
public Filter getLookupFilter()
ValidationService
ServiceLocator
API or due to
an @Inject resolution. The decision made by this filter will be cached and
used every time that Descriptor is subsequently looked up. No validation checks
should be done in the returned filter, it is purely meant to limit the
Descriptor
s that are passed into the validator.
Descriptors passed to this filter may or may not be reified. The filter should try as much as possible to do its work without reifying the descriptor.
The filter may be run more than once on a descriptor if some condition caused the cache of results per descriptor to become invalidated.
getLookupFilter
in interface ValidationService
Descriptor
is looked uppublic Validator getValidator()
ValidationService
Validator
that will be run whenever
a Descriptor
that passed the filter is to be looked up with the API
or injected into an injection point, or on any bind or unbind operation.
If this method returns false then the operation will not proceed.getValidator
in interface ValidationService
public void onFailure(ErrorInformation errorInformation) throws MultiException
ErrorService
ServiceLocator
api. For example, an implementation of this method might want
to remove a descriptor from the registry if the error can be determined to be a
permanent failure.onFailure
in interface ErrorService
errorInformation
- Information about the error that occurredMultiException
- if this method throws an exception that exception will be thrown back to
the caller wrapped in another MultiException if the error is of type ErrorType.FAILURE_TO_REIFY
.
If the error is of type ErrorType.DYNAMIC_CONFIGURATION_FAILURE
or ErrorType.SERVICE_CREATION_FAILURE
or ErrorType.SERVICE_DESTRUCTION_FAILURE
then any exception thrown from this
method is ignored and the original exception is thrown back to the callerpublic boolean validate(ValidationInformation info)
Validator
The candidate descriptor being passed in may not have yet been reified. If possible, this method should do its work without reifying the descriptor. However, if it is necessary to reify the descriptor, it should be done with the ServiceLocator.reifyDescriptor method.
The operation will determine what operation is being performed. In the
BIND or UNBIND cases the Injectee will be null. In the LOOKUP case
the Injectee will be non-null if this is being done as part of an
injection point. In the LOOKUP case the Injectee will be null if this
is being looked up directly from the ServiceLocator
API, in which
case the caller of the lookup method will be on the call frame.
public void run()
public Executor getExecutor()
ImmediateController
getExecutor
in interface ImmediateController
public void setExecutor(Executor executor) throws IllegalStateException
ImmediateController
setExecutor
in interface ImmediateController
executor
- The executor to be used when scheduling work. If null
a default executor implementation will be usedIllegalStateException
- if this is called when the Immediate service
is not in suspended statepublic long getThreadInactivityTimeout()
ImmediateController
getThreadInactivityTimeout
in interface ImmediateController
public void setThreadInactivityTimeout(long timeInMillis) throws IllegalStateException
ImmediateController
setThreadInactivityTimeout
in interface ImmediateController
timeInMillis
- The time in milliseconds a thread will wait for new
Immediate service before dyingIllegalStateException
public ImmediateController.ImmediateServiceState getImmediateState()
ImmediateController
getImmediateState
in interface ImmediateController
public void setImmediateState(ImmediateController.ImmediateServiceState state)
ImmediateController
setImmediateState
in interface ImmediateController
state
- The new state of the ImmediateServiceCopyright © 2009-2017, Oracle and/or its affiliates. All Rights Reserved.