Interface VespaCurator.SingletonWorker

Enclosing interface:
VespaCurator

public static interface VespaCurator.SingletonWorker
Callback interface for processes of which only a single instance should be active at any time, across all containers in the cluster, and across all component generations.


Sample usage:

 public class SingletonHolder extends AbstractComponent {

     private static final Duration timeout = Duration.ofSeconds(10);
     private final VespaCurator curator;
     private final SingletonWorker singleton;

     public SingletonHolder(VespaCurator curator) {
         this.curator = curator;
         this.singleton = new Singleton();
         curator.register(singleton, timeout);
     }

     @Override
     public void deconstruct() {
         curator.unregister(singleton, timeout);
         singleton.shutdown();
     }

 }

 public class Singleton implements SingletonWorker {

     private final SharedResource resource = ...; // Shared resource that requires exclusive access.
     private final ExecutorService executor = Executors.newSingleThreadExecutor();
     private final AtomicBoolean running = new AtomicBoolean();
     private Future<?> future = null;

     @Override
     public void activate() {
         resource.open(); // Verify resource works here, and propagate any errors out.
         running.set(true);
         future = executor.submit(this::doWork);
     }

     @Override
     public void deactivate() {
         running.set(false);
         try { future.get(10, TimeUnit.SECONDS); }
         catch (Exception e) { ... }
         finally { resource.close(); }
     }

     private void doWork() {
         while (running.get()) { ... } // Regularly check whether we should keep running.
     }

     public void shutdown() {
         executor.shutdownNow(); // Executor should have no running tasks at this point.
     }

 }
 


Notes to implementors:

  • activate() is called by the system on a singleton whenever it is the newest registered singleton in this container, and this container has the lease for the ID with which the singleton was registered. See id(), VespaCurator.register(com.yahoo.vespa.curator.api.VespaCurator.SingletonWorker, java.time.Duration) and VespaCurator.isActive(java.lang.String).
  • deactivate() is called by the system on a singleton which is currently active whenever the above no longer holds. See VespaCurator.unregister(com.yahoo.vespa.curator.api.VespaCurator.SingletonWorker, java.time.Duration).
  • Callbacks for the same ID are always invoked by the same thread, in serial; the callbacks must return in a timely manner, but are encouraged to throw exceptions when something's wrong
  • Activation and deactivation may be triggered by:
    1. the container acquiring or losing the activation lease; or
    2. registration of unregistration of a new or obsolete singleton.
    Events triggered by the latter happen synchronously, and errors are propagated to the caller for cleanup. Events triggered by the former may happen in the background, and because the system tries to always have one activated singleton, exceptions during activation will cause the container to abandon its lease, so another container may obtain it instead; exceptions during deactivation are only logged.
  • A container without any registered singletons will not attempt to hold the activation lease.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Called by the system whenever this singleton becomes the single active worker.
    void
    Called by the system whenever this singleton is no longer the single active worker.
    default String
    id()
    The singleton ID to use when registering this with a VespaCurator.
  • Method Details

    • activate

      void activate()
      Called by the system whenever this singleton becomes the single active worker. If this is triggered because the container obtains the activation lease, and activation fails, then the container immediately releases the lease, so another container may acquire it instead.
    • deactivate

      void deactivate()
      Called by the system whenever this singleton is no longer the single active worker.
    • id

      default String id()
      The singleton ID to use when registering this with a VespaCurator. At most one singleton worker with the given ID will be active, in the cluster, at any time. VespaCurator.isActive(String) may be polled to see whether this container is currently allowed to have an active singleton with the given ID.