Details
-
Enhancement
-
Resolution: Unresolved
-
Major
-
32.0.0.Beta1
-
None
-
---
-
---
Description
The process to install a singleton service for a deployment is currently very cumbersome.
While documentation and quickstarts exist, the API itself is just plain awkward.
To summarize, the process for installing a singleton service looks like:
- Obtain the ServiceName of the target SingletonPolicy.
- Install an "installer" service, that depends on the SingletonPolicy with the name calculated above.
- Within the Service.start(...) method, create a ServiceConfigurator from the SingletonPolicy using the child target from the StartContext.
- Install the actual service using the ServiceBuilder obtained from the ServiceConfigurator.
e.g.
public void activate(ServiceActivatorContext context) { ServiceName myServiceName = ...; Service myService = ...; ServiceBuilder<?> installerBuilder = context.getServiceTarget().addService(); Supplier<SingletonPolicy> policy = installerBuilder.requires(ServiceName.parse(SingletonDefaultRequirement.POLICY.getName())); Service installerService = new Service() { @Override public void start(StartContext context) { ServiceBuilder<?> builder = policy.get().createSingletonServiceConfigurator(myServiceName).build(context.getChildTarget()); // Install myService into using this ServiceBuilder } @Override public void stop(StopContext context) { } }; installerBuilder.setInstance(new Service() { } }
Not at all intuitive, I think. The need to install a service that installs the service is especially confusing.
To simplify the user experience, I propose that we create new SingletonServiceActivator SPI extending ServiceActivator but with a default activate(...) method implementation that hides most of the above instrumentation. This will let users install singleton services as if they were normal services.
e.g.
@MetaInfServices(ServiceActivator.class) public class MySingletonServiceActivator implements SingletonServiceActivator { @Override public void activate(SingletonServiceActivatorContext context) { ServiceTarget target = context.getServiceTarget(); // Install service directly into this target } }
Much better.