Skip to content

leanish/terminator

Repository files navigation

Terminator

Terminator is a small Java library that coordinates the orderly shutdown of heterogeneous services. It understands two kinds of services:

  • Blocking services (BlockingTerminable) that finish all work before returning from terminate().
  • Non-blocking services (NonBlockingTerminable) that initiate shutdown in the background and expose awaitTermination(Duration) to finish up.

The coordinator makes sure non-blocking services are signalled first and waited on, while blocking services are stopped afterwards in reverse registration order. It also keeps you honest about interrupts and timeout handling so shutdown code stays responsive.

Key features

  • Register any number of blocking or non-blocking services using distinct marker interfaces.
  • Initiate shutdown once with Terminator#terminate(), or call it repeatedly without side effects.
  • Wait for the async tail of shutdown to finish with awaitTermination(Duration); negative durations are treated as zero, and a zero wait is still passed through to the services.
  • Aggregates failures thrown during termination, keeping the first as the cause and suppressing the rest.
  • Propagates interrupts consistently during both terminate() and awaitTermination().

Quick start

Add the dependency to your Gradle build:

dependencies {
    implementation 'io.github.leanish:terminator:0.1.0'
}

Implement services

class HttpServer implements BlockingTerminable {
    private final Server server;

    ...
    
    @Override
    public void terminate()
            throws InterruptedException {
        server.stop(); // blocks until fully stopped
    }
}

class QueueProcessor implements NonBlockingTerminable {
    private final ExecutorService executor;

    ...

    @Override
    public void terminate() {
        executor.shutdown(); // starts shutdown but returns immediately
    }

    @Override
    public boolean awaitTermination(Duration timeout)
            throws InterruptedException {
        return executor.awaitTermination(timeout.toNanos(), TimeUnit.NANOSECONDS);
    }
}

Coordinate shutdown

Terminator terminator = new Terminator();
terminator.register(httpServer);
terminator.register(queueProcessor);

...

terminator.terminate();
boolean finished = terminator.awaitTermination(Duration.ofSeconds(5));
if (!finished) {
    // log or trigger fallback action
}

Building & testing

This project uses Gradle 8 and Java 21:

./gradlew build   # compile, test, package
./gradlew test    # run the test suite

To regenerate the API documentation:

./gradlew javadoc

Change log

See CHANGELOG.md for notable updates.

Contributing

Issues and pull requests are welcome. Please run ./gradlew test locally before submitting changes.

License

This project is distributed under the terms of the MIT License.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors 2

  •  
  •  

Languages