Class NatsKlient

  • All Implemented Interfaces:
    java.lang.AutoCloseable

    
    public final class NatsKlient
     implements AutoCloseable
                        

    Main entry point for NATS messaging with Kotlin-first API

    This class manages the NATS connection lifecycle and provides access to messaging operations through the NatsScope.

    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      public class NatsKlient.Companion
    • Constructor Summary

      Constructors 
      Constructor Description
    • Enum Constant Summary

      Enum Constants 
      Enum Constant Description
    • Method Summary

      Modifier and Type Method Description
      final NatsScope getScope() Persistent scope for long-lived operations (subscriptions, consumers, etc.
      final Connection getConnection() Direct access to the underlying NATS connection for advanced use cases
      final Statistics getStatistics() Access to connection statistics
      final <T extends Any> T session(SuspendFunction1<NatsScope, T> block) Execute operations against a NatsScope whose lifetime is exactly blockThe scope owns a child Job of the calling coroutine, so everything launched into it — subscriptions above all — is cancelled and awaited when block returns, before the scope's jnats dispatchers are closed.
      final Boolean drain(Duration timeout) Gracefully drain the connection, then close itSuspends until the drain has actually finished.
      final Boolean closeGracefully(Duration timeout) Drain, then close: the complete shutdown sequence in one calldrain delivers what is already in flight and closes the connection; close then cancels scope and releases its dispatchers.
      final Boolean closeBlocking(Duration timeout) closeGracefully for callers that cannot suspendBlocks the calling thread for up to timeout on the drain.
      Unit close() Cancel everything running on scope and close the connection immediatelycloseGracefully is the graceful counterpart: it drains first, so nothing in flight is lost.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

    • Method Detail

      • getScope

         final NatsScope getScope()

        Persistent scope for long-lived operations (subscriptions, consumers, etc.)

        This scope lives for the entire lifetime of the NatsKlient instance and is cancelled by close, so nothing launched into it outlives the klient.

        Use this for:

        • Long-lived subscriptions that should persist for the application lifetime

        • Publishing messages without creating a new scope each time

        • JetStream consumers that need to stay active

        Example:

        klient.scope.subscribe<Event>("events").messages
            .onEach { processEvent(it) }
            .launchIn(applicationScope)
      • getConnection

         final Connection getConnection()

        Direct access to the underlying NATS connection for advanced use cases

      • getStatistics

         final Statistics getStatistics()

        Access to connection statistics

      • session

         final <T extends Any> T session(SuspendFunction1<NatsScope, T> block)

        Execute operations against a NatsScope whose lifetime is exactly block

        The scope owns a child Job of the calling coroutine, so everything launched into it — subscriptions above all — is cancelled and awaited when block returns, before the scope's jnats dispatchers are closed. Work that must outlive the call belongs on scope instead.

        This opens a scope; it does not close the klient. The name is deliberately not use: as a member it would win overload resolution over the stdlib AutoCloseable.use this class now supports, so klient.use { } would silently mean "open a scope" rather than "close when done".

        klient.session {
            subscribe<Event>("events").messages.onEach { handle(it) }.launchIn(this)
            delay(1.minutes) // the subscription collects until the block returns, then stops
        }
      • drain

         final Boolean drain(Duration timeout)

        Gracefully drain the connection, then close it

        Suspends until the drain has actually finished. jnats only unsubscribes and flushes before its Connection.drain returns — delivering the remaining in-flight messages, blocking further publishing, doing a last flush and closing the connection all happen on a background thread, and only the returned future tells you when that is done. This awaits that future, so once this returns it is safe to exit the process without losing messages.

        Draining closes the connection, so the klient is not reusable afterwards. close is still worth calling to release the scope-side resources; it returns immediately on an already-closed connection. closeGracefully is that pair in one call.

        Parameters:
        timeout - budget for the whole drain.
        Returns:

        true if every subscription drained within timeout, false if the timeout forced the close. Also true when the connection was already closed and there was nothing to do.

      • closeGracefully

         final Boolean closeGracefully(Duration timeout)

        Drain, then close: the complete shutdown sequence in one call

        drain delivers what is already in flight and closes the connection; close then cancels scope and releases its dispatchers. The order matters — cancelling first would kill the subscriptions the drain exists to deliver to.

        The klient always ends up closed, even if the drain fails or the caller is cancelled mid-way.

        Drain waits for delivery, not for your handlers: a collector on scope that is still processing its last message when the drain finishes is cancelled like any other. Work that has to finish belongs in front of this call.

        Parameters:
        timeout - budget for the drain, as in drain
        Returns:

        true if every subscription drained within timeout, false if the timeout forced the close

      • closeBlocking

         final Boolean closeBlocking(Duration timeout)

        closeGracefully for callers that cannot suspend

        Blocks the calling thread for up to timeout on the drain. That is what non-suspending shutdown hooks need — Koin's onClose, a JVM shutdown hook, a Ktor MonitoringEvent handler — where the process must not exit until the drain has finished.

        From inside a coroutine closeGracefully is the one to call: this parks the thread it runs on for the whole drain.

        Parameters:
        timeout - budget for the drain, as in drain
        Returns:

        true if every subscription drained within timeout, false if the timeout forced the close

      • close

         Unit close()

        Cancel everything running on scope and close the connection immediately

        closeGracefully is the graceful counterpart: it drains first, so nothing in flight is lost.

        Cancellation is signalled, not awaited: close cannot suspend, so a coroutine that is still unwinding on scope may briefly outlive the call.

        The cancellation comes first so that work still touching the connection observes cancellation rather than an I/O failure against a connection pulled out from under it.

        Idempotent, and safe on a klient whose scope was never touched: an unused scope is not created just to be torn down.