Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Workspace crates

The workspace has two runtime crates, two hub crates, and one FFI crate.

PathCratePublishedContents
lib/veloveloyesThe runtime. All transports, discovery backends, streaming, the messenger, queues, rendezvous, and metrics are modules here.
lib/velo-extvelo-extyesThe trait surface for out-of-tree plugins, and the value types these traits use
lib/velo-hubvelo-hubnot yet; versions with the workspaceA hub: peer discovery for a velo application, plus hosted extensions. See The hub.
lib/velo-hub-extvelo-hub-extnot yet; versions with the workspaceThe wire protocol of the hub, on velo-ext alone. velo-hub re-exports it as velo_hub::protocol. For programs that speak the protocol without the velo runtime.
crates/ucx-rsucx-rsyes, versioned aloneRust bindings and a vendored static build of UCX, for the ucx feature
examplesvelo-examplesnoExamples. Not a workspace member.

Why only two crates

There used to be nine crates: velo-messenger, velo-transports, velo-streaming, and more. Each had its own version. A 0.1.1 patch of one crate changed its dependency on another internal crate from 0.1 to 0.2. Cargo took 0.1.1 as compatible with 0.1.0, so downstream lockfiles got two copies of the messenger types. The result was a flood of E0277 and E0308 errors in downstream builds.

The fix was structural. All runtime code moved into lib/velo/src/. Do not add a new crate under lib/.

ucx-rs is one exception. It is a leaf FFI crate. It exports no types that velo or velo-ext share, so it cannot cause two copies of a shared type. It must be on crates.io before a velo release with the ucx feature can ship.

velo-hub and velo-hub-ext are the other exceptions. They do share types with velo and with each other, so they take the workspace version and require velo and each other with a caret on that version. See Versioning. A separate trait crate for hub extensions was rejected: an extension gets a Velo and returns axum routes, so that crate would still depend on velo and axum, and it would be one more crate that can cause two copies of a type.

What goes in velo-ext

  • The traits: Transport, FrameTransport, PeerDiscovery, ServiceDiscovery, TransportObservability.
  • The types in their signatures: WorkerId, InstanceId, PeerInfo, WorkerAddress, TransportKey, MessageType, TransportError, SendOutcome, ShutdownState, Direction, and similar.
  • The channel types in their signatures: TransportAdapter, DataStreams, make_channels, AdmissionGate.

These stay out of velo-ext:

  • Concrete transports and discovery backends.
  • prometheus, tonic, axum, and other heavy dependencies.
  • The runtime types: Messenger, Velo, AnchorManager, RendezvousManager.

The test for the boundary: cargo tree -p velo-ext | grep -c prometheus must print 0.

Module map of velo

ModuleContents
velo::messengerActive messages, handlers, dispatch, distributed events
velo::eventsThe generational event system
velo::streamingAnchors, senders, frame transports, and the mux
velo::rendezvousLarge-payload staging and the RDMA GET path
velo::transportsTCP, UDS, QUIC, NATS, gRPC, ZMQ, UCX, and the shared ingress and writer code
velo::discoveryFilesystem, NATS, and etcd backends
velo::queueWork queues
velo::observabilityVeloMetrics and the Prometheus families
velo::simulationThe discrete-event simulation transport