Class AbstractAlpacaStream

java.lang.Object
markets.alpaca.client.ws.internal.AbstractAlpacaStream
All Implemented Interfaces:
AutoCloseable
Direct Known Subclasses:
AbstractMarketDataStream, AlpacaTradingStream

public abstract class AbstractAlpacaStream extends Object implements AutoCloseable
Base class for all Alpaca WebSocket stream clients.

Manages the OkHttp WebSocket connection lifecycle, automatic reconnection with jittered exponential backoff, and a thread-safe close flag. Subclasses implement the protocol specifics via template methods.

Thread safety: close() is safe to call from any thread. All template methods are invoked on OkHttp's internal I/O thread.

  • Constructor Details

  • Method Details

    • buildRequest

      protected abstract okhttp3.Request buildRequest()
      Builds the WebSocket upgrade request (URL + any auth headers).
    • handleOpen

      protected abstract void handleOpen(okhttp3.WebSocket ws)
      Called when the WebSocket connection is open.
    • handleText

      protected abstract void handleText(okhttp3.WebSocket ws, String text)
      Called for each text frame received from the server.
    • handleBytes

      protected void handleBytes(okhttp3.WebSocket ws, okio.ByteString bytes)
      Called for each binary frame received from the server.

      Most streams use text frames only. The paper trading endpoint sends binary trade_updates frames; the default implementation decodes them as UTF-8 and delegates to handleText(okhttp3.WebSocket, java.lang.String).

    • handleClose

      protected abstract void handleClose(int code, String reason, boolean willReconnect)
      Called when the connection closes, either cleanly or due to an error.
      Parameters:
      code - WebSocket close code, or -1 for transport failures
      reason - human-readable close reason
    • connect

      public final void connect()
      Opens the WebSocket connection. Safe to call once; subsequent calls are ignored if the stream is already open or has been closed.
    • send

      protected final boolean send(String json)
      Sends a text frame on the current connection.
      Returns:
      true if the message was enqueued successfully
    • close

      public final void close()
      Closes the stream permanently. No reconnect will be attempted after this call. Idempotent — safe to call multiple times.
      Specified by:
      close in interface AutoCloseable
    • isClosed

      public final boolean isClosed()
      Returns true if close() has been called.
    • requireOpenForCommand

      protected final void requireOpenForCommand(String commandName)
      Throws if a user command attempts to mutate a terminal stream.
    • authenticationFuture

      public final CompletableFuture<Boolean> authenticationFuture()
      Returns a future that completes when the stream's first authentication attempt succeeds or fails. A clean close before authentication completes the future with false. Prefer authenticationResultFuture() when callers need the failure status or server error.
    • authenticationResultFuture

      public final CompletableFuture<AlpacaStreamAuthResult> authenticationResultFuture()
      Returns a future that completes with the stream's first authentication outcome.

      The future completes with server rejection details, terminal close reasons, or success. It is not completed by a caller-side timeout from waitForAuthenticationResult(Duration).

    • waitForAuthentication

      public final boolean waitForAuthentication(Duration timeout)
      Blocks until the stream authenticates, authentication fails, or the timeout elapses.
      Parameters:
      timeout - maximum time to wait
      Returns:
      true when authentication succeeded; false on timeout, failure, interruption, or close before authentication
    • waitForAuthenticationResult

      public final AlpacaStreamAuthResult waitForAuthenticationResult(Duration timeout)
      Blocks until the stream authenticates, authentication fails, or the timeout elapses.

      A timeout returns AlpacaStreamAuthResult.Status.TIMEOUT without completing authenticationResultFuture(), allowing other callers to continue waiting for the actual stream outcome.

      Parameters:
      timeout - maximum time to wait
      Returns:
      typed authentication outcome
    • completeAuthentication

      protected final void completeAuthentication(boolean authenticated)
      Marks the first authentication attempt as completed.
    • completeAuthentication

      protected final void completeAuthentication(AlpacaStreamAuthResult result)
      Marks the first authentication attempt as completed with diagnostic details.
    • closeTerminal

      protected final void closeTerminal(String reason)
      Closes the stream permanently after a terminal protocol failure such as failed auth.
    • closeTerminal

      protected final void closeTerminal(String reason, AlpacaStreamAuthResult result)
      Closes the stream permanently and completes authentication with the supplied terminal result.
    • invokeCallback

      protected final void invokeCallback(String callbackName, Runnable callback)
      Runs user-supplied listener code without allowing callback failures to interrupt protocol state transitions such as authentication, re-subscription, or reconnect.
    • resetReconnectAttempts

      protected final void resetReconnectAttempts()
      Resets the reconnect attempt counter after a successful connection.
    • isReconnecting

      protected final boolean isReconnecting()
      Returns true if the current connection is a reconnect (i.e. a previous connection was made and then lost). Check this before calling resetReconnectAttempts().
    • notifyReconnecting

      protected void notifyReconnecting(int attempt)
      Called just before a reconnect attempt is initiated.
      Parameters:
      attempt - 1-based attempt counter
    • notifyReconnected

      protected void notifyReconnected()
      Called after a reconnect attempt succeeds and the stream is fully re-authenticated (and re-subscribed, if applicable). Default implementation is a no-op.