Rust · Design

Design

1.0.0-rc.1 · 60202332

The crate is a thin layer over UCall’s native library, and every rule below follows from that.

  • Verbs share one name across languages. take_call, take_calls, take_batch, take_batches, submit and take_completed name the same calls in Python and Rust.
  • Blocking stays simple, deferring stays symmetric. A reply that is final on return looks as it did before files and streams existed, a deferred one is a Deferred that waits, .awaits or waits as it drops, and nothing costs more until a DetachedRequest is used.
  • Ownership is a type, not a flag. A reply consumes its Request, a dropped request answers 500, only a DetachedRequest hands back a Deferred, a Response frees itself, and a Client is neither Send nor Sync, so misuse does not compile.
  • Single owners are claimed, never assumed. Event loops and batch endpoints take &self, and an atomic claim answers Status::Contended to a second poller instead of racing it.
  • Handlers are plain closures. A panic inside a handler or an authorizer is caught at the boundary, answering 500 or rejecting the peer, and never unwinds through C.
  • Polling allocates nothing. A client sizes its tables by its call budget once, and a batch endpoint reuses the slots it lends requests in.
  • No life of its own. The crate starts no threads, keeps no global state and needs no async runtime, so it drops into any threading model.