Class Worker

java.lang.Object
io.superdurable.dex.Worker
All Implemented Interfaces:
AutoCloseable

public final class Worker extends Object implements AutoCloseable
Hosts synchronous Java Step and RPC implementations for registered Flows.

The worker opens outbound pull streams to Dex. It dispatches invocations on a bounded JVM executor. User methods are ordinary blocking Java methods; slow external I/O occupies a handler thread and should respect the configured Step or RPC timeout. Call start() on a dedicated application thread because it blocks until the worker stops. A worker can be started only once. The supplied BlobCache is borrowed and remains the caller's responsibility.

Worker worker = new Worker(registry, blobCache, WorkerOptions.newBuilder()
        .serverAddress("dex:8801")
        .build());
Runtime.getRuntime().addShutdownHook(new Thread(worker::stop));
worker.start();
  • Constructor Details

    • Worker

      public Worker(Registry registry, BlobCache blobCache)
      Creates a worker using local development defaults.
      Parameters:
      registry - the nonnull registry of Flow implementations
      blobCache - the nonnull cache used to hydrate blob-backed invocation values
      Throws:
      IllegalArgumentException - if either argument is null
    • Worker

      public Worker(Registry registry, BlobCache blobCache, WorkerOptions options)
      Creates a worker with explicit polling, connection, and serialization options.
      Parameters:
      registry - the nonnull registry of Flow implementations
      blobCache - the nonnull cache used to hydrate blob-backed invocation values
      options - the nonnull worker options
      Throws:
      IllegalArgumentException - if any argument is null or the pull Worker ID conflicts with a registered Flow type
  • Method Details

    • start

      public void start()
      Starts the worker pull streams and blocks until termination.

      Only a newly created worker may start. It requires Server protocol 4 before syncing Attribute indexes and opening the pull streams. If the waiting thread is interrupted, the worker stops and restores the thread's interruption status before returning.

      Throws:
      PullRegistrationError - if an uncovered permanent stream rejection stops the Worker with stopOnPermanentStreamRejection enabled, before or after readiness
      IllegalStateException - if the worker was already started or startup fails
    • waitPullRegistered

      public void waitPullRegistered(Duration timeout) throws InterruptedException, TimeoutException
      Waits for a STEP_AND_RPC stream and, when reserved, an RPC_ONLY stream to register.

      Start the Worker on another thread. Multiple callers may wait independently, before or after start. Success latches even after stop; use getPullRegistrationState for later probes. Before readiness, a permanent rejection fails this wait only if that slot kind has no other registered stream. Startup failures are propagated to waiters. Interrupting this wait leaves the Worker running.

      Thread workerThread = new Thread(worker::start);
      workerThread.start();
      worker.waitPullRegistered(Duration.ofSeconds(30));
      boolean isReady = worker.getPullRegistrationState().isReady();
      
      Parameters:
      timeout - the nonnull, nonnegative maximum wait duration
      Throws:
      InterruptedException - if the waiting thread is interrupted
      TimeoutException - if the timeout expires before readiness
      PullRegistrationError - if a slot kind is permanently rejected before readiness
      IllegalArgumentException - if timeout is null or negative
      IllegalStateException - if startup fails, including when maxConcurrentTasks exceeds the Server's per-Worker limit, or the Worker stops before readiness
    • getPullReservedRpcDeclines

      @Deprecated public long getPullReservedRpcDeclines()
      Deprecated.
      reserved slots no longer decline tasks for capacity
      Returns zero for the legacy reserved-RPC decline counter.

      Reserved execution slots prevent capacity declines. This method remains safe to call concurrently and after shutdown.

      Returns:
      always zero
    • getPullRegistrationState

      public PullRegistrationState getPullRegistrationState()
      Returns an independent snapshot for pull Worker readiness probes.

      After initial readiness, transient failures, reconnects, and stop keep readiness true. A permanent rejection makes it false only while that slot kind has no registered stream. Re-registration clears the error. Safe concurrently with start, stop, and registration waits. See waitPullRegistered for a startup example.

      Returns:
      immutable slot-kind state through the legacy queue accessors
    • stop

      public void stop()
      Gracefully stops the pull streams, handler executor, and server channel.

      The method is idempotent. The Worker drains for the configured stop timeout, then cancels remaining handlers and waits for them to return. A handler ignoring cancellation can block Stop. Interruption status is preserved.

      Stop starts no new task. Idle streams half-close immediately and drop later task frames. Busy streams finish their handler and send its final output before half-closing. Streams keep reading until the Server ends them. If the timeout expires, a running task's stream is reset with a transport error instead of half-closing. A half-closed stream that the Server has not ended by then is also reset, for example after a network partition. A task the Server sent on such a stream counts as one that may have run.

      A stream that has sent a final output is not reset at the timeout until the Server confirms that output. The Server confirms it by ending the stream or by assigning the stream's next task. This holds even when the handler has returned or the stream has half-closed. Such a stream gets a five-second flush grace and is reset only after it. So stop can return up to five seconds after the stop timeout, plus the time handlers take to return after cancellation.

    • close

      public void close()
      Stops the worker with stop() drain semantics and permanently closes its lifecycle.

      The application owns any supplied Credential and the borrowed BlobCache.

      Specified by:
      close in interface AutoCloseable