Session A (primary edge node) READY
ready: resolved · draining: pending · closed: pending
Active streams: 0 · Completed: 0
v157 · webtransport draining
Probe the real WebTransport.prototype.draining getter in your browser, then drive a zero-downtime session migration: when Session A receives an HTTP/3 DRAIN_WEBTRANSPORT_SESSION (0x78ae) capsule, its draining Promise resolves, replacement Session B opens immediately for new bidirectional streams, and in-flight streams on Session A finish without dropping a byte.
WebTransport.prototype.draining IDL probeContract tested: Checks whether WebTransport exists, whether 'draining' in WebTransport.prototype is present, and whether Object.getOwnPropertyDescriptor(WebTransport.prototype, 'draining')?.get is a getter function alongside ready and closed.
Spawn bidirectional streams, then trigger DRAIN_WEBTRANSPORT_SESSION (0x78ae) on Session A. Existing streams remain open on Session A until they complete, while newly created streams automatically route to replacement Session B.
ready: resolved · draining: pending · closed: pending
Active streams: 0 · Completed: 0
ready: not opened · draining: not opened · closed: not opened
Active streams: 0 · Completed: 0
| Stream ID | Routed Session | State | Progress |
|---|---|---|---|
| No streams opened yet. Click "Open bidirectional stream" to start traffic. | |||
class DrainingAwareTransportPool {
constructor(url) {
this.url = url;
this.current = this.#connect();
}
#connect() {
const wt = new WebTransport(this.url);
if ("draining" in wt) {
wt.draining.then(() => {
// Server sent HTTP/3 DRAIN_WEBTRANSPORT_SESSION (0x78ae).
// Immediately warm up a replacement session for new streams:
const oldSession = wt;
this.current = this.#connect();
// Existing streams on oldSession continue until they finish.
});
}
return wt;
}
async openBidiStream() {
await this.current.ready;
return this.current.createBidirectionalStream();
}
}