kabel.remote/serve ends quietly when its peer's supervisor aborts instead
of reporting the abort as an error, returns :done next to :stop!, and
answers an invoke that reached the bus without a dialect in the kabel one.client-peer and server-peer accept an
optional :transport-middleware outside serialization, suitable for an
authenticated Noise upgrade without changing application middleware or
pub/sub. Every physical connection gets a unique mutable context containing
initiator/responder role, expected/observed remote address and negotiated
identity/capability slots; kabel.transport preserves it across legacy
middleware and exposes active connection lifecycle state on the peer.superv.async runtime used
by kabel.metrics macro expansions explicitly, removing undeclared-var
warnings in downstream optimized builds.WIRE.md freezes the uint32-big-endian
serializer envelope and CBOR profile. The kabel-protocol Python alpha
package implements bounded framing, serializer 14, keyword/set tags, and an
optional asyncio WebSocket adapter, with a shared JVM/Python known answer.kabel.remote). The request/response runtime that
is.simm.distributed-scope built its macros on now lives in kabel:
register!, serve with an :authorize gate in the kabel.authorize
shape, invoke, and a connection middleware that announces the peer. The
frames are specified in doc/remote-invocation.md; the distributed-scope
dialect is accepted and answered in kind, so peers upgrade one at a time.
Results are correlated per request rather than by scanning the bus, a call
in flight fails with :kabel.remote/disconnected when its connection
closes, :timeout-ms bounds a call, and errors travel typed instead of as
printed strings. Functions receive the principal under :kabel/principal
in their argument map instead of a dynamic binding.kabel.peer/maintain). A client peer stays connected with
exponential backoff, reporting :connecting, :connected, :disconnected,
:failed and :stopped on its bus as :kabel.peer/status and to an
:on-status callback. peer/status! publishes such a status for any
layer, peer/disconnect! closes the current connection, and peer/connect
now yields a channel that closes with the connection.kabel.auth.websocket). The client's :token
may be a function or an atom, read at every connection so a reconnection
carries the current token; refresh-token! replaces the token on the live
connection; a JWT with exp from such a source is refreshed automatically
before it expires. The validating side now watches the accepted token's
exp and, by default, closes a connection whose token expired without a
refresh (:on-expiry :close; :anonymous and :ignore are the
alternatives). Behaviour change: before, an accepted token was never
re-examined and a connection outlived its expiry indefinitely. kabel.auth.jwt/claims
decodes a token's payload without verifying it, for reading exp.AsyncSocket completions where available, with one
write in flight. Jetty provides that contract. Released http-kit 2.8.x does
not and retains an unbounded internal socket queue, so public deployments
must use Jetty or the byte-ceiling work in http-kit PR #619 until that lower
layer ships.kabel.metrics/messages counts logical
messages by direction and type; kabel.metrics/wire counts WebSocket
application bytes outside the codec; connection/reconnection/disconnection
and successful pub/sub subscription events share the same dependency-free
replikativ.metrics registry used by the rest of the stack. Labels exclude
peer ids, URLs, and topics so a deployment cannot accidentally create an
unbounded series set.kabel.ring-ws is written
against ring.websocket.protocols; callers inject run-server.
kabel.http-kit and the new kabel.jetty supply theirs and return the same
map, so switching adapters is one line. http-kit remains the default and
kabel's only declared server dependency; ring-jetty9-adapter is provided.with-channel,
deprecated in 2.4.0 as having "potential race conditions" (http-kit#318).
It hands back a live channel and then you attach on-receive, so a client
that sends immediately after the upgrade could have its first message arrive
before a handler existed. A Ring listener is supplied as part of the upgrade
response, so no such window exists.kabel.jetty for in-process TLS, HTTP/2, connection caps, idle
timeouts or metrics. It also negotiates permessage-deflate out of the box,
which http-kit does not yet (http-kit#617).org.replikativ.kabel.PerMessageDeflateExtension offers RFC 7692
permessage-deflate from kabel's Tyrus JVM client, tested against an
independent server implementation. That cross-implementation testing found a
real §7.2.3.6 bug — an empty fragment must be encoded 0x00, and getting it
wrong desynchronises the stream — present in both implementations.kabel.middleware.cbor, serialization id 14) backed by
boring. Unlike fressian it runs on
ClojureScript from the same implementation, and unlike every other option
here the bytes are an IETF standard that a non-Clojure peer can read with
its own library.kabel.middleware.dual for migrating a live fressian deployment in two
deploys rather than one flag day: read both formats first, switch writers
second.decoding-for now throws on an unknown serialization id instead of
returning nil. Every serialization middleware guards its in-branch on a
match, so a nil fell through all of them and the RAW payload map reached
application code as though it were a decoded value — silent corruption, and
exactly what a peer hits when it meets a codec added after it was built.- factor start stop
- support superv.async
- small bugfixes
- support node on client-side
- add an aleph http client (server still missing)
- add a generic callback middleware
- use lightweight slf4j logging
- expose consistent host ip
- do not initialize http-client on compile time
fixes aot uberjar compilation
- properly close cljs client connection on initial error
- add :sender peer-id to outgoing messages
- add :connection url to incoming messages
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |