InternalHttp

The internal port: the cluster channel and the wait signal entry of a node, served apart from its public port, over HTTP/1.1 and h2c. A node names its service on each request (Wow-Service); the port is reachable by the platform's own pods alone, a NetworkPolicy's boundary, not a token's.

Properties

Link copied to clipboard

Activates a node started on standby, at a migration's cut-over: the operator's act, audited.

Link copied to clipboard

How long a forward's stream stays open past its deadline for the owner's answer, and how long the router waits for that answer past it (HttpClusterChannel.answerGrace). The owner answers about the deadline, as it withdraws a command still queued at its wait's deadline: that answer, not executed, is the forward's outcome rather than an unknown one, so a caller waits at most this long past a forward's deadline. A request timing out resets its stream (RST_STREAM), and the internal port, as any Netty server, closes a connection on which it reads more than 200 resets in 30 seconds, failing every request on it: so a stream is not reset at the very deadline the owner answers at, only when the owner has not answered ANSWER_GRACE after it.

Link copied to clipboard

The default connect timeout of client: a peer that does not accept a connection by then is unreachable.

Link copied to clipboard
const val JSON: String
Link copied to clipboard
const val MAX_CONCURRENT_STREAMS: Int = 100

The streams the internal port takes on one HTTP/2 connection at a time, which it advertises (SETTINGS_MAX_CONCURRENT_STREAMS, Netty's default made explicit). The JDK client neither queues a request past a peer's limit nor opens another connection for it: it fails the request, unsent, with IOException: too many concurrent streams (JDK 21 and 25 alike). So the node's senders on one connection keep within it between them: its HttpSignalSender sends at most HttpSignalSender.DEFAULT_CONCURRENCY requests to a node at a time, and its HttpClusterChannel keeps the rest (HttpClusterChannel.DEFAULT_STREAMS), a forward past them waiting for a stream.

Link copied to clipboard

The default largest message of the internal port: the default in-memory limit of the WebFlux codecs. The host sets its internal server's limits (messageLimit) from the public port's, so a command the public port takes is taken when forwarded too; the server takes a body of up to that size on the request that upgrades a connection to h2c as well (the channel opens each connection with a HEAD). A forward larger than the internal port takes is refused (me.ahoo.wow.runtime.cluster.Refusal.TOO_LARGE), and its sender runs it.

Link copied to clipboard

What a forward carries besides its command's body: ids, the ref, headers, the wait and the trace.

Link copied to clipboard
const val SIGNALS_PATH: String

Takes a WaitSignal for a wait started on this node; answers 204.

Link copied to clipboard
const val STANDBY_PATH: String

Whether the node is on standby, and when and by whom it was activated.

Functions

Link copied to clipboard
fun client(connectTimeout: Duration = DEFAULT_CONNECT_TIMEOUT): HttpClient

A JDK HttpClient for the internal port: HTTP/2, which over cleartext it reaches by upgrading the first request of a connection from HTTP/1.1 (h2c), then multiplexes on that connection, at most MAX_CONCURRENT_STREAMS requests at a time. One client keeps one connection per peer, so a node shares it between its HttpClusterChannel and its HttpSignalSender.

Link copied to clipboard
fun messageLimit(publicLimit: Int): Int

The largest message the internal port takes when the public port's codecs take bodies of up to publicLimit bytes (a negative one: no limit): the body and a forward's MESSAGE_OVERHEAD, never less than MAX_UPGRADE_BODY.

Link copied to clipboard
fun uri(address: String, path: String): URI

The URI of path on the internal port at address (host:port).