org.wildfly.clustering.singleton.server.DistributedSingletonServiceBuilder Maven / Gradle / Ivy
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/
package org.wildfly.clustering.singleton.server;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function;
import org.jboss.msc.Service;
import org.jboss.msc.service.ServiceBuilder;
import org.jboss.msc.service.ServiceController;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceTarget;
import org.wildfly.clustering.singleton.Singleton;
import org.wildfly.clustering.singleton.service.SingletonServiceBuilder;
import org.wildfly.clustering.singleton.service.SingletonServiceController;
import org.wildfly.common.function.Functions;
import org.wildfly.service.AsyncServiceBuilder;
/**
* A service builder that installs a distributed singleton service.
* @author Paul Ferraro
*/
public class DistributedSingletonServiceBuilder extends AbstractSingletonServiceBuilder {
private final ServiceName id = ServiceName.parse(UUID.randomUUID().toString());
private final Function> builderFactory;
private final List>>> injectors = new LinkedList<>();
private final SingletonServiceBuilderContext context;
private final Consumer singleton;
private final SingletonReference reference = new SingletonReference();
public DistributedSingletonServiceBuilder(ServiceBuilder builder, Function> builderFactory, SingletonServiceBuilderContext context, Function, Consumer> singletonFactory) {
super(new AsyncServiceBuilder<>(builder, builder.requires(ServiceName.parse("org.wildfly.management.executor"))), context);
this.builderFactory = builderFactory;
this.context = context;
Consumer injector = builder.provides(this.id);
this.singleton = singletonFactory.apply(builder).andThen(this.reference).andThen(injector);
}
@SuppressWarnings("unchecked")
@Override
public Consumer provides(ServiceName... names) {
if (names.length == 0) return Functions.discardingConsumer();
this.context.setServiceName(names[0]);
AtomicReference> injector = new AtomicReference<>();
this.injectors.add(Map.entry(names, ((AtomicReference>) (AtomicReference>) injector)::set));
return new Consumer<>() {
@Override
public void accept(V value) {
injector.get().accept(value);
}
};
}
@Override
public SingletonServiceBuilder setInstance(Service service) {
this.context.setService(service);
return this;
}
@Override
public SingletonServiceController install() {
// Identify singleton service via its id if caller did not provide one
this.context.setServiceName(this.id);
ServiceController controller = this.getDelegate().setInstance(new DistributedSingletonService(this.context, this.builderFactory, this.injectors, this.singleton)).install();
return new DistributedSingletonServiceController<>(controller, this.reference);
}
}