detached 9c7eb05

feat(brokeripc): credit flow control on broker logical streams

Each broker logical stream now has a 4 MiB credit window per direction.
A sender reserves StreamChunkCredit per data frame and waits for
StreamWindowUpdate grants instead of the receiver failing the stream when
its queue fills. Bumps protocol.Version to 66 for the new broker message.
commit
9c7eb052961e0efec6de5b7a2df87f521134f3dc
author
brice · · 2026-10-08 14:24 UTC
committer
brice · · 2026-10-08 15:05 UTC
parent
e3ca8e1
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
20 files · +770 -366
M docs/protocol.md +18 -3
@@ -109,8 +109,8 @@ Timeout or reply loss after dispatch is outcome unknown and is never replayed.
109109 ## Broker negotiation
110110
111111 Broker connections are a separate conversation from the session protocol.
112-`internal/adapters/brokerwire` owns it: client tags 101-111 and server tags
113-201-209 are disjoint from every session tag, and each direction is its own
112+`internal/adapters/brokerwire` owns it: client tags 101-114 and server tags
113+201-211 are disjoint from every session tag, and each direction is its own
114114 closed directional `oneof` union. A broker connection opens with exactly one
115115 broker preamble (`PreambleRequest` client → server, `PreambleResponse` server
116116 → client) using broker roles 3/4. The preamble carries the same magic
@@ -127,7 +127,14 @@ connection dispatcher.
127127
128128 `internal/adapters/brokeripc` carries this conversation over `broker.sock`
129129 in the per-user runtime directory, with same-user peer-credential admission
130-and bounded per-connection queues. The remote helpers `_broker-mux-stdio`,
130+and bounded per-connection queues. Each logical stream is credit flow
131+controlled in both directions: a sender spends `StreamChunkCredit` (payload
132+plus 64 bytes) per data frame out of a 4 MiB window
133+(`brokerwire.StreamWindowBytes`) and waits when it has too little, and the
134+receiver returns the credit of frames its consumer has read in
135+`StreamWindowUpdate` batches. A slow consumer therefore slows its own stream
136+instead of losing it; data or credit beyond the window is a flow-control
137+violation that settles only that stream. The remote helpers `_broker-mux-stdio`,
131138 `_broker-mux-quic-bootstrap`, and `_broker-mux-quic-proxy` bridge a remote
132139 daemonmux socket to stdio or to one freshly authenticated QUIC stream.
133140
@@ -162,6 +169,12 @@ base. `ValidateOutput` enforces the epoch/base/new chain
162169 claims its carriage's preferred window, or `MaxOutputWindow` when the
163170 carriage states none, so output pipelines instead of waiting a round trip
164171 per frame.
172+- Unacknowledged Output data is also bounded by `MaxOutputWindowBytes`
173+ (2 MiB). State frames are charged to their own state, side effects to the
174+ next state, and a cumulative ACK releases what it covers. The next state
175+ frame waits when either window is full, except that a frame may always be
176+ sent while no state frame is in flight. Images share the remaining byte
177+ budget and wait for a later frame when it is too small.
165178 - The client coalesces ACKs (`client.go:cumulativeAckQueue`) and keeps
166179 applying + acknowledging daemon frames even while a picker lease owns
167180 the terminal (see below) — admission without physical write.
@@ -247,6 +260,8 @@ than `KillResult` and `CommandResult`.
247260 | Queued envelopes per connection | 8 messages, 32 MiB bytes (`streamframe` defaults), then backpressure; sync sends uncharged, async charged once | `adapters/streamframe` |
248261 | Encoding buffer | bounded per-connection framing buffers owned by `streamframe` | `adapters/streamframe` |
249262 | Output states in flight | 8 (`MaxOutputWindow`) preferred for QUIC/IPC/SSH | daemon, negotiated down |
263+| Unacknowledged Output bytes | 2 MiB (`MaxOutputWindowBytes`); one frame always allowed when none is in flight | daemon |
264+| Broker stream window | 4 MiB per stream and direction (`brokerwire.StreamWindowBytes`), returned by `StreamWindowUpdate` | `adapters/brokeripc` |
250265 | QUIC unauthenticated peers | 4 connections, 3 s auth deadline, one bidirectional stream each; extra/unidirectional streams rejected | `adapters/quic` |
251266 | QUIC bootstrap | 32-byte token + 16-byte nonce (base64), ≤4 KiB readiness (schema v1, host-independent port, SHA-256 pin, ≤15 s expiry), one bounded (512 B) auth record, atomic one-time consumption, token erasure on close | `adapters/quic` bootstrap, `app/_broker-mux-quic-bootstrap` + `_broker-mux-quic-proxy` |
252267 | Handshake, dial → first committed publication | 15 s, single absolute deadline propagated unchanged, never reset | both ends |
@@ -109,8 +109,8 @@ Timeout or reply loss after dispatch is outcome unknown and is never replayed.
109 ## Broker negotiation109 ## Broker negotiation
110 110
111 Broker connections are a separate conversation from the session protocol.111 Broker connections are a separate conversation from the session protocol.
112-`internal/adapters/brokerwire` owns it: client tags 101-111 and server tags112+`internal/adapters/brokerwire` owns it: client tags 101-114 and server tags
113-201-209 are disjoint from every session tag, and each direction is its own113+201-211 are disjoint from every session tag, and each direction is its own
114 closed directional `oneof` union. A broker connection opens with exactly one114 closed directional `oneof` union. A broker connection opens with exactly one
115 broker preamble (`PreambleRequest` client → server, `PreambleResponse` server115 broker preamble (`PreambleRequest` client → server, `PreambleResponse` server
116 → client) using broker roles 3/4. The preamble carries the same magic116 → client) using broker roles 3/4. The preamble carries the same magic
@@ -127,7 +127,14 @@ connection dispatcher.
127 127
128 `internal/adapters/brokeripc` carries this conversation over `broker.sock`128 `internal/adapters/brokeripc` carries this conversation over `broker.sock`
129 in the per-user runtime directory, with same-user peer-credential admission129 in the per-user runtime directory, with same-user peer-credential admission
130-and bounded per-connection queues. The remote helpers `_broker-mux-stdio`,130+and bounded per-connection queues. Each logical stream is credit flow
131+controlled in both directions: a sender spends `StreamChunkCredit` (payload
132+plus 64 bytes) per data frame out of a 4 MiB window
133+(`brokerwire.StreamWindowBytes`) and waits when it has too little, and the
134+receiver returns the credit of frames its consumer has read in
135+`StreamWindowUpdate` batches. A slow consumer therefore slows its own stream
136+instead of losing it; data or credit beyond the window is a flow-control
137+violation that settles only that stream. The remote helpers `_broker-mux-stdio`,
131 `_broker-mux-quic-bootstrap`, and `_broker-mux-quic-proxy` bridge a remote138 `_broker-mux-quic-bootstrap`, and `_broker-mux-quic-proxy` bridge a remote
132 daemonmux socket to stdio or to one freshly authenticated QUIC stream.139 daemonmux socket to stdio or to one freshly authenticated QUIC stream.
133 140
@@ -162,6 +169,12 @@ base. `ValidateOutput` enforces the epoch/base/new chain
162 claims its carriage's preferred window, or `MaxOutputWindow` when the169 claims its carriage's preferred window, or `MaxOutputWindow` when the
163 carriage states none, so output pipelines instead of waiting a round trip170 carriage states none, so output pipelines instead of waiting a round trip
164 per frame.171 per frame.
172+- Unacknowledged Output data is also bounded by `MaxOutputWindowBytes`
173+ (2 MiB). State frames are charged to their own state, side effects to the
174+ next state, and a cumulative ACK releases what it covers. The next state
175+ frame waits when either window is full, except that a frame may always be
176+ sent while no state frame is in flight. Images share the remaining byte
177+ budget and wait for a later frame when it is too small.
165 - The client coalesces ACKs (`client.go:cumulativeAckQueue`) and keeps178 - The client coalesces ACKs (`client.go:cumulativeAckQueue`) and keeps
166 applying + acknowledging daemon frames even while a picker lease owns179 applying + acknowledging daemon frames even while a picker lease owns
167 the terminal (see below) — admission without physical write.180 the terminal (see below) — admission without physical write.
@@ -247,6 +260,8 @@ than `KillResult` and `CommandResult`.
247 | Queued envelopes per connection | 8 messages, 32 MiB bytes (`streamframe` defaults), then backpressure; sync sends uncharged, async charged once | `adapters/streamframe` |260 | Queued envelopes per connection | 8 messages, 32 MiB bytes (`streamframe` defaults), then backpressure; sync sends uncharged, async charged once | `adapters/streamframe` |
248 | Encoding buffer | bounded per-connection framing buffers owned by `streamframe` | `adapters/streamframe` |261 | Encoding buffer | bounded per-connection framing buffers owned by `streamframe` | `adapters/streamframe` |
249 | Output states in flight | 8 (`MaxOutputWindow`) preferred for QUIC/IPC/SSH | daemon, negotiated down |262 | Output states in flight | 8 (`MaxOutputWindow`) preferred for QUIC/IPC/SSH | daemon, negotiated down |
263+| Unacknowledged Output bytes | 2 MiB (`MaxOutputWindowBytes`); one frame always allowed when none is in flight | daemon |
264+| Broker stream window | 4 MiB per stream and direction (`brokerwire.StreamWindowBytes`), returned by `StreamWindowUpdate` | `adapters/brokeripc` |
250 | QUIC unauthenticated peers | 4 connections, 3 s auth deadline, one bidirectional stream each; extra/unidirectional streams rejected | `adapters/quic` |265 | QUIC unauthenticated peers | 4 connections, 3 s auth deadline, one bidirectional stream each; extra/unidirectional streams rejected | `adapters/quic` |
251 | QUIC bootstrap | 32-byte token + 16-byte nonce (base64), ≤4 KiB readiness (schema v1, host-independent port, SHA-256 pin, ≤15 s expiry), one bounded (512 B) auth record, atomic one-time consumption, token erasure on close | `adapters/quic` bootstrap, `app/_broker-mux-quic-bootstrap` + `_broker-mux-quic-proxy` |266 | QUIC bootstrap | 32-byte token + 16-byte nonce (base64), ≤4 KiB readiness (schema v1, host-independent port, SHA-256 pin, ≤15 s expiry), one bounded (512 B) auth record, atomic one-time consumption, token erasure on close | `adapters/quic` bootstrap, `app/_broker-mux-quic-bootstrap` + `_broker-mux-quic-proxy` |
252 | Handshake, dial → first committed publication | 15 s, single absolute deadline propagated unchanged, never reset | both ends |267 | Handshake, dial → first committed publication | 15 s, single absolute deadline propagated unchanged, never reset | both ends |
M internal/adapters/brokeripc/client.go +18 -3
@@ -364,9 +364,24 @@ func (c *client) dispatch(message brokerwire.ServerMessage) error {
364364 // lookup; its data is discarded, exactly like a retired stream.
365365 return nil
366366 }
367- if err := st.deliver(m.Data); err != nil {
368- if errors.Is(err, ErrStreamBackpressure) {
369- st.fail(ErrStreamBackpressure)
367+ if err := st.deliver(m.Data); errors.Is(err, ErrStreamCredit) {
368+ st.fail(ErrStreamCredit)
369+ }
370+ return nil
371+ case brokerwire.StreamWindowUpdate:
372+ if !c.scopeMatches(m.Epoch, m.Connection) {
373+ return errors.Join(ErrScopeMismatch, ErrProtocol)
374+ }
375+ disposition, err := c.conn.StreamWindowUpdate(m.Stream)
376+ if err != nil {
377+ return errors.Join(ErrProtocol, err)
378+ }
379+ if disposition == brokerwire.StreamDiscarded {
380+ return nil
381+ }
382+ if st := c.lookupStream(m.Stream); st != nil {
383+ if err := st.pipe.granted(m.Credit); err != nil {
384+ st.fail(err)
370385 }
371386 }
372387 return nil
@@ -364,9 +364,24 @@ func (c *client) dispatch(message brokerwire.ServerMessage) error {
364 // lookup; its data is discarded, exactly like a retired stream.364 // lookup; its data is discarded, exactly like a retired stream.
365 return nil365 return nil
366 }366 }
367- if err := st.deliver(m.Data); err != nil {367+ if err := st.deliver(m.Data); errors.Is(err, ErrStreamCredit) {
368- if errors.Is(err, ErrStreamBackpressure) {368+ st.fail(ErrStreamCredit)
369- st.fail(ErrStreamBackpressure)369+ }
370+ return nil
371+ case brokerwire.StreamWindowUpdate:
372+ if !c.scopeMatches(m.Epoch, m.Connection) {
373+ return errors.Join(ErrScopeMismatch, ErrProtocol)
374+ }
375+ disposition, err := c.conn.StreamWindowUpdate(m.Stream)
376+ if err != nil {
377+ return errors.Join(ErrProtocol, err)
378+ }
379+ if disposition == brokerwire.StreamDiscarded {
380+ return nil
381+ }
382+ if st := c.lookupStream(m.Stream); st != nil {
383+ if err := st.pipe.granted(m.Credit); err != nil {
384+ st.fail(err)
370 }385 }
371 }386 }
372 return nil387 return nil
M internal/adapters/brokeripc/config.go +1 -23
@@ -15,13 +15,6 @@ const (
1515 // listener. A listener acquires one slot before accepting, so the bound is
1616 // enforced before a socket is admitted rather than after.
1717 DefaultMaxClients = 64
18- // DefaultStreamInboundChunks bounds one logical stream's inbound chunk
19- // queue: frames already accepted from the wire and not yet consumed by the
20- // local session carriage.
21- DefaultStreamInboundChunks = 64
22- // DefaultStreamInboundBytes bounds one logical stream's inbound chunk queue
23- // in bytes (4 MiB).
24- DefaultStreamInboundBytes = 4 << 20
2518 )
2619
2720 // Config bounds one endpoint. The zero value is valid and selects every
@@ -29,10 +22,6 @@ const (
2922 type Config struct {
3023 // MaxClients bounds concurrent accepted client connections.
3124 MaxClients int
32- // StreamInboundChunks bounds one logical stream's inbound chunk queue.
33- StreamInboundChunks int
34- // StreamInboundBytes bounds one logical stream's inbound chunk bytes.
35- StreamInboundBytes uint64
3625 // HandshakeTimeout bounds one accepted connection's broker preamble, broker
3726 // admission, and the wait for its Register. The client dialer also bounds
3827 // its whole setup (Unix dial, preamble, Register send, and wait for
@@ -62,12 +51,6 @@ func (c Config) withDefaults() Config {
6251 if c.MaxClients <= 0 {
6352 c.MaxClients = DefaultMaxClients
6453 }
65- if c.StreamInboundChunks <= 0 {
66- c.StreamInboundChunks = DefaultStreamInboundChunks
67- }
68- if c.StreamInboundBytes == 0 {
69- c.StreamInboundBytes = DefaultStreamInboundBytes
70- }
7154 if c.HandshakeTimeout <= 0 {
7255 c.HandshakeTimeout = protocol.HandshakeTimeout
7356 }
@@ -80,16 +63,11 @@ func (c Config) withDefaults() Config {
8063 // validate refuses a configuration whose explicit bounds cannot be honored.
8164 // The zero value is always valid because withDefaults has already been applied.
8265 func (c Config) validate() error {
83- if c.MaxClients <= 0 || c.StreamInboundChunks <= 0 || c.StreamInboundBytes == 0 || c.HandshakeTimeout <= 0 {
66+ if c.MaxClients <= 0 || c.HandshakeTimeout <= 0 {
8467 return ErrConfig
8568 }
8669 if c.MaxPendingOperations <= 0 || c.MaxPendingOperations > brokerwire.MaxPendingOperations {
8770 return ErrConfig
8871 }
89- // A stream inbound byte bound below one maximum chunk can never accept a
90- // full stream frame, which would starve a legal peer.
91- if c.StreamInboundBytes < brokerwire.MaxStreamChunkBytes {
92- return ErrConfig
93- }
9472 return nil
9573 }
@@ -15,13 +15,6 @@ const (
15 // listener. A listener acquires one slot before accepting, so the bound is15 // listener. A listener acquires one slot before accepting, so the bound is
16 // enforced before a socket is admitted rather than after.16 // enforced before a socket is admitted rather than after.
17 DefaultMaxClients = 6417 DefaultMaxClients = 64
18- // DefaultStreamInboundChunks bounds one logical stream's inbound chunk
19- // queue: frames already accepted from the wire and not yet consumed by the
20- // local session carriage.
21- DefaultStreamInboundChunks = 64
22- // DefaultStreamInboundBytes bounds one logical stream's inbound chunk queue
23- // in bytes (4 MiB).
24- DefaultStreamInboundBytes = 4 << 20
25 )18 )
26 19
27 // Config bounds one endpoint. The zero value is valid and selects every20 // Config bounds one endpoint. The zero value is valid and selects every
@@ -29,10 +22,6 @@ const (
29 type Config struct {22 type Config struct {
30 // MaxClients bounds concurrent accepted client connections.23 // MaxClients bounds concurrent accepted client connections.
31 MaxClients int24 MaxClients int
32- // StreamInboundChunks bounds one logical stream's inbound chunk queue.
33- StreamInboundChunks int
34- // StreamInboundBytes bounds one logical stream's inbound chunk bytes.
35- StreamInboundBytes uint64
36 // HandshakeTimeout bounds one accepted connection's broker preamble, broker25 // HandshakeTimeout bounds one accepted connection's broker preamble, broker
37 // admission, and the wait for its Register. The client dialer also bounds26 // admission, and the wait for its Register. The client dialer also bounds
38 // its whole setup (Unix dial, preamble, Register send, and wait for27 // its whole setup (Unix dial, preamble, Register send, and wait for
@@ -62,12 +51,6 @@ func (c Config) withDefaults() Config {
62 if c.MaxClients <= 0 {51 if c.MaxClients <= 0 {
63 c.MaxClients = DefaultMaxClients52 c.MaxClients = DefaultMaxClients
64 }53 }
65- if c.StreamInboundChunks <= 0 {
66- c.StreamInboundChunks = DefaultStreamInboundChunks
67- }
68- if c.StreamInboundBytes == 0 {
69- c.StreamInboundBytes = DefaultStreamInboundBytes
70- }
71 if c.HandshakeTimeout <= 0 {54 if c.HandshakeTimeout <= 0 {
72 c.HandshakeTimeout = protocol.HandshakeTimeout55 c.HandshakeTimeout = protocol.HandshakeTimeout
73 }56 }
@@ -80,16 +63,11 @@ func (c Config) withDefaults() Config {
80 // validate refuses a configuration whose explicit bounds cannot be honored.63 // validate refuses a configuration whose explicit bounds cannot be honored.
81 // The zero value is always valid because withDefaults has already been applied.64 // The zero value is always valid because withDefaults has already been applied.
82 func (c Config) validate() error {65 func (c Config) validate() error {
83- if c.MaxClients <= 0 || c.StreamInboundChunks <= 0 || c.StreamInboundBytes == 0 || c.HandshakeTimeout <= 0 {66+ if c.MaxClients <= 0 || c.HandshakeTimeout <= 0 {
84 return ErrConfig67 return ErrConfig
85 }68 }
86 if c.MaxPendingOperations <= 0 || c.MaxPendingOperations > brokerwire.MaxPendingOperations {69 if c.MaxPendingOperations <= 0 || c.MaxPendingOperations > brokerwire.MaxPendingOperations {
87 return ErrConfig70 return ErrConfig
88 }71 }
89- // A stream inbound byte bound below one maximum chunk can never accept a
90- // full stream frame, which would starve a legal peer.
91- if c.StreamInboundBytes < brokerwire.MaxStreamChunkBytes {
92- return ErrConfig
93- }
94 return nil72 return nil
95 }73 }
M internal/adapters/brokeripc/errors.go +4 -4
@@ -33,10 +33,10 @@ var (
3333 // ordering: a duplicate Register, a frame for an unallocated stream, or
3434 // stream data before the stream was established.
3535 ErrProtocol = errors.New("brokeripc: broker protocol violation")
36- // ErrStreamBackpressure reports a logical stream whose local consumer is
37- // not draining its bounded inbound queue. The affected stream is settled
38- // alone; the connection and every sibling stream stay up.
39- ErrStreamBackpressure = errors.New("brokeripc: stream consumer is not keeping up")
36+ // ErrStreamCredit reports a peer that sent stream data beyond the credit it
37+ // was granted, or granted credit beyond one stream window. The affected
38+ // stream is settled alone; the connection and every sibling stream stay up.
39+ ErrStreamCredit = errors.New("brokeripc: stream flow-control violation")
4040 // ErrStreamGone reports a stream the peer retired while this side was still
4141 // starting or using it.
4242 ErrStreamGone = errors.New("brokeripc: logical stream is gone")
@@ -33,10 +33,10 @@ var (
33 // ordering: a duplicate Register, a frame for an unallocated stream, or33 // ordering: a duplicate Register, a frame for an unallocated stream, or
34 // stream data before the stream was established.34 // stream data before the stream was established.
35 ErrProtocol = errors.New("brokeripc: broker protocol violation")35 ErrProtocol = errors.New("brokeripc: broker protocol violation")
36- // ErrStreamBackpressure reports a logical stream whose local consumer is36+ // ErrStreamCredit reports a peer that sent stream data beyond the credit it
37- // not draining its bounded inbound queue. The affected stream is settled37+ // was granted, or granted credit beyond one stream window. The affected
38- // alone; the connection and every sibling stream stay up.38+ // stream is settled alone; the connection and every sibling stream stay up.
39- ErrStreamBackpressure = errors.New("brokeripc: stream consumer is not keeping up")39+ ErrStreamCredit = errors.New("brokeripc: stream flow-control violation")
40 // ErrStreamGone reports a stream the peer retired while this side was still40 // ErrStreamGone reports a stream the peer retired while this side was still
41 // starting or using it.41 // starting or using it.
42 ErrStreamGone = errors.New("brokeripc: logical stream is gone")42 ErrStreamGone = errors.New("brokeripc: logical stream is gone")
M internal/adapters/brokeripc/limits_test.go +12 -44
@@ -147,71 +147,39 @@ func TestConfigDefaultsAndValidation(t *testing.T) {
147147 cfg := Config{}.withDefaults()
148148 require.NoError(t, cfg.validate())
149149 require.Equal(t, DefaultMaxClients, cfg.MaxClients)
150- require.Equal(t, DefaultStreamInboundChunks, cfg.StreamInboundChunks)
151- require.Equal(t, uint64(DefaultStreamInboundBytes), cfg.StreamInboundBytes)
152150 require.Equal(t, brokerwire.MaxPendingOperations, cfg.MaxPendingOperations)
153151
154- require.ErrorIs(t, (Config{StreamInboundBytes: 1}).withDefaults().validate(), ErrConfig)
155152 require.ErrorIs(t, (Config{MaxPendingOperations: brokerwire.MaxPendingOperations + 1}).withDefaults().validate(), ErrConfig)
156153 // A negative explicit bound is replaced by its default rather than refused.
157- require.NoError(t, (Config{MaxClients: -1, StreamInboundChunks: -1}).withDefaults().validate())
154+ require.NoError(t, (Config{MaxClients: -1}).withDefaults().validate())
158155 }
159156
160-// TestStreamPipeBoundsAndClose proves the per-stream byte channel is bounded,
161-// reports backpressure instead of growing, and releases a parked reader on
162-// close.
163-func TestStreamPipeBoundsAndClose(t *testing.T) {
164- pipe := newStreamPipe(2, 4096, func([]byte) error { return nil })
165- require.NoError(t, pipe.deliver([]byte("one")))
166- require.NoError(t, pipe.deliver([]byte("two")))
167- require.ErrorIs(t, pipe.deliver([]byte("three")), ErrStreamBackpressure)
168-
169- buf := make([]byte, 3)
170- n, err := pipe.Read(buf)
171- require.NoError(t, err)
172- require.Equal(t, "one", string(buf[:n]))
173- require.NoError(t, pipe.deliver([]byte("three")))
174-
175- // An orderly Close keeps what is already queued ("two" and "three"): Read
176- // drains it before observing io.EOF, so a chunk delivered just ahead of an
177- // orderly close is never discarded underneath its reader (see
178- // TestStreamPipeCloseWithPreservesQueuedDataOnOrderlyClose for the focused
179- // coverage of this behavior).
180- require.NoError(t, pipe.Close())
181- require.ErrorIs(t, pipe.deliver([]byte("four")), ErrStreamGone)
182- drained := make([]byte, 8)
183- n, err = pipe.Read(drained)
184- require.NoError(t, err)
185- require.Equal(t, "two", string(drained[:n]))
186- n, err = pipe.Read(drained)
187- require.NoError(t, err)
188- require.Equal(t, "three", string(drained[:n]))
189- _, err = pipe.Read(drained)
190- require.ErrorIs(t, err, io.EOF)
191-
192- // A reader parked on an empty pipe is released by closeWith with its cause.
193- parked := newStreamPipe(1, 4096, func([]byte) error { return nil })
157+// TestStreamPipeCloseReleasesParkedReader proves a reader parked on an empty
158+// pipe is released by closeWith with its cause.
159+func TestStreamPipeCloseReleasesParkedReader(t *testing.T) {
160+ parked := newTestPipe()
194161 done := make(chan error, 1)
195162 go func() {
196- _, err := parked.Read(buf)
163+ _, err := parked.Read(make([]byte, 3))
197164 done <- err
198165 }()
199- time.Sleep(20 * time.Millisecond)
200- parked.closeWith(ErrStreamBackpressure)
166+ parked.closeWith(ErrStreamCredit)
201167 select {
202168 case err := <-done:
203- require.ErrorIs(t, err, ErrStreamBackpressure)
169+ require.ErrorIs(t, err, ErrStreamCredit)
204170 case <-time.After(5 * time.Second):
205171 t.Fatal("closeWith must release a parked reader")
206172 }
173+ require.ErrorIs(t, parked.deliver([]byte("late")), ErrStreamGone)
207174 }
208175
209176 // TestStreamPipeOutboundError proves a failing outbound hook surfaces instead of
210177 // silently dropping bytes.
211178 func TestStreamPipeOutboundError(t *testing.T) {
212- pipe := newStreamPipe(1, 4096, func([]byte) error { return ErrStreamBackpressure })
179+ failure := errors.New("outbound failed")
180+ pipe := newStreamPipe(func([]byte) error { return failure }, func(uint64) error { return nil })
213181 _, err := pipe.Write([]byte("payload"))
214- require.ErrorIs(t, err, ErrStreamBackpressure)
182+ require.ErrorIs(t, err, failure)
215183 require.NoError(t, pipe.Close())
216184 _, err = pipe.Write([]byte("payload"))
217185 require.ErrorIs(t, err, ErrStreamGone)
@@ -147,71 +147,39 @@ func TestConfigDefaultsAndValidation(t *testing.T) {
147 cfg := Config{}.withDefaults()147 cfg := Config{}.withDefaults()
148 require.NoError(t, cfg.validate())148 require.NoError(t, cfg.validate())
149 require.Equal(t, DefaultMaxClients, cfg.MaxClients)149 require.Equal(t, DefaultMaxClients, cfg.MaxClients)
150- require.Equal(t, DefaultStreamInboundChunks, cfg.StreamInboundChunks)
151- require.Equal(t, uint64(DefaultStreamInboundBytes), cfg.StreamInboundBytes)
152 require.Equal(t, brokerwire.MaxPendingOperations, cfg.MaxPendingOperations)150 require.Equal(t, brokerwire.MaxPendingOperations, cfg.MaxPendingOperations)
153 151
154- require.ErrorIs(t, (Config{StreamInboundBytes: 1}).withDefaults().validate(), ErrConfig)
155 require.ErrorIs(t, (Config{MaxPendingOperations: brokerwire.MaxPendingOperations + 1}).withDefaults().validate(), ErrConfig)152 require.ErrorIs(t, (Config{MaxPendingOperations: brokerwire.MaxPendingOperations + 1}).withDefaults().validate(), ErrConfig)
156 // A negative explicit bound is replaced by its default rather than refused.153 // A negative explicit bound is replaced by its default rather than refused.
157- require.NoError(t, (Config{MaxClients: -1, StreamInboundChunks: -1}).withDefaults().validate())154+ require.NoError(t, (Config{MaxClients: -1}).withDefaults().validate())
158 }155 }
159 156
160-// TestStreamPipeBoundsAndClose proves the per-stream byte channel is bounded,157+// TestStreamPipeCloseReleasesParkedReader proves a reader parked on an empty
161-// reports backpressure instead of growing, and releases a parked reader on158+// pipe is released by closeWith with its cause.
162-// close.159+func TestStreamPipeCloseReleasesParkedReader(t *testing.T) {
163-func TestStreamPipeBoundsAndClose(t *testing.T) {160+ parked := newTestPipe()
164- pipe := newStreamPipe(2, 4096, func([]byte) error { return nil })
165- require.NoError(t, pipe.deliver([]byte("one")))
166- require.NoError(t, pipe.deliver([]byte("two")))
167- require.ErrorIs(t, pipe.deliver([]byte("three")), ErrStreamBackpressure)
168-
169- buf := make([]byte, 3)
170- n, err := pipe.Read(buf)
171- require.NoError(t, err)
172- require.Equal(t, "one", string(buf[:n]))
173- require.NoError(t, pipe.deliver([]byte("three")))
174-
175- // An orderly Close keeps what is already queued ("two" and "three"): Read
176- // drains it before observing io.EOF, so a chunk delivered just ahead of an
177- // orderly close is never discarded underneath its reader (see
178- // TestStreamPipeCloseWithPreservesQueuedDataOnOrderlyClose for the focused
179- // coverage of this behavior).
180- require.NoError(t, pipe.Close())
181- require.ErrorIs(t, pipe.deliver([]byte("four")), ErrStreamGone)
182- drained := make([]byte, 8)
183- n, err = pipe.Read(drained)
184- require.NoError(t, err)
185- require.Equal(t, "two", string(drained[:n]))
186- n, err = pipe.Read(drained)
187- require.NoError(t, err)
188- require.Equal(t, "three", string(drained[:n]))
189- _, err = pipe.Read(drained)
190- require.ErrorIs(t, err, io.EOF)
191-
192- // A reader parked on an empty pipe is released by closeWith with its cause.
193- parked := newStreamPipe(1, 4096, func([]byte) error { return nil })
194 done := make(chan error, 1)161 done := make(chan error, 1)
195 go func() {162 go func() {
196- _, err := parked.Read(buf)163+ _, err := parked.Read(make([]byte, 3))
197 done <- err164 done <- err
198 }()165 }()
199- time.Sleep(20 * time.Millisecond)166+ parked.closeWith(ErrStreamCredit)
200- parked.closeWith(ErrStreamBackpressure)
201 select {167 select {
202 case err := <-done:168 case err := <-done:
203- require.ErrorIs(t, err, ErrStreamBackpressure)169+ require.ErrorIs(t, err, ErrStreamCredit)
204 case <-time.After(5 * time.Second):170 case <-time.After(5 * time.Second):
205 t.Fatal("closeWith must release a parked reader")171 t.Fatal("closeWith must release a parked reader")
206 }172 }
173+ require.ErrorIs(t, parked.deliver([]byte("late")), ErrStreamGone)
207 }174 }
208 175
209 // TestStreamPipeOutboundError proves a failing outbound hook surfaces instead of176 // TestStreamPipeOutboundError proves a failing outbound hook surfaces instead of
210 // silently dropping bytes.177 // silently dropping bytes.
211 func TestStreamPipeOutboundError(t *testing.T) {178 func TestStreamPipeOutboundError(t *testing.T) {
212- pipe := newStreamPipe(1, 4096, func([]byte) error { return ErrStreamBackpressure })179+ failure := errors.New("outbound failed")
180+ pipe := newStreamPipe(func([]byte) error { return failure }, func(uint64) error { return nil })
213 _, err := pipe.Write([]byte("payload"))181 _, err := pipe.Write([]byte("payload"))
214- require.ErrorIs(t, err, ErrStreamBackpressure)182+ require.ErrorIs(t, err, failure)
215 require.NoError(t, pipe.Close())183 require.NoError(t, pipe.Close())
216 _, err = pipe.Write([]byte("payload"))184 _, err = pipe.Write([]byte("payload"))
217 require.ErrorIs(t, err, ErrStreamGone)185 require.ErrorIs(t, err, ErrStreamGone)
M internal/adapters/brokeripc/pipe.go +131 -50
@@ -3,53 +3,80 @@ package brokeripc
33 import (
44 "io"
55 "sync"
6+
7+ "github.com/bnema/vev/internal/adapters/brokerwire"
68 )
79
8-// streamPipe is the private ordered, bounded byte channel between one broker
9-// wire session and the sessionwire framing of one logical stream.
10+// streamPipe is the private ordered, credit-controlled byte channel between one
11+// broker wire session and the sessionwire framing of one logical stream.
1012 //
11-// The wire reader never blocks on a slow consumer: a chunk the peer sent is
12-// appended to a bounded queue and refused with ErrStreamBackpressure once the
13-// bound is reached, so only that stream is settled and every sibling and the
14-// physical connection stay untouched. The consumer never blocks the writer:
15-// Read serves already-queued chunks or parks on the wake channel, and Close
16-// releases both ends promptly. Write hands each byte slice to the injected
17-// outbound hook, which owns chunking it under the negotiated stream chunk
18-// ceiling and enqueueing the frames on the connection.
13+// Each direction of a stream has a brokerwire.StreamWindowBytes credit window.
14+// The sender spends brokerwire.StreamChunkCredit per data frame before writing
15+// it and waits while it has too little, so a slow consumer slows its own
16+// sender instead of failing the stream. The receiver returns the credit of
17+// every frame its consumer has fully read with one StreamWindowUpdate per
18+// batch. Because a conforming peer never exceeds the window, the wire reader
19+// never blocks: it appends each frame to the queue, and a frame beyond the
20+// granted credit is a peer violation (ErrStreamCredit) that settles only that
21+// stream. Close releases the reader, a writer waiting for credit, and the
22+// writer's peer promptly.
1923 type streamPipe struct {
20- mu sync.Mutex
21- queue [][]byte
22- queued int
23- closed bool
24- err error
25- maxChunk int
26- maxBytes int
24+ mu sync.Mutex
25+ queue []pipeChunk
26+ closed bool
27+ err error
28+
29+ // recvUsed is the credit held by queued frames, recvReturn the credit of
30+ // fully read frames not yet granted back, and returnAt the batch size.
31+ recvUsed uint64
32+ recvReturn uint64
33+ returnAt uint64
34+ // sendCredit is what the peer still allows this side to send.
35+ sendCredit uint64
36+ creditWake chan struct{}
2737
2838 wake chan struct{}
2939 closedCh chan struct{}
3040
3141 outbound func([]byte) error
42+ grant func(uint64) error
3243 }
3344
34-// newStreamPipe builds one bounded stream carriage. outbound must not be nil.
35-func newStreamPipe(maxChunks int, maxBytes uint64, outbound func([]byte) error) *streamPipe {
36- if maxChunks <= 0 {
37- maxChunks = DefaultStreamInboundChunks
38- }
39- if maxBytes == 0 {
40- maxBytes = DefaultStreamInboundBytes
41- }
45+// pipeChunk is one queued inbound frame and the credit it holds until it is
46+// fully read.
47+type pipeChunk struct {
48+ data []byte
49+ cost uint64
50+}
51+
52+// newStreamPipe builds one stream carriage. outbound writes one outbound byte
53+// slice; grant returns consumed inbound credit to the peer. Neither may be nil.
54+func newStreamPipe(outbound func([]byte) error, grant func(uint64) error) *streamPipe {
55+ window := brokerwire.StreamWindowBytes
4256 return &streamPipe{
43- maxChunk: maxChunks,
44- maxBytes: int(maxBytes),
45- wake: make(chan struct{}, 1),
46- closedCh: make(chan struct{}),
47- outbound: outbound,
57+ returnAt: streamCreditReturnAt(window),
58+ sendCredit: window,
59+ creditWake: make(chan struct{}),
60+ wake: make(chan struct{}, 1),
61+ closedCh: make(chan struct{}),
62+ outbound: outbound,
63+ grant: grant,
4864 }
4965 }
5066
51-// Read serves the next queued chunk, blocking until one arrives or the pipe
52-// closes. A partial copy retains the unread remainder for the next call.
67+// streamCreditReturnAt is the consumed credit a receiver batches before it
68+// grants it back: half the window, lowered so a sender blocked on a maximum
69+// frame is always released. A sender waits only once more than
70+// window-StreamChunkCredit(max) is unreturned, so granting at or below that
71+// point can never deadlock.
72+func streamCreditReturnAt(window uint64) uint64 {
73+ cost := brokerwire.StreamChunkCredit(int(brokerwire.MaxStreamChunkBytes))
74+ return max(min(window/2, window-cost+1), 1)
75+}
76+
77+// Read serves the next queued frame, blocking until one arrives or the pipe
78+// closes. A partial copy retains the unread remainder for the next call. The
79+// credit of each fully read frame is returned to the peer in batches.
5380 func (p *streamPipe) Read(b []byte) (int, error) {
5481 if len(b) == 0 {
5582 return 0, nil
@@ -57,16 +84,26 @@ func (p *streamPipe) Read(b []byte) (int, error) {
5784 for {
5885 p.mu.Lock()
5986 if len(p.queue) > 0 {
60- chunk := p.queue[0]
61- n := copy(b, chunk)
62- if n == len(chunk) {
63- p.queue[0] = nil
87+ chunk := &p.queue[0]
88+ n := copy(b, chunk.data)
89+ var grant uint64
90+ if n == len(chunk.data) {
91+ p.recvUsed -= chunk.cost
92+ p.recvReturn += chunk.cost
93+ p.queue[0] = pipeChunk{}
6494 p.queue = p.queue[1:]
95+ if p.recvReturn >= p.returnAt && !p.closed {
96+ grant, p.recvReturn = p.recvReturn, 0
97+ }
6598 } else {
66- p.queue[0] = chunk[n:]
99+ chunk.data = chunk.data[n:]
67100 }
68- p.queued -= n
69101 p.mu.Unlock()
102+ if grant > 0 {
103+ // A failed grant means the connection itself is failing; its
104+ // terminal path settles this stream, so there is nothing to retry.
105+ _ = p.grant(grant)
106+ }
70107 return n, nil
71108 }
72109 if p.closed {
@@ -85,8 +122,9 @@ func (p *streamPipe) Read(b []byte) (int, error) {
85122 }
86123 }
87124
88-// Write hands one byte slice to the outbound hook. It returns ErrClosed once the
89-// pipe reached its terminal outcome.
125+// Write hands one byte slice to the outbound hook, which spends send credit
126+// per frame through reserve. It returns ErrStreamGone once the pipe reached its
127+// terminal outcome.
90128 func (p *streamPipe) Write(b []byte) (int, error) {
91129 p.mu.Lock()
92130 closed := p.closed
@@ -100,25 +138,68 @@ func (p *streamPipe) Write(b []byte) (int, error) {
100138 return len(b), nil
101139 }
102140
103-// deliver accepts one inbound chunk from the connection reader. It returns
104-// ErrStreamBackpressure when the bound is reached and ErrStreamGone once the
105-// pipe is closed; the caller settles the affected stream in both cases.
141+// reserve spends the send credit of one outbound frame of n bytes, waiting for
142+// the peer to grant more when it is short. It returns ErrStreamGone once the
143+// pipe closes, so a writer waiting for credit is always released.
144+func (p *streamPipe) reserve(n int) error {
145+ cost := brokerwire.StreamChunkCredit(n)
146+ for {
147+ p.mu.Lock()
148+ if p.closed {
149+ p.mu.Unlock()
150+ return ErrStreamGone
151+ }
152+ if p.sendCredit >= cost {
153+ p.sendCredit -= cost
154+ p.mu.Unlock()
155+ return nil
156+ }
157+ wake := p.creditWake
158+ p.mu.Unlock()
159+ select {
160+ case <-wake:
161+ case <-p.closedCh:
162+ }
163+ }
164+}
165+
166+// granted adds credit the peer returned. Credit beyond the window is a peer
167+// flow-control violation.
168+func (p *streamPipe) granted(credit uint64) error {
169+ p.mu.Lock()
170+ defer p.mu.Unlock()
171+ if p.closed {
172+ return nil
173+ }
174+ if credit > brokerwire.StreamWindowBytes-p.sendCredit {
175+ return ErrStreamCredit
176+ }
177+ p.sendCredit += credit
178+ close(p.creditWake)
179+ p.creditWake = make(chan struct{})
180+ return nil
181+}
182+
183+// deliver accepts one inbound frame from the connection reader. It returns
184+// ErrStreamCredit when the peer sent beyond the credit it was granted and
185+// ErrStreamGone once the pipe is closed; the caller settles the affected stream
186+// in both cases.
106187 func (p *streamPipe) deliver(chunk []byte) error {
107188 if len(chunk) == 0 {
108189 return nil
109190 }
191+ cost := brokerwire.StreamChunkCredit(len(chunk))
110192 p.mu.Lock()
111193 if p.closed {
112194 p.mu.Unlock()
113195 return ErrStreamGone
114196 }
115- if len(p.queue) >= p.maxChunk || p.queued+len(chunk) > p.maxBytes {
197+ if p.recvUsed+p.recvReturn+cost > brokerwire.StreamWindowBytes {
116198 p.mu.Unlock()
117- return ErrStreamBackpressure
199+ return ErrStreamCredit
118200 }
119- owned := append([]byte(nil), chunk...)
120- p.queue = append(p.queue, owned)
121- p.queued += len(owned)
201+ p.queue = append(p.queue, pipeChunk{data: append([]byte(nil), chunk...), cost: cost})
202+ p.recvUsed += cost
122203 p.mu.Unlock()
123204 select {
124205 case p.wake <- struct{}{}:
@@ -128,7 +209,7 @@ func (p *streamPipe) deliver(chunk []byte) error {
128209 }
129210
130211 // closeWith settles the pipe exactly once with cause. A nil cause is an orderly
131-// close; every blocked Read observes it promptly. On a nil cause, any chunks
212+// close; every blocked Read observes it promptly. On a nil cause, any frames
132213 // already queued are kept: Read serves them first and only returns io.EOF once
133214 // the queue is drained, so a reply that arrived just before an orderly peer
134215 // close is never discarded underneath its reader. An error cause is a failure:
@@ -144,7 +225,7 @@ func (p *streamPipe) closeWith(cause error) {
144225 p.err = cause
145226 if cause != nil {
146227 p.queue = nil
147- p.queued = 0
228+ p.recvUsed = 0
148229 }
149230 p.mu.Unlock()
150231 close(p.closedCh)
@@ -3,53 +3,80 @@ package brokeripc
3 import (3 import (
4 "io"4 "io"
5 "sync"5 "sync"
6+
7+ "github.com/bnema/vev/internal/adapters/brokerwire"
6 )8 )
7 9
8-// streamPipe is the private ordered, bounded byte channel between one broker10+// streamPipe is the private ordered, credit-controlled byte channel between one
9-// wire session and the sessionwire framing of one logical stream.11+// broker wire session and the sessionwire framing of one logical stream.
10 //12 //
11-// The wire reader never blocks on a slow consumer: a chunk the peer sent is13+// Each direction of a stream has a brokerwire.StreamWindowBytes credit window.
12-// appended to a bounded queue and refused with ErrStreamBackpressure once the14+// The sender spends brokerwire.StreamChunkCredit per data frame before writing
13-// bound is reached, so only that stream is settled and every sibling and the15+// it and waits while it has too little, so a slow consumer slows its own
14-// physical connection stay untouched. The consumer never blocks the writer:16+// sender instead of failing the stream. The receiver returns the credit of
15-// Read serves already-queued chunks or parks on the wake channel, and Close17+// every frame its consumer has fully read with one StreamWindowUpdate per
16-// releases both ends promptly. Write hands each byte slice to the injected18+// batch. Because a conforming peer never exceeds the window, the wire reader
17-// outbound hook, which owns chunking it under the negotiated stream chunk19+// never blocks: it appends each frame to the queue, and a frame beyond the
18-// ceiling and enqueueing the frames on the connection.20+// granted credit is a peer violation (ErrStreamCredit) that settles only that
21+// stream. Close releases the reader, a writer waiting for credit, and the
22+// writer's peer promptly.
19 type streamPipe struct {23 type streamPipe struct {
20- mu sync.Mutex24+ mu sync.Mutex
21- queue [][]byte25+ queue []pipeChunk
22- queued int26+ closed bool
23- closed bool27+ err error
24- err error28+
25- maxChunk int29+ // recvUsed is the credit held by queued frames, recvReturn the credit of
26- maxBytes int30+ // fully read frames not yet granted back, and returnAt the batch size.
31+ recvUsed uint64
32+ recvReturn uint64
33+ returnAt uint64
34+ // sendCredit is what the peer still allows this side to send.
35+ sendCredit uint64
36+ creditWake chan struct{}
27 37
28 wake chan struct{}38 wake chan struct{}
29 closedCh chan struct{}39 closedCh chan struct{}
30 40
31 outbound func([]byte) error41 outbound func([]byte) error
42+ grant func(uint64) error
32 }43 }
33 44
34-// newStreamPipe builds one bounded stream carriage. outbound must not be nil.45+// pipeChunk is one queued inbound frame and the credit it holds until it is
35-func newStreamPipe(maxChunks int, maxBytes uint64, outbound func([]byte) error) *streamPipe {46+// fully read.
36- if maxChunks <= 0 {47+type pipeChunk struct {
37- maxChunks = DefaultStreamInboundChunks48+ data []byte
38- }49+ cost uint64
39- if maxBytes == 0 {50+}
40- maxBytes = DefaultStreamInboundBytes51+
41- }52+// newStreamPipe builds one stream carriage. outbound writes one outbound byte
53+// slice; grant returns consumed inbound credit to the peer. Neither may be nil.
54+func newStreamPipe(outbound func([]byte) error, grant func(uint64) error) *streamPipe {
55+ window := brokerwire.StreamWindowBytes
42 return &streamPipe{56 return &streamPipe{
43- maxChunk: maxChunks,57+ returnAt: streamCreditReturnAt(window),
44- maxBytes: int(maxBytes),58+ sendCredit: window,
45- wake: make(chan struct{}, 1),59+ creditWake: make(chan struct{}),
46- closedCh: make(chan struct{}),60+ wake: make(chan struct{}, 1),
47- outbound: outbound,61+ closedCh: make(chan struct{}),
62+ outbound: outbound,
63+ grant: grant,
48 }64 }
49 }65 }
50 66
51-// Read serves the next queued chunk, blocking until one arrives or the pipe67+// streamCreditReturnAt is the consumed credit a receiver batches before it
52-// closes. A partial copy retains the unread remainder for the next call.68+// grants it back: half the window, lowered so a sender blocked on a maximum
69+// frame is always released. A sender waits only once more than
70+// window-StreamChunkCredit(max) is unreturned, so granting at or below that
71+// point can never deadlock.
72+func streamCreditReturnAt(window uint64) uint64 {
73+ cost := brokerwire.StreamChunkCredit(int(brokerwire.MaxStreamChunkBytes))
74+ return max(min(window/2, window-cost+1), 1)
75+}
76+
77+// Read serves the next queued frame, blocking until one arrives or the pipe
78+// closes. A partial copy retains the unread remainder for the next call. The
79+// credit of each fully read frame is returned to the peer in batches.
53 func (p *streamPipe) Read(b []byte) (int, error) {80 func (p *streamPipe) Read(b []byte) (int, error) {
54 if len(b) == 0 {81 if len(b) == 0 {
55 return 0, nil82 return 0, nil
@@ -57,16 +84,26 @@ func (p *streamPipe) Read(b []byte) (int, error) {
57 for {84 for {
58 p.mu.Lock()85 p.mu.Lock()
59 if len(p.queue) > 0 {86 if len(p.queue) > 0 {
60- chunk := p.queue[0]87+ chunk := &p.queue[0]
61- n := copy(b, chunk)88+ n := copy(b, chunk.data)
62- if n == len(chunk) {89+ var grant uint64
63- p.queue[0] = nil90+ if n == len(chunk.data) {
91+ p.recvUsed -= chunk.cost
92+ p.recvReturn += chunk.cost
93+ p.queue[0] = pipeChunk{}
64 p.queue = p.queue[1:]94 p.queue = p.queue[1:]
95+ if p.recvReturn >= p.returnAt && !p.closed {
96+ grant, p.recvReturn = p.recvReturn, 0
97+ }
65 } else {98 } else {
66- p.queue[0] = chunk[n:]99+ chunk.data = chunk.data[n:]
67 }100 }
68- p.queued -= n
69 p.mu.Unlock()101 p.mu.Unlock()
102+ if grant > 0 {
103+ // A failed grant means the connection itself is failing; its
104+ // terminal path settles this stream, so there is nothing to retry.
105+ _ = p.grant(grant)
106+ }
70 return n, nil107 return n, nil
71 }108 }
72 if p.closed {109 if p.closed {
@@ -85,8 +122,9 @@ func (p *streamPipe) Read(b []byte) (int, error) {
85 }122 }
86 }123 }
87 124
88-// Write hands one byte slice to the outbound hook. It returns ErrClosed once the125+// Write hands one byte slice to the outbound hook, which spends send credit
89-// pipe reached its terminal outcome.126+// per frame through reserve. It returns ErrStreamGone once the pipe reached its
127+// terminal outcome.
90 func (p *streamPipe) Write(b []byte) (int, error) {128 func (p *streamPipe) Write(b []byte) (int, error) {
91 p.mu.Lock()129 p.mu.Lock()
92 closed := p.closed130 closed := p.closed
@@ -100,25 +138,68 @@ func (p *streamPipe) Write(b []byte) (int, error) {
100 return len(b), nil138 return len(b), nil
101 }139 }
102 140
103-// deliver accepts one inbound chunk from the connection reader. It returns141+// reserve spends the send credit of one outbound frame of n bytes, waiting for
104-// ErrStreamBackpressure when the bound is reached and ErrStreamGone once the142+// the peer to grant more when it is short. It returns ErrStreamGone once the
105-// pipe is closed; the caller settles the affected stream in both cases.143+// pipe closes, so a writer waiting for credit is always released.
144+func (p *streamPipe) reserve(n int) error {
145+ cost := brokerwire.StreamChunkCredit(n)
146+ for {
147+ p.mu.Lock()
148+ if p.closed {
149+ p.mu.Unlock()
150+ return ErrStreamGone
151+ }
152+ if p.sendCredit >= cost {
153+ p.sendCredit -= cost
154+ p.mu.Unlock()
155+ return nil
156+ }
157+ wake := p.creditWake
158+ p.mu.Unlock()
159+ select {
160+ case <-wake:
161+ case <-p.closedCh:
162+ }
163+ }
164+}
165+
166+// granted adds credit the peer returned. Credit beyond the window is a peer
167+// flow-control violation.
168+func (p *streamPipe) granted(credit uint64) error {
169+ p.mu.Lock()
170+ defer p.mu.Unlock()
171+ if p.closed {
172+ return nil
173+ }
174+ if credit > brokerwire.StreamWindowBytes-p.sendCredit {
175+ return ErrStreamCredit
176+ }
177+ p.sendCredit += credit
178+ close(p.creditWake)
179+ p.creditWake = make(chan struct{})
180+ return nil
181+}
182+
183+// deliver accepts one inbound frame from the connection reader. It returns
184+// ErrStreamCredit when the peer sent beyond the credit it was granted and
185+// ErrStreamGone once the pipe is closed; the caller settles the affected stream
186+// in both cases.
106 func (p *streamPipe) deliver(chunk []byte) error {187 func (p *streamPipe) deliver(chunk []byte) error {
107 if len(chunk) == 0 {188 if len(chunk) == 0 {
108 return nil189 return nil
109 }190 }
191+ cost := brokerwire.StreamChunkCredit(len(chunk))
110 p.mu.Lock()192 p.mu.Lock()
111 if p.closed {193 if p.closed {
112 p.mu.Unlock()194 p.mu.Unlock()
113 return ErrStreamGone195 return ErrStreamGone
114 }196 }
115- if len(p.queue) >= p.maxChunk || p.queued+len(chunk) > p.maxBytes {197+ if p.recvUsed+p.recvReturn+cost > brokerwire.StreamWindowBytes {
116 p.mu.Unlock()198 p.mu.Unlock()
117- return ErrStreamBackpressure199+ return ErrStreamCredit
118 }200 }
119- owned := append([]byte(nil), chunk...)201+ p.queue = append(p.queue, pipeChunk{data: append([]byte(nil), chunk...), cost: cost})
120- p.queue = append(p.queue, owned)202+ p.recvUsed += cost
121- p.queued += len(owned)
122 p.mu.Unlock()203 p.mu.Unlock()
123 select {204 select {
124 case p.wake <- struct{}{}:205 case p.wake <- struct{}{}:
@@ -128,7 +209,7 @@ func (p *streamPipe) deliver(chunk []byte) error {
128 }209 }
129 210
130 // closeWith settles the pipe exactly once with cause. A nil cause is an orderly211 // closeWith settles the pipe exactly once with cause. A nil cause is an orderly
131-// close; every blocked Read observes it promptly. On a nil cause, any chunks212+// close; every blocked Read observes it promptly. On a nil cause, any frames
132 // already queued are kept: Read serves them first and only returns io.EOF once213 // already queued are kept: Read serves them first and only returns io.EOF once
133 // the queue is drained, so a reply that arrived just before an orderly peer214 // the queue is drained, so a reply that arrived just before an orderly peer
134 // close is never discarded underneath its reader. An error cause is a failure:215 // close is never discarded underneath its reader. An error cause is a failure:
@@ -144,7 +225,7 @@ func (p *streamPipe) closeWith(cause error) {
144 p.err = cause225 p.err = cause
145 if cause != nil {226 if cause != nil {
146 p.queue = nil227 p.queue = nil
147- p.queued = 0228+ p.recvUsed = 0
148 }229 }
149 p.mu.Unlock()230 p.mu.Unlock()
150 close(p.closedCh)231 close(p.closedCh)
M internal/adapters/brokeripc/pipe_test.go +98 -19
@@ -5,6 +5,7 @@ import (
55 "errors"
66 "io"
77 "testing"
8+ "time"
89
910 "github.com/bnema/vev/internal/adapters/brokerwire"
1011 "github.com/bnema/vev/internal/protocol"
@@ -71,7 +72,7 @@ func TestStreamPipeCloseWithPreservesQueuedDataOnOrderlyClose(t *testing.T) {
7172
7273 for _, tt := range tests {
7374 t.Run(tt.name, func(t *testing.T) {
74- p := newStreamPipe(0, 0, func([]byte) error { return nil })
75+ p := newTestPipe()
7576 for _, chunk := range tt.chunks {
7677 require.NoError(t, p.deliver(chunk))
7778 }
@@ -109,26 +110,104 @@ func TestStreamPipeCloseWithPreservesQueuedDataOnOrderlyClose(t *testing.T) {
109110 }
110111 }
111112
112-// TestStreamPipeHoldsAFullOutputWindow pins the client pipe headroom for the
113-// session output window. A client claims protocol.MaxOutputWindow unacked
114-// Output frames; with a terminal that is not draining, all of them may sit in
115-// this pipe at once, and overflow fails the whole stream
116-// (ErrStreamBackpressure). The frame size is a typical text repaint: a
117-// near-full page of a 500x140 terminal measured about 70 KB. Uncompressed diff
118-// frames with per-cell truecolor SGR can be far larger (estimated near 1 MB at
119-// 300x80), and eight of those can still overflow the default 4 MiB bound.
120-func TestStreamPipeHoldsAFullOutputWindow(t *testing.T) {
121- const frameBytes = 72 << 10
113+// newTestPipe is a pipe whose outbound writes and credit grants go nowhere.
114+func newTestPipe() *streamPipe {
115+ return newStreamPipe(func([]byte) error { return nil }, func(uint64) error { return nil })
116+}
117+
118+// TestStreamWindowCoversTheSessionOutputWindow pins the invariant that lets a
119+// broker stream carry a full session output window without the daemon ever
120+// waiting on the stream instead of on its own ACK window: the daemon's
121+// unacknowledged byte budget plus one maximum Output fits in one stream window.
122+// When it does not, credit still keeps every stream correct, only slower.
123+func TestStreamWindowCoversTheSessionOutputWindow(t *testing.T) {
124+ require.GreaterOrEqual(t, brokerwire.StreamWindowBytes, uint64(protocol.MaxOutputWindowBytes),
125+ "one stream window must hold the daemon's whole unacknowledged byte budget")
126+}
127+
128+// TestStreamPipeCredit covers the receive and send sides of stream credit:
129+// a peer may send up to one window, the consumer's reads return credit in
130+// batches, a sender waits instead of failing while it has none, and grants or
131+// data beyond the window are flow-control violations.
132+func TestStreamPipeCredit(t *testing.T) {
122133 chunk := int(brokerwire.MaxStreamChunkBytes)
123- p := newStreamPipe(0, 0, func([]byte) error { return nil })
124- payload := bytes.Repeat([]byte{'x'}, frameBytes)
125- for frame := range protocol.MaxOutputWindow {
126- for data := payload; len(data) > 0; {
127- n := min(len(data), chunk)
128- require.NoError(t, p.deliver(data[:n]), "frame %d overflowed the client pipe", frame)
129- data = data[n:]
134+ cost := brokerwire.StreamChunkCredit(chunk)
135+ perWindow := int(brokerwire.StreamWindowBytes / cost)
136+
137+ t.Run("a full window is accepted and one more frame is a violation", func(t *testing.T) {
138+ p := newTestPipe()
139+ for range perWindow {
140+ require.NoError(t, p.deliver(make([]byte, chunk)))
130141 }
131- }
142+ require.ErrorIs(t, p.deliver(make([]byte, chunk)), ErrStreamCredit)
143+ })
144+
145+ t.Run("reads return credit in batches", func(t *testing.T) {
146+ var grants []uint64
147+ p := newStreamPipe(func([]byte) error { return nil }, func(c uint64) error { grants = append(grants, c); return nil })
148+ for range perWindow {
149+ require.NoError(t, p.deliver(make([]byte, chunk)))
150+ }
151+ buf := make([]byte, chunk)
152+ for range perWindow {
153+ _, err := io.ReadFull(p, buf)
154+ require.NoError(t, err)
155+ }
156+ require.NotEmpty(t, grants)
157+ total := uint64(0)
158+ for _, g := range grants {
159+ require.GreaterOrEqual(t, g, streamCreditReturnAt(brokerwire.StreamWindowBytes))
160+ total += g
161+ }
162+ require.LessOrEqual(t, total, uint64(perWindow)*cost)
163+ // Once the returned credit reaches the peer, the window is open again.
164+ require.NoError(t, p.deliver(make([]byte, chunk)))
165+ })
166+
167+ t.Run("a sender waits for credit and resumes on a grant", func(t *testing.T) {
168+ p := newTestPipe()
169+ for range perWindow {
170+ require.NoError(t, p.reserve(chunk))
171+ }
172+ reserved := make(chan error, 1)
173+ go func() { reserved <- p.reserve(chunk) }()
174+ select {
175+ case err := <-reserved:
176+ t.Fatalf("reserve returned %v without credit", err)
177+ case <-time.After(20 * time.Millisecond):
178+ }
179+ require.NoError(t, p.granted(cost))
180+ select {
181+ case err := <-reserved:
182+ require.NoError(t, err)
183+ case <-time.After(5 * time.Second):
184+ t.Fatal("a grant must release a sender waiting for credit")
185+ }
186+ })
187+
188+ t.Run("close releases a sender waiting for credit", func(t *testing.T) {
189+ p := newTestPipe()
190+ for range perWindow {
191+ require.NoError(t, p.reserve(chunk))
192+ }
193+ reserved := make(chan error, 1)
194+ go func() { reserved <- p.reserve(chunk) }()
195+ p.closeWith(ErrStreamGone)
196+ select {
197+ case err := <-reserved:
198+ require.ErrorIs(t, err, ErrStreamGone)
199+ case <-time.After(5 * time.Second):
200+ t.Fatal("close must release a sender waiting for credit")
201+ }
202+ })
203+
204+ t.Run("a grant beyond the window is a violation", func(t *testing.T) {
205+ p := newTestPipe()
206+ require.ErrorIs(t, p.granted(1), ErrStreamCredit)
207+ require.NoError(t, p.reserve(chunk))
208+ require.NoError(t, p.granted(cost))
209+ require.ErrorIs(t, p.granted(1), ErrStreamCredit)
210+ })
132211 }
133212
134213 // TestClientStreamPrefersTheFullOutputWindow pins what a real broker-routed
@@ -5,6 +5,7 @@ import (
5 "errors"5 "errors"
6 "io"6 "io"
7 "testing"7 "testing"
8+ "time"
8 9
9 "github.com/bnema/vev/internal/adapters/brokerwire"10 "github.com/bnema/vev/internal/adapters/brokerwire"
10 "github.com/bnema/vev/internal/protocol"11 "github.com/bnema/vev/internal/protocol"
@@ -71,7 +72,7 @@ func TestStreamPipeCloseWithPreservesQueuedDataOnOrderlyClose(t *testing.T) {
71 72
72 for _, tt := range tests {73 for _, tt := range tests {
73 t.Run(tt.name, func(t *testing.T) {74 t.Run(tt.name, func(t *testing.T) {
74- p := newStreamPipe(0, 0, func([]byte) error { return nil })75+ p := newTestPipe()
75 for _, chunk := range tt.chunks {76 for _, chunk := range tt.chunks {
76 require.NoError(t, p.deliver(chunk))77 require.NoError(t, p.deliver(chunk))
77 }78 }
@@ -109,26 +110,104 @@ func TestStreamPipeCloseWithPreservesQueuedDataOnOrderlyClose(t *testing.T) {
109 }110 }
110 }111 }
111 112
112-// TestStreamPipeHoldsAFullOutputWindow pins the client pipe headroom for the113+// newTestPipe is a pipe whose outbound writes and credit grants go nowhere.
113-// session output window. A client claims protocol.MaxOutputWindow unacked114+func newTestPipe() *streamPipe {
114-// Output frames; with a terminal that is not draining, all of them may sit in115+ return newStreamPipe(func([]byte) error { return nil }, func(uint64) error { return nil })
115-// this pipe at once, and overflow fails the whole stream116+}
116-// (ErrStreamBackpressure). The frame size is a typical text repaint: a117+
117-// near-full page of a 500x140 terminal measured about 70 KB. Uncompressed diff118+// TestStreamWindowCoversTheSessionOutputWindow pins the invariant that lets a
118-// frames with per-cell truecolor SGR can be far larger (estimated near 1 MB at119+// broker stream carry a full session output window without the daemon ever
119-// 300x80), and eight of those can still overflow the default 4 MiB bound.120+// waiting on the stream instead of on its own ACK window: the daemon's
120-func TestStreamPipeHoldsAFullOutputWindow(t *testing.T) {121+// unacknowledged byte budget plus one maximum Output fits in one stream window.
121- const frameBytes = 72 << 10122+// When it does not, credit still keeps every stream correct, only slower.
123+func TestStreamWindowCoversTheSessionOutputWindow(t *testing.T) {
124+ require.GreaterOrEqual(t, brokerwire.StreamWindowBytes, uint64(protocol.MaxOutputWindowBytes),
125+ "one stream window must hold the daemon's whole unacknowledged byte budget")
126+}
127+
128+// TestStreamPipeCredit covers the receive and send sides of stream credit:
129+// a peer may send up to one window, the consumer's reads return credit in
130+// batches, a sender waits instead of failing while it has none, and grants or
131+// data beyond the window are flow-control violations.
132+func TestStreamPipeCredit(t *testing.T) {
122 chunk := int(brokerwire.MaxStreamChunkBytes)133 chunk := int(brokerwire.MaxStreamChunkBytes)
123- p := newStreamPipe(0, 0, func([]byte) error { return nil })134+ cost := brokerwire.StreamChunkCredit(chunk)
124- payload := bytes.Repeat([]byte{'x'}, frameBytes)135+ perWindow := int(brokerwire.StreamWindowBytes / cost)
125- for frame := range protocol.MaxOutputWindow {136+
126- for data := payload; len(data) > 0; {137+ t.Run("a full window is accepted and one more frame is a violation", func(t *testing.T) {
127- n := min(len(data), chunk)138+ p := newTestPipe()
128- require.NoError(t, p.deliver(data[:n]), "frame %d overflowed the client pipe", frame)139+ for range perWindow {
129- data = data[n:]140+ require.NoError(t, p.deliver(make([]byte, chunk)))
130 }141 }
131- }142+ require.ErrorIs(t, p.deliver(make([]byte, chunk)), ErrStreamCredit)
143+ })
144+
145+ t.Run("reads return credit in batches", func(t *testing.T) {
146+ var grants []uint64
147+ p := newStreamPipe(func([]byte) error { return nil }, func(c uint64) error { grants = append(grants, c); return nil })
148+ for range perWindow {
149+ require.NoError(t, p.deliver(make([]byte, chunk)))
150+ }
151+ buf := make([]byte, chunk)
152+ for range perWindow {
153+ _, err := io.ReadFull(p, buf)
154+ require.NoError(t, err)
155+ }
156+ require.NotEmpty(t, grants)
157+ total := uint64(0)
158+ for _, g := range grants {
159+ require.GreaterOrEqual(t, g, streamCreditReturnAt(brokerwire.StreamWindowBytes))
160+ total += g
161+ }
162+ require.LessOrEqual(t, total, uint64(perWindow)*cost)
163+ // Once the returned credit reaches the peer, the window is open again.
164+ require.NoError(t, p.deliver(make([]byte, chunk)))
165+ })
166+
167+ t.Run("a sender waits for credit and resumes on a grant", func(t *testing.T) {
168+ p := newTestPipe()
169+ for range perWindow {
170+ require.NoError(t, p.reserve(chunk))
171+ }
172+ reserved := make(chan error, 1)
173+ go func() { reserved <- p.reserve(chunk) }()
174+ select {
175+ case err := <-reserved:
176+ t.Fatalf("reserve returned %v without credit", err)
177+ case <-time.After(20 * time.Millisecond):
178+ }
179+ require.NoError(t, p.granted(cost))
180+ select {
181+ case err := <-reserved:
182+ require.NoError(t, err)
183+ case <-time.After(5 * time.Second):
184+ t.Fatal("a grant must release a sender waiting for credit")
185+ }
186+ })
187+
188+ t.Run("close releases a sender waiting for credit", func(t *testing.T) {
189+ p := newTestPipe()
190+ for range perWindow {
191+ require.NoError(t, p.reserve(chunk))
192+ }
193+ reserved := make(chan error, 1)
194+ go func() { reserved <- p.reserve(chunk) }()
195+ p.closeWith(ErrStreamGone)
196+ select {
197+ case err := <-reserved:
198+ require.ErrorIs(t, err, ErrStreamGone)
199+ case <-time.After(5 * time.Second):
200+ t.Fatal("close must release a sender waiting for credit")
201+ }
202+ })
203+
204+ t.Run("a grant beyond the window is a violation", func(t *testing.T) {
205+ p := newTestPipe()
206+ require.ErrorIs(t, p.granted(1), ErrStreamCredit)
207+ require.NoError(t, p.reserve(chunk))
208+ require.NoError(t, p.granted(cost))
209+ require.ErrorIs(t, p.granted(1), ErrStreamCredit)
210+ })
132 }211 }
133 212
134 // TestClientStreamPrefersTheFullOutputWindow pins what a real broker-routed213 // TestClientStreamPrefersTheFullOutputWindow pins what a real broker-routed
M internal/adapters/brokeripc/server.go +5 -0
@@ -763,6 +763,11 @@ func (s *serverSession) dispatch(message brokerwire.ClientMessage) error {
763763 }
764764 s.closeStreamByPeer(m.Stream)
765765 return nil
766+ case brokerwire.StreamWindowUpdate:
767+ if !s.scopeMatches(m.Epoch, m.Connection) {
768+ return s.refuseScope()
769+ }
770+ return s.grantStreamCredit(m)
766771 case brokerwire.StartPreview:
767772 if !s.scopeMatches(m.Epoch, m.Connection) {
768773 return s.refuseScope()
@@ -763,6 +763,11 @@ func (s *serverSession) dispatch(message brokerwire.ClientMessage) error {
763 }763 }
764 s.closeStreamByPeer(m.Stream)764 s.closeStreamByPeer(m.Stream)
765 return nil765 return nil
766+ case brokerwire.StreamWindowUpdate:
767+ if !s.scopeMatches(m.Epoch, m.Connection) {
768+ return s.refuseScope()
769+ }
770+ return s.grantStreamCredit(m)
766 case brokerwire.StartPreview:771 case brokerwire.StartPreview:
767 if !s.scopeMatches(m.Epoch, m.Connection) {772 if !s.scopeMatches(m.Epoch, m.Connection) {
768 return s.refuseScope()773 return s.refuseScope()
M internal/adapters/brokeripc/session_test.go +47 -22
@@ -856,43 +856,68 @@ func TestStalledSubscriberDoesNotBlockOtherClients(t *testing.T) {
856856 requireConnectionDelegates(t, active)
857857 }
858858
859-// TestClientStreamBackpressureSettlesOnlyThatStream proves a local consumer that
860-// stops draining a stream's bounded inbound queue settles exactly that stream:
861-// the peer is told, the stream reports backpressure, and the connection and its
862-// operations stay up.
863-func TestClientStreamBackpressureSettlesOnlyThatStream(t *testing.T) {
859+// TestStalledClientStreamWaitsForCredit proves a local consumer that stops
860+// reading slows the broker relay instead of losing its stream: the daemon's
861+// messages beyond one stream window wait at the broker, every one is delivered
862+// in order once the consumer reads again, and the connection stays usable
863+// meanwhile.
864+func TestStalledClientStreamWaitsForCredit(t *testing.T) {
864865 e := startEndpoint(t, Config{MaxClients: 2})
865- client := e.dialWith(Config{StreamInboundChunks: 1})
866+ client := e.dial()
866867 _ = e.accept()
867868 core := e.authority.last()
868869
869- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
870+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
870871 defer cancel()
871872 stream, err := client.OpenStream(ctx, openRequest(nextStreamID(t, client)))
872873 require.NoError(t, err)
874+ t.Cleanup(func() { _ = stream.Close() })
873875 conn := core.logicalConn(1)
874876 require.NotNil(t, conn)
877+ // Complete the session preamble before the daemon speaks.
878+ require.NoError(t, stream.SendClient(protocol.Ping{}))
879+ select {
880+ case <-conn.fromClient:
881+ case <-ctx.Done():
882+ t.Fatal("client message never reached the broker core")
883+ }
875884
876- // Two daemon messages arrive while the local consumer never reads: the
877- // bounded capacity-one queue refuses the second one.
878- conn.toClient <- protocol.Pong{}
879- conn.toClient <- protocol.Pong{}
885+ // Well over one stream window of daemon output while nothing reads. Side
886+ // effect Outputs need no view context; random-looking data defeats
887+ // compression so every byte crosses the stream.
888+ const messages = 24
889+ data := make([]byte, 512<<10)
890+ for i := range data {
891+ data[i] = byte(i*131 + i/7)
892+ }
893+ go func() {
894+ for i := range messages {
895+ payload := append([]byte{byte(i)}, data...)
896+ select {
897+ case conn.toClient <- protocol.Output{Epoch: 1, Size: domain.Size{Cols: 80, Rows: 24}, Data: payload}:
898+ case <-ctx.Done():
899+ return
900+ }
901+ }
902+ }()
880903
904+ // The relay is blocked on credit, not failed: the stream stays open and the
905+ // connection keeps serving other work.
881906 select {
882907 case <-stream.Done():
883- case <-time.After(5 * time.Second):
884- t.Fatal("a stalled stream consumer must settle the stream")
908+ t.Fatalf("a stalled consumer must not settle its stream: %v", stream.Err())
909+ case <-time.After(200 * time.Millisecond):
885910 }
886- require.ErrorIs(t, stream.(*clientStream).Err(), ErrStreamBackpressure)
887-
888- require.Eventually(t, func() bool {
889- core.mu.Lock()
890- defer core.mu.Unlock()
891- return len(core.closedIDs) > 0
892- }, 5*time.Second, 10*time.Millisecond, "the broker must be told to retire the stalled stream")
893-
894- // The connection survives a stream-local stall.
895911 requireConnectionDelegates(t, client)
912+
913+ for i := range messages {
914+ message, err := stream.ReceiveServer()
915+ require.NoError(t, err)
916+ got, ok := message.(protocol.Output)
917+ require.True(t, ok, "message %d is %T", i, message)
918+ require.Len(t, got.Data, len(data)+1)
919+ require.Equal(t, byte(i), got.Data[0], "messages arrive in order")
920+ }
896921 }
897922
898923 // TestOrderlyStreamCloseReportsNoError proves a local close is an orderly end:
@@ -856,43 +856,68 @@ func TestStalledSubscriberDoesNotBlockOtherClients(t *testing.T) {
856 requireConnectionDelegates(t, active)856 requireConnectionDelegates(t, active)
857 }857 }
858 858
859-// TestClientStreamBackpressureSettlesOnlyThatStream proves a local consumer that859+// TestStalledClientStreamWaitsForCredit proves a local consumer that stops
860-// stops draining a stream's bounded inbound queue settles exactly that stream:860+// reading slows the broker relay instead of losing its stream: the daemon's
861-// the peer is told, the stream reports backpressure, and the connection and its861+// messages beyond one stream window wait at the broker, every one is delivered
862-// operations stay up.862+// in order once the consumer reads again, and the connection stays usable
863-func TestClientStreamBackpressureSettlesOnlyThatStream(t *testing.T) {863+// meanwhile.
864+func TestStalledClientStreamWaitsForCredit(t *testing.T) {
864 e := startEndpoint(t, Config{MaxClients: 2})865 e := startEndpoint(t, Config{MaxClients: 2})
865- client := e.dialWith(Config{StreamInboundChunks: 1})866+ client := e.dial()
866 _ = e.accept()867 _ = e.accept()
867 core := e.authority.last()868 core := e.authority.last()
868 869
869- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)870+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
870 defer cancel()871 defer cancel()
871 stream, err := client.OpenStream(ctx, openRequest(nextStreamID(t, client)))872 stream, err := client.OpenStream(ctx, openRequest(nextStreamID(t, client)))
872 require.NoError(t, err)873 require.NoError(t, err)
874+ t.Cleanup(func() { _ = stream.Close() })
873 conn := core.logicalConn(1)875 conn := core.logicalConn(1)
874 require.NotNil(t, conn)876 require.NotNil(t, conn)
877+ // Complete the session preamble before the daemon speaks.
878+ require.NoError(t, stream.SendClient(protocol.Ping{}))
879+ select {
880+ case <-conn.fromClient:
881+ case <-ctx.Done():
882+ t.Fatal("client message never reached the broker core")
883+ }
875 884
876- // Two daemon messages arrive while the local consumer never reads: the885+ // Well over one stream window of daemon output while nothing reads. Side
877- // bounded capacity-one queue refuses the second one.886+ // effect Outputs need no view context; random-looking data defeats
878- conn.toClient <- protocol.Pong{}887+ // compression so every byte crosses the stream.
879- conn.toClient <- protocol.Pong{}888+ const messages = 24
889+ data := make([]byte, 512<<10)
890+ for i := range data {
891+ data[i] = byte(i*131 + i/7)
892+ }
893+ go func() {
894+ for i := range messages {
895+ payload := append([]byte{byte(i)}, data...)
896+ select {
897+ case conn.toClient <- protocol.Output{Epoch: 1, Size: domain.Size{Cols: 80, Rows: 24}, Data: payload}:
898+ case <-ctx.Done():
899+ return
900+ }
901+ }
902+ }()
880 903
904+ // The relay is blocked on credit, not failed: the stream stays open and the
905+ // connection keeps serving other work.
881 select {906 select {
882 case <-stream.Done():907 case <-stream.Done():
883- case <-time.After(5 * time.Second):908+ t.Fatalf("a stalled consumer must not settle its stream: %v", stream.Err())
884- t.Fatal("a stalled stream consumer must settle the stream")909+ case <-time.After(200 * time.Millisecond):
885 }910 }
886- require.ErrorIs(t, stream.(*clientStream).Err(), ErrStreamBackpressure)
887-
888- require.Eventually(t, func() bool {
889- core.mu.Lock()
890- defer core.mu.Unlock()
891- return len(core.closedIDs) > 0
892- }, 5*time.Second, 10*time.Millisecond, "the broker must be told to retire the stalled stream")
893-
894- // The connection survives a stream-local stall.
895 requireConnectionDelegates(t, client)911 requireConnectionDelegates(t, client)
912+
913+ for i := range messages {
914+ message, err := stream.ReceiveServer()
915+ require.NoError(t, err)
916+ got, ok := message.(protocol.Output)
917+ require.True(t, ok, "message %d is %T", i, message)
918+ require.Len(t, got.Data, len(data)+1)
919+ require.Equal(t, byte(i), got.Data[0], "messages arrive in order")
920+ }
896 }921 }
897 922
898 // TestOrderlyStreamCloseReportsNoError proves a local close is an orderly end:923 // TestOrderlyStreamCloseReportsNoError proves a local close is an orderly end:
M internal/adapters/brokeripc/stream.go +64 -29
@@ -42,13 +42,15 @@ func newServerStream(s *serverSession, id ports.BrokerStreamID, core ports.Broke
4242 return nil, ErrConfig
4343 }
4444 st := &serverStream{session: s, id: id, core: core, done: make(chan struct{})}
45- st.pipe = newStreamPipe(s.cfg.StreamInboundChunks, s.cfg.StreamInboundBytes, st.sendChunk)
45+ st.pipe = newStreamPipe(st.sendChunk, st.grantCredit)
4646 st.carriage = newCarriage(st.pipe)
4747 return st, nil
4848 }
4949
5050 // sendChunk splits one outbound byte slice under the negotiated stream chunk
51-// ceiling and writes each frame in order.
51+// ceiling and writes each frame in order, waiting for the client's credit
52+// before each one: a client that is not reading slows this relay, and through
53+// the daemon link the daemon, instead of losing its stream.
5254 func (st *serverStream) sendChunk(data []byte) error {
5355 ceiling := int(st.session.ceilings.StreamChunkLimit)
5456 if ceiling <= 0 {
@@ -56,6 +58,9 @@ func (st *serverStream) sendChunk(data []byte) error {
5658 }
5759 for len(data) > 0 {
5860 n := min(len(data), ceiling)
61+ if err := st.pipe.reserve(n); err != nil {
62+ return err
63+ }
5964 if err := st.session.send(brokerwire.ServerStreamData{
6065 Epoch: st.session.epoch, Connection: st.session.scope.Connection, Stream: st.id, Data: data[:n],
6166 }); err != nil {
@@ -66,6 +71,13 @@ func (st *serverStream) sendChunk(data []byte) error {
6671 return nil
6772 }
6873
74+// grantCredit returns consumed inbound credit to the client.
75+func (st *serverStream) grantCredit(credit uint64) error {
76+ return st.session.send(brokerwire.StreamWindowUpdate{
77+ Epoch: st.session.epoch, Connection: st.session.scope.Connection, Stream: st.id, Credit: credit,
78+ })
79+}
80+
6981 // deliver accepts one inbound chunk from the connection reader.
7082 func (st *serverStream) deliver(chunk []byte) error { return st.pipe.deliver(chunk) }
7183
@@ -347,36 +359,47 @@ func (s *serverSession) closeStreamByPeer(id ports.BrokerStreamID) {
347359 _ = s.core.CloseStream(s.scope.Connection, id)
348360 }
349361
350-// deliverStreamData routes one inbound client chunk to its bridge. Backpressure
351-// settles only that stream; a chunk for an identity the peer never opened is a
352-// protocol violation.
362+// deliverStreamData routes one inbound client chunk to its bridge. Data beyond
363+// the granted credit settles only that stream; a chunk for an identity the peer
364+// never opened is a protocol violation.
353365 func (s *serverSession) deliverStreamData(m brokerwire.ClientStreamData) error {
354- disposition, err := s.conn.StreamData(m.Stream)
355- if err != nil {
356- // Stream data for a stream that was never allocated, or before it was
357- // confirmed open, is a peer protocol violation.
358- return errors.Join(ErrProtocol, err)
366+ st, err := s.streamFor(m.Stream)
367+ if st == nil || err != nil {
368+ return err
359369 }
360- if disposition == brokerwire.StreamDiscarded {
361- return nil
370+ if err := st.deliver(m.Data); errors.Is(err, ErrStreamCredit) {
371+ s.settleStream(st, ErrStreamCredit)
362372 }
363- st := s.lookupStream(m.Stream)
364- if st == nil {
365- // The bridge was settled between the tracker check and the lookup (a
366- // stream-local failure won the race); the chunk is discarded with it.
367- return nil
373+ // Any other error means the stream already reached its terminal outcome;
374+ // its data is discarded.
375+ return nil
376+}
377+
378+// grantStreamCredit applies one client credit grant to its bridge.
379+func (s *serverSession) grantStreamCredit(m brokerwire.StreamWindowUpdate) error {
380+ st, err := s.streamFor(m.Stream)
381+ if st == nil || err != nil {
382+ return err
368383 }
369- switch err := st.deliver(m.Data); {
370- case err == nil:
371- return nil
372- case errors.Is(err, ErrStreamBackpressure):
373- s.settleStream(st, ErrStreamBackpressure)
374- return nil
375- default:
376- // The stream already reached its terminal outcome; its data is
377- // discarded.
378- return nil
384+ if err := st.pipe.granted(m.Credit); err != nil {
385+ s.settleStream(st, err)
386+ }
387+ return nil
388+}
389+
390+// streamFor classifies one stream-scoped frame and returns its live bridge. A
391+// frame for a retired stream, or one settled between the tracker check and the
392+// lookup, yields no bridge and no error; a frame for a stream that was never
393+// allocated, or before it was confirmed open, is a peer protocol violation.
394+func (s *serverSession) streamFor(id ports.BrokerStreamID) (*serverStream, error) {
395+ disposition, err := s.conn.StreamData(id)
396+ if err != nil {
397+ return nil, errors.Join(ErrProtocol, err)
398+ }
399+ if disposition == brokerwire.StreamDiscarded {
400+ return nil, nil
379401 }
402+ return s.lookupStream(id), nil
380403 }
381404
382405 // clientStream is the client-side half of one logical stream: the sessionwire
@@ -407,7 +430,7 @@ func newClientStream(c *client, id ports.BrokerStreamID) (*clientStream, error)
407430 opened: make(chan error, 1),
408431 done: make(chan struct{}),
409432 }
410- st.pipe = newStreamPipe(c.cfg.StreamInboundChunks, c.cfg.StreamInboundBytes, st.sendChunk)
433+ st.pipe = newStreamPipe(st.sendChunk, st.grantCredit)
411434 st.carriage = newCarriage(st.pipe)
412435 st.ClientConnection = sessionwire.NewClientConnection(st.carriage)
413436 if st.ClientConnection == nil {
@@ -417,7 +440,7 @@ func newClientStream(c *client, id ports.BrokerStreamID) (*clientStream, error)
417440 }
418441
419442 // sendChunk splits one outbound client byte slice under the negotiated stream
420-// chunk ceiling.
443+// chunk ceiling, waiting for the broker's credit before each frame.
421444 func (st *clientStream) sendChunk(data []byte) error {
422445 ceiling := int(st.client.ceilings.StreamChunkLimit)
423446 if ceiling <= 0 {
@@ -425,6 +448,9 @@ func (st *clientStream) sendChunk(data []byte) error {
425448 }
426449 for len(data) > 0 {
427450 n := min(len(data), ceiling)
451+ if err := st.pipe.reserve(n); err != nil {
452+ return err
453+ }
428454 if err := st.client.send(brokerwire.ClientStreamData{
429455 Epoch: st.client.scope.Epoch, Connection: st.client.scope.Connection, Stream: st.id, Data: data[:n],
430456 }); err != nil {
@@ -435,6 +461,15 @@ func (st *clientStream) sendChunk(data []byte) error {
435461 return nil
436462 }
437463
464+// grantCredit returns consumed inbound credit to the broker. It is written
465+// synchronously because a dropped grant would stall the stream forever; the
466+// write never waits long, since the broker's reader never blocks on a stream.
467+func (st *clientStream) grantCredit(credit uint64) error {
468+ return st.client.send(brokerwire.StreamWindowUpdate{
469+ Epoch: st.client.scope.Epoch, Connection: st.client.scope.Connection, Stream: st.id, Credit: credit,
470+ })
471+}
472+
438473 // deliver accepts one inbound server chunk.
439474 func (st *clientStream) deliver(chunk []byte) error { return st.pipe.deliver(chunk) }
440475
@@ -42,13 +42,15 @@ func newServerStream(s *serverSession, id ports.BrokerStreamID, core ports.Broke
42 return nil, ErrConfig42 return nil, ErrConfig
43 }43 }
44 st := &serverStream{session: s, id: id, core: core, done: make(chan struct{})}44 st := &serverStream{session: s, id: id, core: core, done: make(chan struct{})}
45- st.pipe = newStreamPipe(s.cfg.StreamInboundChunks, s.cfg.StreamInboundBytes, st.sendChunk)45+ st.pipe = newStreamPipe(st.sendChunk, st.grantCredit)
46 st.carriage = newCarriage(st.pipe)46 st.carriage = newCarriage(st.pipe)
47 return st, nil47 return st, nil
48 }48 }
49 49
50 // sendChunk splits one outbound byte slice under the negotiated stream chunk50 // sendChunk splits one outbound byte slice under the negotiated stream chunk
51-// ceiling and writes each frame in order.51+// ceiling and writes each frame in order, waiting for the client's credit
52+// before each one: a client that is not reading slows this relay, and through
53+// the daemon link the daemon, instead of losing its stream.
52 func (st *serverStream) sendChunk(data []byte) error {54 func (st *serverStream) sendChunk(data []byte) error {
53 ceiling := int(st.session.ceilings.StreamChunkLimit)55 ceiling := int(st.session.ceilings.StreamChunkLimit)
54 if ceiling <= 0 {56 if ceiling <= 0 {
@@ -56,6 +58,9 @@ func (st *serverStream) sendChunk(data []byte) error {
56 }58 }
57 for len(data) > 0 {59 for len(data) > 0 {
58 n := min(len(data), ceiling)60 n := min(len(data), ceiling)
61+ if err := st.pipe.reserve(n); err != nil {
62+ return err
63+ }
59 if err := st.session.send(brokerwire.ServerStreamData{64 if err := st.session.send(brokerwire.ServerStreamData{
60 Epoch: st.session.epoch, Connection: st.session.scope.Connection, Stream: st.id, Data: data[:n],65 Epoch: st.session.epoch, Connection: st.session.scope.Connection, Stream: st.id, Data: data[:n],
61 }); err != nil {66 }); err != nil {
@@ -66,6 +71,13 @@ func (st *serverStream) sendChunk(data []byte) error {
66 return nil71 return nil
67 }72 }
68 73
74+// grantCredit returns consumed inbound credit to the client.
75+func (st *serverStream) grantCredit(credit uint64) error {
76+ return st.session.send(brokerwire.StreamWindowUpdate{
77+ Epoch: st.session.epoch, Connection: st.session.scope.Connection, Stream: st.id, Credit: credit,
78+ })
79+}
80+
69 // deliver accepts one inbound chunk from the connection reader.81 // deliver accepts one inbound chunk from the connection reader.
70 func (st *serverStream) deliver(chunk []byte) error { return st.pipe.deliver(chunk) }82 func (st *serverStream) deliver(chunk []byte) error { return st.pipe.deliver(chunk) }
71 83
@@ -347,36 +359,47 @@ func (s *serverSession) closeStreamByPeer(id ports.BrokerStreamID) {
347 _ = s.core.CloseStream(s.scope.Connection, id)359 _ = s.core.CloseStream(s.scope.Connection, id)
348 }360 }
349 361
350-// deliverStreamData routes one inbound client chunk to its bridge. Backpressure362+// deliverStreamData routes one inbound client chunk to its bridge. Data beyond
351-// settles only that stream; a chunk for an identity the peer never opened is a363+// the granted credit settles only that stream; a chunk for an identity the peer
352-// protocol violation.364+// never opened is a protocol violation.
353 func (s *serverSession) deliverStreamData(m brokerwire.ClientStreamData) error {365 func (s *serverSession) deliverStreamData(m brokerwire.ClientStreamData) error {
354- disposition, err := s.conn.StreamData(m.Stream)366+ st, err := s.streamFor(m.Stream)
355- if err != nil {367+ if st == nil || err != nil {
356- // Stream data for a stream that was never allocated, or before it was368+ return err
357- // confirmed open, is a peer protocol violation.
358- return errors.Join(ErrProtocol, err)
359 }369 }
360- if disposition == brokerwire.StreamDiscarded {370+ if err := st.deliver(m.Data); errors.Is(err, ErrStreamCredit) {
361- return nil371+ s.settleStream(st, ErrStreamCredit)
362 }372 }
363- st := s.lookupStream(m.Stream)373+ // Any other error means the stream already reached its terminal outcome;
364- if st == nil {374+ // its data is discarded.
365- // The bridge was settled between the tracker check and the lookup (a375+ return nil
366- // stream-local failure won the race); the chunk is discarded with it.376+}
367- return nil377+
378+// grantStreamCredit applies one client credit grant to its bridge.
379+func (s *serverSession) grantStreamCredit(m brokerwire.StreamWindowUpdate) error {
380+ st, err := s.streamFor(m.Stream)
381+ if st == nil || err != nil {
382+ return err
368 }383 }
369- switch err := st.deliver(m.Data); {384+ if err := st.pipe.granted(m.Credit); err != nil {
370- case err == nil:385+ s.settleStream(st, err)
371- return nil386+ }
372- case errors.Is(err, ErrStreamBackpressure):387+ return nil
373- s.settleStream(st, ErrStreamBackpressure)388+}
374- return nil389+
375- default:390+// streamFor classifies one stream-scoped frame and returns its live bridge. A
376- // The stream already reached its terminal outcome; its data is391+// frame for a retired stream, or one settled between the tracker check and the
377- // discarded.392+// lookup, yields no bridge and no error; a frame for a stream that was never
378- return nil393+// allocated, or before it was confirmed open, is a peer protocol violation.
394+func (s *serverSession) streamFor(id ports.BrokerStreamID) (*serverStream, error) {
395+ disposition, err := s.conn.StreamData(id)
396+ if err != nil {
397+ return nil, errors.Join(ErrProtocol, err)
398+ }
399+ if disposition == brokerwire.StreamDiscarded {
400+ return nil, nil
379 }401 }
402+ return s.lookupStream(id), nil
380 }403 }
381 404
382 // clientStream is the client-side half of one logical stream: the sessionwire405 // clientStream is the client-side half of one logical stream: the sessionwire
@@ -407,7 +430,7 @@ func newClientStream(c *client, id ports.BrokerStreamID) (*clientStream, error)
407 opened: make(chan error, 1),430 opened: make(chan error, 1),
408 done: make(chan struct{}),431 done: make(chan struct{}),
409 }432 }
410- st.pipe = newStreamPipe(c.cfg.StreamInboundChunks, c.cfg.StreamInboundBytes, st.sendChunk)433+ st.pipe = newStreamPipe(st.sendChunk, st.grantCredit)
411 st.carriage = newCarriage(st.pipe)434 st.carriage = newCarriage(st.pipe)
412 st.ClientConnection = sessionwire.NewClientConnection(st.carriage)435 st.ClientConnection = sessionwire.NewClientConnection(st.carriage)
413 if st.ClientConnection == nil {436 if st.ClientConnection == nil {
@@ -417,7 +440,7 @@ func newClientStream(c *client, id ports.BrokerStreamID) (*clientStream, error)
417 }440 }
418 441
419 // sendChunk splits one outbound client byte slice under the negotiated stream442 // sendChunk splits one outbound client byte slice under the negotiated stream
420-// chunk ceiling.443+// chunk ceiling, waiting for the broker's credit before each frame.
421 func (st *clientStream) sendChunk(data []byte) error {444 func (st *clientStream) sendChunk(data []byte) error {
422 ceiling := int(st.client.ceilings.StreamChunkLimit)445 ceiling := int(st.client.ceilings.StreamChunkLimit)
423 if ceiling <= 0 {446 if ceiling <= 0 {
@@ -425,6 +448,9 @@ func (st *clientStream) sendChunk(data []byte) error {
425 }448 }
426 for len(data) > 0 {449 for len(data) > 0 {
427 n := min(len(data), ceiling)450 n := min(len(data), ceiling)
451+ if err := st.pipe.reserve(n); err != nil {
452+ return err
453+ }
428 if err := st.client.send(brokerwire.ClientStreamData{454 if err := st.client.send(brokerwire.ClientStreamData{
429 Epoch: st.client.scope.Epoch, Connection: st.client.scope.Connection, Stream: st.id, Data: data[:n],455 Epoch: st.client.scope.Epoch, Connection: st.client.scope.Connection, Stream: st.id, Data: data[:n],
430 }); err != nil {456 }); err != nil {
@@ -435,6 +461,15 @@ func (st *clientStream) sendChunk(data []byte) error {
435 return nil461 return nil
436 }462 }
437 463
464+// grantCredit returns consumed inbound credit to the broker. It is written
465+// synchronously because a dropped grant would stall the stream forever; the
466+// write never waits long, since the broker's reader never blocks on a stream.
467+func (st *clientStream) grantCredit(credit uint64) error {
468+ return st.client.send(brokerwire.StreamWindowUpdate{
469+ Epoch: st.client.scope.Epoch, Connection: st.client.scope.Connection, Stream: st.id, Credit: credit,
470+ })
471+}
472+
438 // deliver accepts one inbound server chunk.473 // deliver accepts one inbound server chunk.
439 func (st *clientStream) deliver(chunk []byte) error { return st.pipe.deliver(chunk) }474 func (st *clientStream) deliver(chunk []byte) error { return st.pipe.deliver(chunk) }
440 475
M internal/adapters/brokerwire/codec.go +53 -0
@@ -241,6 +241,17 @@ func encodeClientEnvelope(message ClientMessage, maxChunkBytes uint64) (*wire.Br
241241 return nil, ErrInvalidMessage
242242 }
243243 return encodeClientEnvelope(*m, maxChunkBytes)
244+ case StreamWindowUpdate:
245+ converted, err := streamWindowUpdateToWire(m)
246+ if err != nil {
247+ return nil, err
248+ }
249+ return &wire.BrokerClientEnvelope{Payload: &wire.BrokerClientEnvelope_StreamWindowUpdate{StreamWindowUpdate: converted}}, nil
250+ case *StreamWindowUpdate:
251+ if m == nil {
252+ return nil, ErrInvalidMessage
253+ }
254+ return encodeClientEnvelope(*m, maxChunkBytes)
244255 case StartPreview:
245256 converted, err := startPreviewToWire(m)
246257 if err != nil {
@@ -308,6 +319,8 @@ func decodeClientEnvelope(envelope *wire.BrokerClientEnvelope, maxChunkBytes uin
308319 return nil, ErrInvalidMessage
309320 }
310321 return CloseStream{Epoch: epoch, Connection: connection, Stream: stream}, nil
322+ case *wire.BrokerClientEnvelope_StreamWindowUpdate:
323+ return streamWindowUpdateFromWire(payload.StreamWindowUpdate)
311324 case *wire.BrokerClientEnvelope_StartPreview:
312325 return startPreviewFromWire(payload.StartPreview)
313326 case *wire.BrokerClientEnvelope_CancelPreview:
@@ -707,6 +720,33 @@ func openStreamFromWire(message *wire.OpenStream) (OpenStream, error) {
707720 return candidate, nil
708721 }
709722
723+// streamWindowUpdateToWire refuses a zero or above-window grant: credit is
724+// returned only for consumed data, so a valid grant never exceeds one window.
725+func streamWindowUpdateToWire(m StreamWindowUpdate) (*wire.StreamWindowUpdate, error) {
726+ if m.Epoch == 0 || m.Connection.Validate() != nil || m.Stream.Validate() != nil {
727+ return nil, ErrInvalidMessage
728+ }
729+ if m.Credit == 0 || m.Credit > StreamWindowBytes {
730+ return nil, ErrInvalidMessage
731+ }
732+ return &wire.StreamWindowUpdate{Ref: refToWire(m.Epoch, m.Connection, m.Stream), Credit: m.Credit}, nil
733+}
734+
735+func streamWindowUpdateFromWire(message *wire.StreamWindowUpdate) (StreamWindowUpdate, error) {
736+ if message == nil {
737+ return StreamWindowUpdate{}, ErrInvalidMessage
738+ }
739+ epoch, connection, stream, err := refFromWire(message.GetRef())
740+ if err != nil {
741+ return StreamWindowUpdate{}, ErrInvalidMessage
742+ }
743+ credit := message.GetCredit()
744+ if credit == 0 || credit > StreamWindowBytes {
745+ return StreamWindowUpdate{}, ErrInvalidMessage
746+ }
747+ return StreamWindowUpdate{Epoch: epoch, Connection: connection, Stream: stream, Credit: credit}, nil
748+}
749+
710750 func clientStreamDataToWire(m ClientStreamData, maxChunkBytes uint64) (*wire.ClientStreamData, error) {
711751 if m.Epoch == 0 {
712752 return nil, ErrInvalidMessage
@@ -828,6 +868,17 @@ func encodeServerEnvelope(message ServerMessage, maxChunkBytes uint64) (*wire.Br
828868 return nil, ErrInvalidMessage
829869 }
830870 return encodeServerEnvelope(*m, maxChunkBytes)
871+ case StreamWindowUpdate:
872+ converted, err := streamWindowUpdateToWire(m)
873+ if err != nil {
874+ return nil, err
875+ }
876+ return &wire.BrokerServerEnvelope{Payload: &wire.BrokerServerEnvelope_StreamWindowUpdate{StreamWindowUpdate: converted}}, nil
877+ case *StreamWindowUpdate:
878+ if m == nil {
879+ return nil, ErrInvalidMessage
880+ }
881+ return encodeServerEnvelope(*m, maxChunkBytes)
831882 case StreamClosed:
832883 converted, err := streamClosedToWire(m)
833884 if err != nil {
@@ -929,6 +980,8 @@ func decodeServerEnvelope(envelope *wire.BrokerServerEnvelope, maxChunkBytes uin
929980 return serverStreamDataFromWire(payload.ServerStreamData, maxChunkBytes)
930981 case *wire.BrokerServerEnvelope_StreamClosed:
931982 return streamClosedFromWire(payload.StreamClosed)
983+ case *wire.BrokerServerEnvelope_StreamWindowUpdate:
984+ return streamWindowUpdateFromWire(payload.StreamWindowUpdate)
932985 case *wire.BrokerServerEnvelope_Progress:
933986 return progressFromWire(payload.Progress)
934987 case *wire.BrokerServerEnvelope_BrokerErrorMessage:
@@ -241,6 +241,17 @@ func encodeClientEnvelope(message ClientMessage, maxChunkBytes uint64) (*wire.Br
241 return nil, ErrInvalidMessage241 return nil, ErrInvalidMessage
242 }242 }
243 return encodeClientEnvelope(*m, maxChunkBytes)243 return encodeClientEnvelope(*m, maxChunkBytes)
244+ case StreamWindowUpdate:
245+ converted, err := streamWindowUpdateToWire(m)
246+ if err != nil {
247+ return nil, err
248+ }
249+ return &wire.BrokerClientEnvelope{Payload: &wire.BrokerClientEnvelope_StreamWindowUpdate{StreamWindowUpdate: converted}}, nil
250+ case *StreamWindowUpdate:
251+ if m == nil {
252+ return nil, ErrInvalidMessage
253+ }
254+ return encodeClientEnvelope(*m, maxChunkBytes)
244 case StartPreview:255 case StartPreview:
245 converted, err := startPreviewToWire(m)256 converted, err := startPreviewToWire(m)
246 if err != nil {257 if err != nil {
@@ -308,6 +319,8 @@ func decodeClientEnvelope(envelope *wire.BrokerClientEnvelope, maxChunkBytes uin
308 return nil, ErrInvalidMessage319 return nil, ErrInvalidMessage
309 }320 }
310 return CloseStream{Epoch: epoch, Connection: connection, Stream: stream}, nil321 return CloseStream{Epoch: epoch, Connection: connection, Stream: stream}, nil
322+ case *wire.BrokerClientEnvelope_StreamWindowUpdate:
323+ return streamWindowUpdateFromWire(payload.StreamWindowUpdate)
311 case *wire.BrokerClientEnvelope_StartPreview:324 case *wire.BrokerClientEnvelope_StartPreview:
312 return startPreviewFromWire(payload.StartPreview)325 return startPreviewFromWire(payload.StartPreview)
313 case *wire.BrokerClientEnvelope_CancelPreview:326 case *wire.BrokerClientEnvelope_CancelPreview:
@@ -707,6 +720,33 @@ func openStreamFromWire(message *wire.OpenStream) (OpenStream, error) {
707 return candidate, nil720 return candidate, nil
708 }721 }
709 722
723+// streamWindowUpdateToWire refuses a zero or above-window grant: credit is
724+// returned only for consumed data, so a valid grant never exceeds one window.
725+func streamWindowUpdateToWire(m StreamWindowUpdate) (*wire.StreamWindowUpdate, error) {
726+ if m.Epoch == 0 || m.Connection.Validate() != nil || m.Stream.Validate() != nil {
727+ return nil, ErrInvalidMessage
728+ }
729+ if m.Credit == 0 || m.Credit > StreamWindowBytes {
730+ return nil, ErrInvalidMessage
731+ }
732+ return &wire.StreamWindowUpdate{Ref: refToWire(m.Epoch, m.Connection, m.Stream), Credit: m.Credit}, nil
733+}
734+
735+func streamWindowUpdateFromWire(message *wire.StreamWindowUpdate) (StreamWindowUpdate, error) {
736+ if message == nil {
737+ return StreamWindowUpdate{}, ErrInvalidMessage
738+ }
739+ epoch, connection, stream, err := refFromWire(message.GetRef())
740+ if err != nil {
741+ return StreamWindowUpdate{}, ErrInvalidMessage
742+ }
743+ credit := message.GetCredit()
744+ if credit == 0 || credit > StreamWindowBytes {
745+ return StreamWindowUpdate{}, ErrInvalidMessage
746+ }
747+ return StreamWindowUpdate{Epoch: epoch, Connection: connection, Stream: stream, Credit: credit}, nil
748+}
749+
710 func clientStreamDataToWire(m ClientStreamData, maxChunkBytes uint64) (*wire.ClientStreamData, error) {750 func clientStreamDataToWire(m ClientStreamData, maxChunkBytes uint64) (*wire.ClientStreamData, error) {
711 if m.Epoch == 0 {751 if m.Epoch == 0 {
712 return nil, ErrInvalidMessage752 return nil, ErrInvalidMessage
@@ -828,6 +868,17 @@ func encodeServerEnvelope(message ServerMessage, maxChunkBytes uint64) (*wire.Br
828 return nil, ErrInvalidMessage868 return nil, ErrInvalidMessage
829 }869 }
830 return encodeServerEnvelope(*m, maxChunkBytes)870 return encodeServerEnvelope(*m, maxChunkBytes)
871+ case StreamWindowUpdate:
872+ converted, err := streamWindowUpdateToWire(m)
873+ if err != nil {
874+ return nil, err
875+ }
876+ return &wire.BrokerServerEnvelope{Payload: &wire.BrokerServerEnvelope_StreamWindowUpdate{StreamWindowUpdate: converted}}, nil
877+ case *StreamWindowUpdate:
878+ if m == nil {
879+ return nil, ErrInvalidMessage
880+ }
881+ return encodeServerEnvelope(*m, maxChunkBytes)
831 case StreamClosed:882 case StreamClosed:
832 converted, err := streamClosedToWire(m)883 converted, err := streamClosedToWire(m)
833 if err != nil {884 if err != nil {
@@ -929,6 +980,8 @@ func decodeServerEnvelope(envelope *wire.BrokerServerEnvelope, maxChunkBytes uin
929 return serverStreamDataFromWire(payload.ServerStreamData, maxChunkBytes)980 return serverStreamDataFromWire(payload.ServerStreamData, maxChunkBytes)
930 case *wire.BrokerServerEnvelope_StreamClosed:981 case *wire.BrokerServerEnvelope_StreamClosed:
931 return streamClosedFromWire(payload.StreamClosed)982 return streamClosedFromWire(payload.StreamClosed)
983+ case *wire.BrokerServerEnvelope_StreamWindowUpdate:
984+ return streamWindowUpdateFromWire(payload.StreamWindowUpdate)
932 case *wire.BrokerServerEnvelope_Progress:985 case *wire.BrokerServerEnvelope_Progress:
933 return progressFromWire(payload.Progress)986 return progressFromWire(payload.Progress)
934 case *wire.BrokerServerEnvelope_BrokerErrorMessage:987 case *wire.BrokerServerEnvelope_BrokerErrorMessage:
M internal/adapters/brokerwire/limits.go +14 -0
@@ -39,8 +39,22 @@ const (
3939 // MaxStreamChunkBytes is the largest legal stream chunk ceiling:
4040 // 64 KiB per opaque stream frame.
4141 MaxStreamChunkBytes uint64 = 64 << 10
42+
43+ // StreamWindowBytes is the stream-data credit each side of one logical
44+ // stream grants its peer per direction. A sender spends StreamChunkCredit
45+ // per data frame and waits when it has too little, so the receiver never
46+ // queues more than this per stream; StreamWindowUpdate returns the credit
47+ // of consumed frames.
48+ StreamWindowBytes uint64 = 4 << 20
49+ // StreamChunkCreditOverhead is the fixed credit one data frame costs on top
50+ // of its payload, so a burst of tiny frames is bounded in count as well.
51+ StreamChunkCreditOverhead uint64 = 64
4252 )
4353
54+// StreamChunkCredit is the flow-control cost of one stream data frame of n
55+// payload bytes.
56+func StreamChunkCredit(n int) uint64 { return uint64(n) + StreamChunkCreditOverhead }
57+
4458 // Ceilings are the immutable per-connection ceilings negotiated once by the
4559 // broker preamble. MaxReceiveEnvelopeBytes bounds every envelope this side
4660 // accepts; StreamChunkLimit bounds one opaque stream data frame in either
@@ -39,8 +39,22 @@ const (
39 // MaxStreamChunkBytes is the largest legal stream chunk ceiling:39 // MaxStreamChunkBytes is the largest legal stream chunk ceiling:
40 // 64 KiB per opaque stream frame.40 // 64 KiB per opaque stream frame.
41 MaxStreamChunkBytes uint64 = 64 << 1041 MaxStreamChunkBytes uint64 = 64 << 10
42+
43+ // StreamWindowBytes is the stream-data credit each side of one logical
44+ // stream grants its peer per direction. A sender spends StreamChunkCredit
45+ // per data frame and waits when it has too little, so the receiver never
46+ // queues more than this per stream; StreamWindowUpdate returns the credit
47+ // of consumed frames.
48+ StreamWindowBytes uint64 = 4 << 20
49+ // StreamChunkCreditOverhead is the fixed credit one data frame costs on top
50+ // of its payload, so a burst of tiny frames is bounded in count as well.
51+ StreamChunkCreditOverhead uint64 = 64
42 )52 )
43 53
54+// StreamChunkCredit is the flow-control cost of one stream data frame of n
55+// payload bytes.
56+func StreamChunkCredit(n int) uint64 { return uint64(n) + StreamChunkCreditOverhead }
57+
44 // Ceilings are the immutable per-connection ceilings negotiated once by the58 // Ceilings are the immutable per-connection ceilings negotiated once by the
45 // broker preamble. MaxReceiveEnvelopeBytes bounds every envelope this side59 // broker preamble. MaxReceiveEnvelopeBytes bounds every envelope this side
46 // accepts; StreamChunkLimit bounds one opaque stream data frame in either60 // accepts; StreamChunkLimit bounds one opaque stream data frame in either
M internal/adapters/brokerwire/messages.go +13 -0
@@ -165,6 +165,19 @@ type CloseStream struct {
165165
166166 func (CloseStream) brokerClientMessage() {}
167167
168+// StreamWindowUpdate grants the peer Credit more stream-data bytes on one
169+// logical stream after the receiver consumed them. It travels in both
170+// directions: each side grants credit for the data it receives.
171+type StreamWindowUpdate struct {
172+ Epoch ports.BrokerEpoch
173+ Connection ports.BrokerConnectionID
174+ Stream ports.BrokerStreamID
175+ Credit uint64
176+}
177+
178+func (StreamWindowUpdate) brokerClientMessage() {}
179+func (StreamWindowUpdate) brokerServerMessage() {}
180+
168181 // StartPreview starts or replaces one connection-scoped live preview.
169182 // Generation is the connection-scoped preview authority; Route names the
170183 // observed daemon (the broker allocates the stream) and Preview is the bounded
@@ -165,6 +165,19 @@ type CloseStream struct {
165 165
166 func (CloseStream) brokerClientMessage() {}166 func (CloseStream) brokerClientMessage() {}
167 167
168+// StreamWindowUpdate grants the peer Credit more stream-data bytes on one
169+// logical stream after the receiver consumed them. It travels in both
170+// directions: each side grants credit for the data it receives.
171+type StreamWindowUpdate struct {
172+ Epoch ports.BrokerEpoch
173+ Connection ports.BrokerConnectionID
174+ Stream ports.BrokerStreamID
175+ Credit uint64
176+}
177+
178+func (StreamWindowUpdate) brokerClientMessage() {}
179+func (StreamWindowUpdate) brokerServerMessage() {}
180+
168 // StartPreview starts or replaces one connection-scoped live preview.181 // StartPreview starts or replaces one connection-scoped live preview.
169 // Generation is the connection-scoped preview authority; Route names the182 // Generation is the connection-scoped preview authority; Route names the
170 // observed daemon (the broker allocates the stream) and Preview is the bounded183 // observed daemon (the broker allocates the stream) and Preview is the bounded
M internal/adapters/brokerwire/state.go +7 -0
@@ -486,6 +486,13 @@ func (c *Connection) StreamData(stream ports.BrokerStreamID) (StreamDisposition,
486486 return c.streams.Data(c.scope, stream)
487487 }
488488
489+// StreamWindowUpdate classifies one credit grant for a stream exactly like
490+// stream data: legal while open, discarded once retired. The ready check and
491+// the tracker lookup share one connection lock.
492+func (c *Connection) StreamWindowUpdate(stream ports.BrokerStreamID) (StreamDisposition, error) {
493+ return c.StreamData(stream)
494+}
495+
489496 // StreamProgress reports one phase of an in-flight stream operation. The
490497 // ready check and the tracker mutation share one connection lock.
491498 func (c *Connection) StreamProgress(stream ports.BrokerStreamID) (StreamDisposition, error) {
@@ -486,6 +486,13 @@ func (c *Connection) StreamData(stream ports.BrokerStreamID) (StreamDisposition,
486 return c.streams.Data(c.scope, stream)486 return c.streams.Data(c.scope, stream)
487 }487 }
488 488
489+// StreamWindowUpdate classifies one credit grant for a stream exactly like
490+// stream data: legal while open, discarded once retired. The ready check and
491+// the tracker lookup share one connection lock.
492+func (c *Connection) StreamWindowUpdate(stream ports.BrokerStreamID) (StreamDisposition, error) {
493+ return c.StreamData(stream)
494+}
495+
489 // StreamProgress reports one phase of an in-flight stream operation. The496 // StreamProgress reports one phase of an in-flight stream operation. The
490 // ready check and the tracker mutation share one connection lock.497 // ready check and the tracker mutation share one connection lock.
491 func (c *Connection) StreamProgress(stream ports.BrokerStreamID) (StreamDisposition, error) {498 func (c *Connection) StreamProgress(stream ports.BrokerStreamID) (StreamDisposition, error) {
M internal/protocol/session.go +1 -1
@@ -17,7 +17,7 @@ import (
1717 // daemonmux physical preamble conversation (multiplex.proto), whose
1818 // negotiated ceilings and accepted daemon binding ride the same wire
1919 // version as the session and broker conversations.
20-const Version uint16 = 65
20+const Version uint16 = 66
2121
2222 // HandshakeTimeout bounds every transport handshake from connect through the
2323 // first committed publication. It excludes the preceding client-local
@@ -17,7 +17,7 @@ import (
17 // daemonmux physical preamble conversation (multiplex.proto), whose17 // daemonmux physical preamble conversation (multiplex.proto), whose
18 // negotiated ceilings and accepted daemon binding ride the same wire18 // negotiated ceilings and accepted daemon binding ride the same wire
19 // version as the session and broker conversations.19 // version as the session and broker conversations.
20-const Version uint16 = 6520+const Version uint16 = 66
21 21
22 // HandshakeTimeout bounds every transport handshake from connect through the22 // HandshakeTimeout bounds every transport handshake from connect through the
23 // first committed publication. It excludes the preceding client-local23 // first committed publication. It excludes the preceding client-local
M internal/protocol/session_test.go +1 -1
@@ -10,7 +10,7 @@ import (
1010 )
1111
1212 func TestVersionRemainsWireCompatible(t *testing.T) {
13- require.Equal(t, uint16(65), Version)
13+ require.Equal(t, uint16(66), Version)
1414 require.Equal(t, (16<<20)-407, MaxOutputDataLen)
1515 }
1616
@@ -10,7 +10,7 @@ import (
10 )10 )
11 11
12 func TestVersionRemainsWireCompatible(t *testing.T) {12 func TestVersionRemainsWireCompatible(t *testing.T) {
13- require.Equal(t, uint16(65), Version)13+ require.Equal(t, uint16(66), Version)
14 require.Equal(t, (16<<20)-407, MaxOutputDataLen)14 require.Equal(t, (16<<20)-407, MaxOutputDataLen)
15 }15 }
16 16
M internal/protocol/wire/broker.pb.go +262 -163
@@ -390,6 +390,7 @@ type BrokerClientEnvelope struct {
390390 // *BrokerClientEnvelope_UpdateHostPolicy
391391 // *BrokerClientEnvelope_StartPreview
392392 // *BrokerClientEnvelope_CancelPreview
393+ // *BrokerClientEnvelope_StreamWindowUpdate
393394 Payload isBrokerClientEnvelope_Payload `protobuf_oneof:"payload"`
394395 unknownFields protoimpl.UnknownFields
395396 sizeCache protoimpl.SizeCache
@@ -549,6 +550,15 @@ func (x *BrokerClientEnvelope) GetCancelPreview() *CancelPreview {
549550 return nil
550551 }
551552
553+func (x *BrokerClientEnvelope) GetStreamWindowUpdate() *StreamWindowUpdate {
554+ if x != nil {
555+ if x, ok := x.Payload.(*BrokerClientEnvelope_StreamWindowUpdate); ok {
556+ return x.StreamWindowUpdate
557+ }
558+ }
559+ return nil
560+}
561+
552562 type isBrokerClientEnvelope_Payload interface {
553563 isBrokerClientEnvelope_Payload()
554564 }
@@ -605,6 +615,10 @@ type BrokerClientEnvelope_CancelPreview struct {
605615 CancelPreview *CancelPreview `protobuf:"bytes,113,opt,name=cancel_preview,json=cancelPreview,proto3,oneof"`
606616 }
607617
618+type BrokerClientEnvelope_StreamWindowUpdate struct {
619+ StreamWindowUpdate *StreamWindowUpdate `protobuf:"bytes,114,opt,name=stream_window_update,json=streamWindowUpdate,proto3,oneof"`
620+}
621+
608622 func (*BrokerClientEnvelope_Register) isBrokerClientEnvelope_Payload() {}
609623
610624 func (*BrokerClientEnvelope_Subscribe) isBrokerClientEnvelope_Payload() {}
@@ -631,6 +645,8 @@ func (*BrokerClientEnvelope_StartPreview) isBrokerClientEnvelope_Payload() {}
631645
632646 func (*BrokerClientEnvelope_CancelPreview) isBrokerClientEnvelope_Payload() {}
633647
648+func (*BrokerClientEnvelope_StreamWindowUpdate) isBrokerClientEnvelope_Payload() {}
649+
634650 // BrokerServerEnvelope is the closed server-to-client broker union. Exactly
635651 // one variant must be set per envelope.
636652 type BrokerServerEnvelope struct {
@@ -647,6 +663,7 @@ type BrokerServerEnvelope struct {
647663 // *BrokerServerEnvelope_BrokerErrorMessage
648664 // *BrokerServerEnvelope_Shutdown
649665 // *BrokerServerEnvelope_PreviewPublication
666+ // *BrokerServerEnvelope_StreamWindowUpdate
650667 Payload isBrokerServerEnvelope_Payload `protobuf_oneof:"payload"`
651668 unknownFields protoimpl.UnknownFields
652669 sizeCache protoimpl.SizeCache
@@ -779,6 +796,15 @@ func (x *BrokerServerEnvelope) GetPreviewPublication() *PreviewPublication {
779796 return nil
780797 }
781798
799+func (x *BrokerServerEnvelope) GetStreamWindowUpdate() *StreamWindowUpdate {
800+ if x != nil {
801+ if x, ok := x.Payload.(*BrokerServerEnvelope_StreamWindowUpdate); ok {
802+ return x.StreamWindowUpdate
803+ }
804+ }
805+ return nil
806+}
807+
782808 type isBrokerServerEnvelope_Payload interface {
783809 isBrokerServerEnvelope_Payload()
784810 }
@@ -823,6 +849,10 @@ type BrokerServerEnvelope_PreviewPublication struct {
823849 PreviewPublication *PreviewPublication `protobuf:"bytes,210,opt,name=preview_publication,json=previewPublication,proto3,oneof"`
824850 }
825851
852+type BrokerServerEnvelope_StreamWindowUpdate struct {
853+ StreamWindowUpdate *StreamWindowUpdate `protobuf:"bytes,211,opt,name=stream_window_update,json=streamWindowUpdate,proto3,oneof"`
854+}
855+
826856 func (*BrokerServerEnvelope_Registered) isBrokerServerEnvelope_Payload() {}
827857
828858 func (*BrokerServerEnvelope_SnapshotPart) isBrokerServerEnvelope_Payload() {}
@@ -843,6 +873,8 @@ func (*BrokerServerEnvelope_Shutdown) isBrokerServerEnvelope_Payload() {}
843873
844874 func (*BrokerServerEnvelope_PreviewPublication) isBrokerServerEnvelope_Payload() {}
845875
876+func (*BrokerServerEnvelope_StreamWindowUpdate) isBrokerServerEnvelope_Payload() {}
877+
846878 // Register opens one client connection to the broker.
847879 type Register struct {
848880 state protoimpl.MessageState `protogen:"open.v1"`
@@ -1563,6 +1595,62 @@ func (x *CloseStream) GetRef() *BrokerStreamRef {
15631595 return nil
15641596 }
15651597
1598+// StreamWindowUpdate grants the peer credit to send more stream data on one
1599+// logical stream: the receiver consumed that much of its stream window. Each
1600+// direction of a stream has its own window, so a client grants credit for
1601+// ServerStreamData and the server grants credit for ClientStreamData.
1602+type StreamWindowUpdate struct {
1603+ state protoimpl.MessageState `protogen:"open.v1"`
1604+ Ref *BrokerStreamRef `protobuf:"bytes,1,opt,name=ref,proto3" json:"ref,omitempty"`
1605+ Credit uint64 `protobuf:"varint,2,opt,name=credit,proto3" json:"credit,omitempty"`
1606+ unknownFields protoimpl.UnknownFields
1607+ sizeCache protoimpl.SizeCache
1608+}
1609+
1610+func (x *StreamWindowUpdate) Reset() {
1611+ *x = StreamWindowUpdate{}
1612+ mi := &file_broker_proto_msgTypes[18]
1613+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
1614+ ms.StoreMessageInfo(mi)
1615+}
1616+
1617+func (x *StreamWindowUpdate) String() string {
1618+ return protoimpl.X.MessageStringOf(x)
1619+}
1620+
1621+func (*StreamWindowUpdate) ProtoMessage() {}
1622+
1623+func (x *StreamWindowUpdate) ProtoReflect() protoreflect.Message {
1624+ mi := &file_broker_proto_msgTypes[18]
1625+ if x != nil {
1626+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
1627+ if ms.LoadMessageInfo() == nil {
1628+ ms.StoreMessageInfo(mi)
1629+ }
1630+ return ms
1631+ }
1632+ return mi.MessageOf(x)
1633+}
1634+
1635+// Deprecated: Use StreamWindowUpdate.ProtoReflect.Descriptor instead.
1636+func (*StreamWindowUpdate) Descriptor() ([]byte, []int) {
1637+ return file_broker_proto_rawDescGZIP(), []int{18}
1638+}
1639+
1640+func (x *StreamWindowUpdate) GetRef() *BrokerStreamRef {
1641+ if x != nil {
1642+ return x.Ref
1643+ }
1644+ return nil
1645+}
1646+
1647+func (x *StreamWindowUpdate) GetCredit() uint64 {
1648+ if x != nil {
1649+ return x.Credit
1650+ }
1651+ return 0
1652+}
1653+
15661654 // Registered confirms one accepted client connection and its assigned scope.
15671655 type Registered struct {
15681656 state protoimpl.MessageState `protogen:"open.v1"`
@@ -1575,7 +1663,7 @@ type Registered struct {
15751663
15761664 func (x *Registered) Reset() {
15771665 *x = Registered{}
1578- mi := &file_broker_proto_msgTypes[18]
1666+ mi := &file_broker_proto_msgTypes[19]
15791667 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
15801668 ms.StoreMessageInfo(mi)
15811669 }
@@ -1587,7 +1675,7 @@ func (x *Registered) String() string {
15871675 func (*Registered) ProtoMessage() {}
15881676
15891677 func (x *Registered) ProtoReflect() protoreflect.Message {
1590- mi := &file_broker_proto_msgTypes[18]
1678+ mi := &file_broker_proto_msgTypes[19]
15911679 if x != nil {
15921680 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
15931681 if ms.LoadMessageInfo() == nil {
@@ -1600,7 +1688,7 @@ func (x *Registered) ProtoReflect() protoreflect.Message {
16001688
16011689 // Deprecated: Use Registered.ProtoReflect.Descriptor instead.
16021690 func (*Registered) Descriptor() ([]byte, []int) {
1603- return file_broker_proto_rawDescGZIP(), []int{18}
1691+ return file_broker_proto_rawDescGZIP(), []int{19}
16041692 }
16051693
16061694 func (x *Registered) GetScope() *BrokerScope {
@@ -1647,7 +1735,7 @@ type SnapshotPart struct {
16471735
16481736 func (x *SnapshotPart) Reset() {
16491737 *x = SnapshotPart{}
1650- mi := &file_broker_proto_msgTypes[19]
1738+ mi := &file_broker_proto_msgTypes[20]
16511739 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
16521740 ms.StoreMessageInfo(mi)
16531741 }
@@ -1659,7 +1747,7 @@ func (x *SnapshotPart) String() string {
16591747 func (*SnapshotPart) ProtoMessage() {}
16601748
16611749 func (x *SnapshotPart) ProtoReflect() protoreflect.Message {
1662- mi := &file_broker_proto_msgTypes[19]
1750+ mi := &file_broker_proto_msgTypes[20]
16631751 if x != nil {
16641752 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
16651753 if ms.LoadMessageInfo() == nil {
@@ -1672,7 +1760,7 @@ func (x *SnapshotPart) ProtoReflect() protoreflect.Message {
16721760
16731761 // Deprecated: Use SnapshotPart.ProtoReflect.Descriptor instead.
16741762 func (*SnapshotPart) Descriptor() ([]byte, []int) {
1675- return file_broker_proto_rawDescGZIP(), []int{19}
1763+ return file_broker_proto_rawDescGZIP(), []int{20}
16761764 }
16771765
16781766 func (x *SnapshotPart) GetScope() *BrokerScope {
@@ -1805,7 +1893,7 @@ type SnapshotBegin struct {
18051893
18061894 func (x *SnapshotBegin) Reset() {
18071895 *x = SnapshotBegin{}
1808- mi := &file_broker_proto_msgTypes[20]
1896+ mi := &file_broker_proto_msgTypes[21]
18091897 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
18101898 ms.StoreMessageInfo(mi)
18111899 }
@@ -1817,7 +1905,7 @@ func (x *SnapshotBegin) String() string {
18171905 func (*SnapshotBegin) ProtoMessage() {}
18181906
18191907 func (x *SnapshotBegin) ProtoReflect() protoreflect.Message {
1820- mi := &file_broker_proto_msgTypes[20]
1908+ mi := &file_broker_proto_msgTypes[21]
18211909 if x != nil {
18221910 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
18231911 if ms.LoadMessageInfo() == nil {
@@ -1830,7 +1918,7 @@ func (x *SnapshotBegin) ProtoReflect() protoreflect.Message {
18301918
18311919 // Deprecated: Use SnapshotBegin.ProtoReflect.Descriptor instead.
18321920 func (*SnapshotBegin) Descriptor() ([]byte, []int) {
1833- return file_broker_proto_rawDescGZIP(), []int{20}
1921+ return file_broker_proto_rawDescGZIP(), []int{21}
18341922 }
18351923
18361924 func (x *SnapshotBegin) GetHostCount() uint32 {
@@ -1905,7 +1993,7 @@ type SnapshotDaemon struct {
19051993
19061994 func (x *SnapshotDaemon) Reset() {
19071995 *x = SnapshotDaemon{}
1908- mi := &file_broker_proto_msgTypes[21]
1996+ mi := &file_broker_proto_msgTypes[22]
19091997 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
19101998 ms.StoreMessageInfo(mi)
19111999 }
@@ -1917,7 +2005,7 @@ func (x *SnapshotDaemon) String() string {
19172005 func (*SnapshotDaemon) ProtoMessage() {}
19182006
19192007 func (x *SnapshotDaemon) ProtoReflect() protoreflect.Message {
1920- mi := &file_broker_proto_msgTypes[21]
2008+ mi := &file_broker_proto_msgTypes[22]
19212009 if x != nil {
19222010 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
19232011 if ms.LoadMessageInfo() == nil {
@@ -1930,7 +2018,7 @@ func (x *SnapshotDaemon) ProtoReflect() protoreflect.Message {
19302018
19312019 // Deprecated: Use SnapshotDaemon.ProtoReflect.Descriptor instead.
19322020 func (*SnapshotDaemon) Descriptor() ([]byte, []int) {
1933- return file_broker_proto_rawDescGZIP(), []int{21}
2021+ return file_broker_proto_rawDescGZIP(), []int{22}
19342022 }
19352023
19362024 func (x *SnapshotDaemon) GetHostIndex() uint32 {
@@ -2095,7 +2183,7 @@ type SnapshotSession struct {
20952183
20962184 func (x *SnapshotSession) Reset() {
20972185 *x = SnapshotSession{}
2098- mi := &file_broker_proto_msgTypes[22]
2186+ mi := &file_broker_proto_msgTypes[23]
20992187 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
21002188 ms.StoreMessageInfo(mi)
21012189 }
@@ -2107,7 +2195,7 @@ func (x *SnapshotSession) String() string {
21072195 func (*SnapshotSession) ProtoMessage() {}
21082196
21092197 func (x *SnapshotSession) ProtoReflect() protoreflect.Message {
2110- mi := &file_broker_proto_msgTypes[22]
2198+ mi := &file_broker_proto_msgTypes[23]
21112199 if x != nil {
21122200 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
21132201 if ms.LoadMessageInfo() == nil {
@@ -2120,7 +2208,7 @@ func (x *SnapshotSession) ProtoReflect() protoreflect.Message {
21202208
21212209 // Deprecated: Use SnapshotSession.ProtoReflect.Descriptor instead.
21222210 func (*SnapshotSession) Descriptor() ([]byte, []int) {
2123- return file_broker_proto_rawDescGZIP(), []int{22}
2211+ return file_broker_proto_rawDescGZIP(), []int{23}
21242212 }
21252213
21262214 func (x *SnapshotSession) GetHostIndex() uint32 {
@@ -2164,7 +2252,7 @@ type SnapshotTombstone struct {
21642252
21652253 func (x *SnapshotTombstone) Reset() {
21662254 *x = SnapshotTombstone{}
2167- mi := &file_broker_proto_msgTypes[23]
2255+ mi := &file_broker_proto_msgTypes[24]
21682256 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
21692257 ms.StoreMessageInfo(mi)
21702258 }
@@ -2176,7 +2264,7 @@ func (x *SnapshotTombstone) String() string {
21762264 func (*SnapshotTombstone) ProtoMessage() {}
21772265
21782266 func (x *SnapshotTombstone) ProtoReflect() protoreflect.Message {
2179- mi := &file_broker_proto_msgTypes[23]
2267+ mi := &file_broker_proto_msgTypes[24]
21802268 if x != nil {
21812269 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
21822270 if ms.LoadMessageInfo() == nil {
@@ -2189,7 +2277,7 @@ func (x *SnapshotTombstone) ProtoReflect() protoreflect.Message {
21892277
21902278 // Deprecated: Use SnapshotTombstone.ProtoReflect.Descriptor instead.
21912279 func (*SnapshotTombstone) Descriptor() ([]byte, []int) {
2192- return file_broker_proto_rawDescGZIP(), []int{23}
2280+ return file_broker_proto_rawDescGZIP(), []int{24}
21932281 }
21942282
21952283 func (x *SnapshotTombstone) GetTombstoneIndex() uint32 {
@@ -2222,7 +2310,7 @@ type SnapshotEnd struct {
22222310
22232311 func (x *SnapshotEnd) Reset() {
22242312 *x = SnapshotEnd{}
2225- mi := &file_broker_proto_msgTypes[24]
2313+ mi := &file_broker_proto_msgTypes[25]
22262314 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
22272315 ms.StoreMessageInfo(mi)
22282316 }
@@ -2234,7 +2322,7 @@ func (x *SnapshotEnd) String() string {
22342322 func (*SnapshotEnd) ProtoMessage() {}
22352323
22362324 func (x *SnapshotEnd) ProtoReflect() protoreflect.Message {
2237- mi := &file_broker_proto_msgTypes[24]
2325+ mi := &file_broker_proto_msgTypes[25]
22382326 if x != nil {
22392327 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
22402328 if ms.LoadMessageInfo() == nil {
@@ -2247,7 +2335,7 @@ func (x *SnapshotEnd) ProtoReflect() protoreflect.Message {
22472335
22482336 // Deprecated: Use SnapshotEnd.ProtoReflect.Descriptor instead.
22492337 func (*SnapshotEnd) Descriptor() ([]byte, []int) {
2250- return file_broker_proto_rawDescGZIP(), []int{24}
2338+ return file_broker_proto_rawDescGZIP(), []int{25}
22512339 }
22522340
22532341 // OperationResult is exactly one completion for one admitted mutating
@@ -2270,7 +2358,7 @@ type OperationResult struct {
22702358
22712359 func (x *OperationResult) Reset() {
22722360 *x = OperationResult{}
2273- mi := &file_broker_proto_msgTypes[25]
2361+ mi := &file_broker_proto_msgTypes[26]
22742362 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
22752363 ms.StoreMessageInfo(mi)
22762364 }
@@ -2282,7 +2370,7 @@ func (x *OperationResult) String() string {
22822370 func (*OperationResult) ProtoMessage() {}
22832371
22842372 func (x *OperationResult) ProtoReflect() protoreflect.Message {
2285- mi := &file_broker_proto_msgTypes[25]
2373+ mi := &file_broker_proto_msgTypes[26]
22862374 if x != nil {
22872375 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
22882376 if ms.LoadMessageInfo() == nil {
@@ -2295,7 +2383,7 @@ func (x *OperationResult) ProtoReflect() protoreflect.Message {
22952383
22962384 // Deprecated: Use OperationResult.ProtoReflect.Descriptor instead.
22972385 func (*OperationResult) Descriptor() ([]byte, []int) {
2298- return file_broker_proto_rawDescGZIP(), []int{25}
2386+ return file_broker_proto_rawDescGZIP(), []int{26}
22992387 }
23002388
23012389 func (x *OperationResult) GetScope() *BrokerScope {
@@ -2350,7 +2438,7 @@ type StreamOpened struct {
23502438
23512439 func (x *StreamOpened) Reset() {
23522440 *x = StreamOpened{}
2353- mi := &file_broker_proto_msgTypes[26]
2441+ mi := &file_broker_proto_msgTypes[27]
23542442 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
23552443 ms.StoreMessageInfo(mi)
23562444 }
@@ -2362,7 +2450,7 @@ func (x *StreamOpened) String() string {
23622450 func (*StreamOpened) ProtoMessage() {}
23632451
23642452 func (x *StreamOpened) ProtoReflect() protoreflect.Message {
2365- mi := &file_broker_proto_msgTypes[26]
2453+ mi := &file_broker_proto_msgTypes[27]
23662454 if x != nil {
23672455 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
23682456 if ms.LoadMessageInfo() == nil {
@@ -2375,7 +2463,7 @@ func (x *StreamOpened) ProtoReflect() protoreflect.Message {
23752463
23762464 // Deprecated: Use StreamOpened.ProtoReflect.Descriptor instead.
23772465 func (*StreamOpened) Descriptor() ([]byte, []int) {
2378- return file_broker_proto_rawDescGZIP(), []int{26}
2466+ return file_broker_proto_rawDescGZIP(), []int{27}
23792467 }
23802468
23812469 func (x *StreamOpened) GetRef() *BrokerStreamRef {
@@ -2396,7 +2484,7 @@ type ServerStreamData struct {
23962484
23972485 func (x *ServerStreamData) Reset() {
23982486 *x = ServerStreamData{}
2399- mi := &file_broker_proto_msgTypes[27]
2487+ mi := &file_broker_proto_msgTypes[28]
24002488 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
24012489 ms.StoreMessageInfo(mi)
24022490 }
@@ -2408,7 +2496,7 @@ func (x *ServerStreamData) String() string {
24082496 func (*ServerStreamData) ProtoMessage() {}
24092497
24102498 func (x *ServerStreamData) ProtoReflect() protoreflect.Message {
2411- mi := &file_broker_proto_msgTypes[27]
2499+ mi := &file_broker_proto_msgTypes[28]
24122500 if x != nil {
24132501 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
24142502 if ms.LoadMessageInfo() == nil {
@@ -2421,7 +2509,7 @@ func (x *ServerStreamData) ProtoReflect() protoreflect.Message {
24212509
24222510 // Deprecated: Use ServerStreamData.ProtoReflect.Descriptor instead.
24232511 func (*ServerStreamData) Descriptor() ([]byte, []int) {
2424- return file_broker_proto_rawDescGZIP(), []int{27}
2512+ return file_broker_proto_rawDescGZIP(), []int{28}
24252513 }
24262514
24272515 func (x *ServerStreamData) GetRef() *BrokerStreamRef {
@@ -2450,7 +2538,7 @@ type StreamClosed struct {
24502538
24512539 func (x *StreamClosed) Reset() {
24522540 *x = StreamClosed{}
2453- mi := &file_broker_proto_msgTypes[28]
2541+ mi := &file_broker_proto_msgTypes[29]
24542542 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
24552543 ms.StoreMessageInfo(mi)
24562544 }
@@ -2462,7 +2550,7 @@ func (x *StreamClosed) String() string {
24622550 func (*StreamClosed) ProtoMessage() {}
24632551
24642552 func (x *StreamClosed) ProtoReflect() protoreflect.Message {
2465- mi := &file_broker_proto_msgTypes[28]
2553+ mi := &file_broker_proto_msgTypes[29]
24662554 if x != nil {
24672555 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
24682556 if ms.LoadMessageInfo() == nil {
@@ -2475,7 +2563,7 @@ func (x *StreamClosed) ProtoReflect() protoreflect.Message {
24752563
24762564 // Deprecated: Use StreamClosed.ProtoReflect.Descriptor instead.
24772565 func (*StreamClosed) Descriptor() ([]byte, []int) {
2478- return file_broker_proto_rawDescGZIP(), []int{28}
2566+ return file_broker_proto_rawDescGZIP(), []int{29}
24792567 }
24802568
24812569 func (x *StreamClosed) GetRef() *BrokerStreamRef {
@@ -2504,7 +2592,7 @@ type Progress struct {
25042592
25052593 func (x *Progress) Reset() {
25062594 *x = Progress{}
2507- mi := &file_broker_proto_msgTypes[29]
2595+ mi := &file_broker_proto_msgTypes[30]
25082596 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
25092597 ms.StoreMessageInfo(mi)
25102598 }
@@ -2516,7 +2604,7 @@ func (x *Progress) String() string {
25162604 func (*Progress) ProtoMessage() {}
25172605
25182606 func (x *Progress) ProtoReflect() protoreflect.Message {
2519- mi := &file_broker_proto_msgTypes[29]
2607+ mi := &file_broker_proto_msgTypes[30]
25202608 if x != nil {
25212609 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
25222610 if ms.LoadMessageInfo() == nil {
@@ -2529,7 +2617,7 @@ func (x *Progress) ProtoReflect() protoreflect.Message {
25292617
25302618 // Deprecated: Use Progress.ProtoReflect.Descriptor instead.
25312619 func (*Progress) Descriptor() ([]byte, []int) {
2532- return file_broker_proto_rawDescGZIP(), []int{29}
2620+ return file_broker_proto_rawDescGZIP(), []int{30}
25332621 }
25342622
25352623 func (x *Progress) GetRef() *BrokerStreamRef {
@@ -2564,7 +2652,7 @@ type BrokerErrorMessage struct {
25642652
25652653 func (x *BrokerErrorMessage) Reset() {
25662654 *x = BrokerErrorMessage{}
2567- mi := &file_broker_proto_msgTypes[30]
2655+ mi := &file_broker_proto_msgTypes[31]
25682656 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
25692657 ms.StoreMessageInfo(mi)
25702658 }
@@ -2576,7 +2664,7 @@ func (x *BrokerErrorMessage) String() string {
25762664 func (*BrokerErrorMessage) ProtoMessage() {}
25772665
25782666 func (x *BrokerErrorMessage) ProtoReflect() protoreflect.Message {
2579- mi := &file_broker_proto_msgTypes[30]
2667+ mi := &file_broker_proto_msgTypes[31]
25802668 if x != nil {
25812669 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
25822670 if ms.LoadMessageInfo() == nil {
@@ -2589,7 +2677,7 @@ func (x *BrokerErrorMessage) ProtoReflect() protoreflect.Message {
25892677
25902678 // Deprecated: Use BrokerErrorMessage.ProtoReflect.Descriptor instead.
25912679 func (*BrokerErrorMessage) Descriptor() ([]byte, []int) {
2592- return file_broker_proto_rawDescGZIP(), []int{30}
2680+ return file_broker_proto_rawDescGZIP(), []int{31}
25932681 }
25942682
25952683 func (x *BrokerErrorMessage) GetScope() *BrokerScope {
@@ -2619,7 +2707,7 @@ type Shutdown struct {
26192707
26202708 func (x *Shutdown) Reset() {
26212709 *x = Shutdown{}
2622- mi := &file_broker_proto_msgTypes[31]
2710+ mi := &file_broker_proto_msgTypes[32]
26232711 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
26242712 ms.StoreMessageInfo(mi)
26252713 }
@@ -2631,7 +2719,7 @@ func (x *Shutdown) String() string {
26312719 func (*Shutdown) ProtoMessage() {}
26322720
26332721 func (x *Shutdown) ProtoReflect() protoreflect.Message {
2634- mi := &file_broker_proto_msgTypes[31]
2722+ mi := &file_broker_proto_msgTypes[32]
26352723 if x != nil {
26362724 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
26372725 if ms.LoadMessageInfo() == nil {
@@ -2644,7 +2732,7 @@ func (x *Shutdown) ProtoReflect() protoreflect.Message {
26442732
26452733 // Deprecated: Use Shutdown.ProtoReflect.Descriptor instead.
26462734 func (*Shutdown) Descriptor() ([]byte, []int) {
2647- return file_broker_proto_rawDescGZIP(), []int{31}
2735+ return file_broker_proto_rawDescGZIP(), []int{32}
26482736 }
26492737
26502738 func (x *Shutdown) GetScope() *BrokerScope {
@@ -2683,7 +2771,7 @@ type PreviewRoute struct {
26832771
26842772 func (x *PreviewRoute) Reset() {
26852773 *x = PreviewRoute{}
2686- mi := &file_broker_proto_msgTypes[32]
2774+ mi := &file_broker_proto_msgTypes[33]
26872775 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
26882776 ms.StoreMessageInfo(mi)
26892777 }
@@ -2695,7 +2783,7 @@ func (x *PreviewRoute) String() string {
26952783 func (*PreviewRoute) ProtoMessage() {}
26962784
26972785 func (x *PreviewRoute) ProtoReflect() protoreflect.Message {
2698- mi := &file_broker_proto_msgTypes[32]
2786+ mi := &file_broker_proto_msgTypes[33]
26992787 if x != nil {
27002788 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
27012789 if ms.LoadMessageInfo() == nil {
@@ -2708,7 +2796,7 @@ func (x *PreviewRoute) ProtoReflect() protoreflect.Message {
27082796
27092797 // Deprecated: Use PreviewRoute.ProtoReflect.Descriptor instead.
27102798 func (*PreviewRoute) Descriptor() ([]byte, []int) {
2711- return file_broker_proto_rawDescGZIP(), []int{32}
2799+ return file_broker_proto_rawDescGZIP(), []int{33}
27122800 }
27132801
27142802 func (x *PreviewRoute) GetLocal() bool {
@@ -2756,7 +2844,7 @@ type StartPreview struct {
27562844
27572845 func (x *StartPreview) Reset() {
27582846 *x = StartPreview{}
2759- mi := &file_broker_proto_msgTypes[33]
2847+ mi := &file_broker_proto_msgTypes[34]
27602848 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
27612849 ms.StoreMessageInfo(mi)
27622850 }
@@ -2768,7 +2856,7 @@ func (x *StartPreview) String() string {
27682856 func (*StartPreview) ProtoMessage() {}
27692857
27702858 func (x *StartPreview) ProtoReflect() protoreflect.Message {
2771- mi := &file_broker_proto_msgTypes[33]
2859+ mi := &file_broker_proto_msgTypes[34]
27722860 if x != nil {
27732861 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
27742862 if ms.LoadMessageInfo() == nil {
@@ -2781,7 +2869,7 @@ func (x *StartPreview) ProtoReflect() protoreflect.Message {
27812869
27822870 // Deprecated: Use StartPreview.ProtoReflect.Descriptor instead.
27832871 func (*StartPreview) Descriptor() ([]byte, []int) {
2784- return file_broker_proto_rawDescGZIP(), []int{33}
2872+ return file_broker_proto_rawDescGZIP(), []int{34}
27852873 }
27862874
27872875 func (x *StartPreview) GetScope() *BrokerScope {
@@ -2823,7 +2911,7 @@ type CancelPreview struct {
28232911
28242912 func (x *CancelPreview) Reset() {
28252913 *x = CancelPreview{}
2826- mi := &file_broker_proto_msgTypes[34]
2914+ mi := &file_broker_proto_msgTypes[35]
28272915 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
28282916 ms.StoreMessageInfo(mi)
28292917 }
@@ -2835,7 +2923,7 @@ func (x *CancelPreview) String() string {
28352923 func (*CancelPreview) ProtoMessage() {}
28362924
28372925 func (x *CancelPreview) ProtoReflect() protoreflect.Message {
2838- mi := &file_broker_proto_msgTypes[34]
2926+ mi := &file_broker_proto_msgTypes[35]
28392927 if x != nil {
28402928 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
28412929 if ms.LoadMessageInfo() == nil {
@@ -2848,7 +2936,7 @@ func (x *CancelPreview) ProtoReflect() protoreflect.Message {
28482936
28492937 // Deprecated: Use CancelPreview.ProtoReflect.Descriptor instead.
28502938 func (*CancelPreview) Descriptor() ([]byte, []int) {
2851- return file_broker_proto_rawDescGZIP(), []int{34}
2939+ return file_broker_proto_rawDescGZIP(), []int{35}
28522940 }
28532941
28542942 func (x *CancelPreview) GetScope() *BrokerScope {
@@ -2882,7 +2970,7 @@ type PreviewPublication struct {
28822970
28832971 func (x *PreviewPublication) Reset() {
28842972 *x = PreviewPublication{}
2885- mi := &file_broker_proto_msgTypes[35]
2973+ mi := &file_broker_proto_msgTypes[36]
28862974 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
28872975 ms.StoreMessageInfo(mi)
28882976 }
@@ -2894,7 +2982,7 @@ func (x *PreviewPublication) String() string {
28942982 func (*PreviewPublication) ProtoMessage() {}
28952983
28962984 func (x *PreviewPublication) ProtoReflect() protoreflect.Message {
2897- mi := &file_broker_proto_msgTypes[35]
2985+ mi := &file_broker_proto_msgTypes[36]
28982986 if x != nil {
28992987 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
29002988 if ms.LoadMessageInfo() == nil {
@@ -2907,7 +2995,7 @@ func (x *PreviewPublication) ProtoReflect() protoreflect.Message {
29072995
29082996 // Deprecated: Use PreviewPublication.ProtoReflect.Descriptor instead.
29092997 func (*PreviewPublication) Descriptor() ([]byte, []int) {
2910- return file_broker_proto_rawDescGZIP(), []int{35}
2998+ return file_broker_proto_rawDescGZIP(), []int{36}
29112999 }
29123000
29133001 func (x *PreviewPublication) GetScope() *BrokerScope {
@@ -2987,7 +3075,7 @@ type BrokerCatalogSession struct {
29873075
29883076 func (x *BrokerCatalogSession) Reset() {
29893077 *x = BrokerCatalogSession{}
2990- mi := &file_broker_proto_msgTypes[36]
3078+ mi := &file_broker_proto_msgTypes[37]
29913079 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
29923080 ms.StoreMessageInfo(mi)
29933081 }
@@ -2999,7 +3087,7 @@ func (x *BrokerCatalogSession) String() string {
29993087 func (*BrokerCatalogSession) ProtoMessage() {}
30003088
30013089 func (x *BrokerCatalogSession) ProtoReflect() protoreflect.Message {
3002- mi := &file_broker_proto_msgTypes[36]
3090+ mi := &file_broker_proto_msgTypes[37]
30033091 if x != nil {
30043092 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
30053093 if ms.LoadMessageInfo() == nil {
@@ -3012,7 +3100,7 @@ func (x *BrokerCatalogSession) ProtoReflect() protoreflect.Message {
30123100
30133101 // Deprecated: Use BrokerCatalogSession.ProtoReflect.Descriptor instead.
30143102 func (*BrokerCatalogSession) Descriptor() ([]byte, []int) {
3015- return file_broker_proto_rawDescGZIP(), []int{36}
3103+ return file_broker_proto_rawDescGZIP(), []int{37}
30163104 }
30173105
30183106 func (x *BrokerCatalogSession) GetLifecycleId() []byte {
@@ -3092,7 +3180,7 @@ type BrokerCatalogTab struct {
30923180
30933181 func (x *BrokerCatalogTab) Reset() {
30943182 *x = BrokerCatalogTab{}
3095- mi := &file_broker_proto_msgTypes[37]
3183+ mi := &file_broker_proto_msgTypes[38]
30963184 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
30973185 ms.StoreMessageInfo(mi)
30983186 }
@@ -3104,7 +3192,7 @@ func (x *BrokerCatalogTab) String() string {
31043192 func (*BrokerCatalogTab) ProtoMessage() {}
31053193
31063194 func (x *BrokerCatalogTab) ProtoReflect() protoreflect.Message {
3107- mi := &file_broker_proto_msgTypes[37]
3195+ mi := &file_broker_proto_msgTypes[38]
31083196 if x != nil {
31093197 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
31103198 if ms.LoadMessageInfo() == nil {
@@ -3117,7 +3205,7 @@ func (x *BrokerCatalogTab) ProtoReflect() protoreflect.Message {
31173205
31183206 // Deprecated: Use BrokerCatalogTab.ProtoReflect.Descriptor instead.
31193207 func (*BrokerCatalogTab) Descriptor() ([]byte, []int) {
3120- return file_broker_proto_rawDescGZIP(), []int{37}
3208+ return file_broker_proto_rawDescGZIP(), []int{38}
31213209 }
31223210
31233211 func (x *BrokerCatalogTab) GetId() string {
@@ -3181,7 +3269,7 @@ const file_broker_proto_rawDesc = "" +
31813269 "\ffailure_kind\x18\x04 \x01(\rR\vfailureKind\"A\n" +
31823270 "\x0fBrokerTimestamp\x12\x18\n" +
31833271 "\aseconds\x18\x01 \x01(\x03R\aseconds\x12\x14\n" +
3184- "\x05nanos\x18\x02 \x01(\x05R\x05nanos\"\xc2\x06\n" +
3272+ "\x05nanos\x18\x02 \x01(\x05R\x05nanos\"\x97\a\n" +
31853273 "\x14BrokerClientEnvelope\x123\n" +
31863274 "\bregister\x18e \x01(\v2\x15.vev.wire.v1.RegisterH\x00R\bregister\x126\n" +
31873275 "\tsubscribe\x18f \x01(\v2\x16.vev.wire.v1.SubscribeH\x00R\tsubscribe\x12-\n" +
@@ -3197,8 +3285,9 @@ const file_broker_proto_rawDesc = "" +
31973285 "\fclose_stream\x18n \x01(\v2\x18.vev.wire.v1.CloseStreamH\x00R\vcloseStream\x12M\n" +
31983286 "\x12update_host_policy\x18o \x01(\v2\x1d.vev.wire.v1.UpdateHostPolicyH\x00R\x10updateHostPolicy\x12@\n" +
31993287 "\rstart_preview\x18p \x01(\v2\x19.vev.wire.v1.StartPreviewH\x00R\fstartPreview\x12C\n" +
3200- "\x0ecancel_preview\x18q \x01(\v2\x1a.vev.wire.v1.CancelPreviewH\x00R\rcancelPreviewB\t\n" +
3201- "\apayload\"\xd9\x05\n" +
3288+ "\x0ecancel_preview\x18q \x01(\v2\x1a.vev.wire.v1.CancelPreviewH\x00R\rcancelPreview\x12S\n" +
3289+ "\x14stream_window_update\x18r \x01(\v2\x1f.vev.wire.v1.StreamWindowUpdateH\x00R\x12streamWindowUpdateB\t\n" +
3290+ "\apayload\"\xaf\x06\n" +
32023291 "\x14BrokerServerEnvelope\x12:\n" +
32033292 "\n" +
32043293 "registered\x18\xc9\x01 \x01(\v2\x17.vev.wire.v1.RegisteredH\x00R\n" +
@@ -3211,7 +3300,8 @@ const file_broker_proto_rawDesc = "" +
32113300 "\bprogress\x18\xcf\x01 \x01(\v2\x15.vev.wire.v1.ProgressH\x00R\bprogress\x12T\n" +
32123301 "\x14broker_error_message\x18\xd0\x01 \x01(\v2\x1f.vev.wire.v1.BrokerErrorMessageH\x00R\x12brokerErrorMessage\x124\n" +
32133302 "\bshutdown\x18\xd1\x01 \x01(\v2\x15.vev.wire.v1.ShutdownH\x00R\bshutdown\x12S\n" +
3214- "\x13preview_publication\x18\xd2\x01 \x01(\v2\x1f.vev.wire.v1.PreviewPublicationH\x00R\x12previewPublicationB\t\n" +
3303+ "\x13preview_publication\x18\xd2\x01 \x01(\v2\x1f.vev.wire.v1.PreviewPublicationH\x00R\x12previewPublication\x12T\n" +
3304+ "\x14stream_window_update\x18\xd3\x01 \x01(\v2\x1f.vev.wire.v1.StreamWindowUpdateH\x00R\x12streamWindowUpdateB\t\n" +
32153305 "\apayload\" \n" +
32163306 "\bRegister\x12\x14\n" +
32173307 "\x05build\x18\x01 \x01(\tR\x05build\"u\n" +
@@ -3268,7 +3358,10 @@ const file_broker_proto_rawDesc = "" +
32683358 "\x03ref\x18\x01 \x01(\v2\x1c.vev.wire.v1.BrokerStreamRefR\x03ref\x12\x12\n" +
32693359 "\x04data\x18\x02 \x01(\fR\x04data\"=\n" +
32703360 "\vCloseStream\x12.\n" +
3271- "\x03ref\x18\x01 \x01(\v2\x1c.vev.wire.v1.BrokerStreamRefR\x03ref\"n\n" +
3361+ "\x03ref\x18\x01 \x01(\v2\x1c.vev.wire.v1.BrokerStreamRefR\x03ref\"\\\n" +
3362+ "\x12StreamWindowUpdate\x12.\n" +
3363+ "\x03ref\x18\x01 \x01(\v2\x1c.vev.wire.v1.BrokerStreamRefR\x03ref\x12\x16\n" +
3364+ "\x06credit\x18\x02 \x01(\x04R\x06credit\"n\n" +
32723365 "\n" +
32733366 "Registered\x12.\n" +
32743367 "\x05scope\x18\x01 \x01(\v2\x18.vev.wire.v1.BrokerScopeR\x05scope\x12\x14\n" +
@@ -3409,7 +3502,7 @@ func file_broker_proto_rawDescGZIP() []byte {
34093502 return file_broker_proto_rawDescData
34103503 }
34113504
3412-var file_broker_proto_msgTypes = make([]protoimpl.MessageInfo, 38)
3505+var file_broker_proto_msgTypes = make([]protoimpl.MessageInfo, 39)
34133506 var file_broker_proto_goTypes = []any{
34143507 (*BrokerScope)(nil), // 0: vev.wire.v1.BrokerScope
34153508 (*BrokerStreamRef)(nil), // 1: vev.wire.v1.BrokerStreamRef
@@ -3429,30 +3522,31 @@ var file_broker_proto_goTypes = []any{
34293522 (*OpenStream)(nil), // 15: vev.wire.v1.OpenStream
34303523 (*ClientStreamData)(nil), // 16: vev.wire.v1.ClientStreamData
34313524 (*CloseStream)(nil), // 17: vev.wire.v1.CloseStream
3432- (*Registered)(nil), // 18: vev.wire.v1.Registered
3433- (*SnapshotPart)(nil), // 19: vev.wire.v1.SnapshotPart
3434- (*SnapshotBegin)(nil), // 20: vev.wire.v1.SnapshotBegin
3435- (*SnapshotDaemon)(nil), // 21: vev.wire.v1.SnapshotDaemon
3436- (*SnapshotSession)(nil), // 22: vev.wire.v1.SnapshotSession
3437- (*SnapshotTombstone)(nil), // 23: vev.wire.v1.SnapshotTombstone
3438- (*SnapshotEnd)(nil), // 24: vev.wire.v1.SnapshotEnd
3439- (*OperationResult)(nil), // 25: vev.wire.v1.OperationResult
3440- (*StreamOpened)(nil), // 26: vev.wire.v1.StreamOpened
3441- (*ServerStreamData)(nil), // 27: vev.wire.v1.ServerStreamData
3442- (*StreamClosed)(nil), // 28: vev.wire.v1.StreamClosed
3443- (*Progress)(nil), // 29: vev.wire.v1.Progress
3444- (*BrokerErrorMessage)(nil), // 30: vev.wire.v1.BrokerErrorMessage
3445- (*Shutdown)(nil), // 31: vev.wire.v1.Shutdown
3446- (*PreviewRoute)(nil), // 32: vev.wire.v1.PreviewRoute
3447- (*StartPreview)(nil), // 33: vev.wire.v1.StartPreview
3448- (*CancelPreview)(nil), // 34: vev.wire.v1.CancelPreview
3449- (*PreviewPublication)(nil), // 35: vev.wire.v1.PreviewPublication
3450- (*BrokerCatalogSession)(nil), // 36: vev.wire.v1.BrokerCatalogSession
3451- (*BrokerCatalogTab)(nil), // 37: vev.wire.v1.BrokerCatalogTab
3452- (*RemoteRegistration)(nil), // 38: vev.wire.v1.RemoteRegistration
3453- (*ExactTarget)(nil), // 39: vev.wire.v1.ExactTarget
3454- (*RemotePreviewRequest)(nil), // 40: vev.wire.v1.RemotePreviewRequest
3455- (*RemotePreview)(nil), // 41: vev.wire.v1.RemotePreview
3525+ (*StreamWindowUpdate)(nil), // 18: vev.wire.v1.StreamWindowUpdate
3526+ (*Registered)(nil), // 19: vev.wire.v1.Registered
3527+ (*SnapshotPart)(nil), // 20: vev.wire.v1.SnapshotPart
3528+ (*SnapshotBegin)(nil), // 21: vev.wire.v1.SnapshotBegin
3529+ (*SnapshotDaemon)(nil), // 22: vev.wire.v1.SnapshotDaemon
3530+ (*SnapshotSession)(nil), // 23: vev.wire.v1.SnapshotSession
3531+ (*SnapshotTombstone)(nil), // 24: vev.wire.v1.SnapshotTombstone
3532+ (*SnapshotEnd)(nil), // 25: vev.wire.v1.SnapshotEnd
3533+ (*OperationResult)(nil), // 26: vev.wire.v1.OperationResult
3534+ (*StreamOpened)(nil), // 27: vev.wire.v1.StreamOpened
3535+ (*ServerStreamData)(nil), // 28: vev.wire.v1.ServerStreamData
3536+ (*StreamClosed)(nil), // 29: vev.wire.v1.StreamClosed
3537+ (*Progress)(nil), // 30: vev.wire.v1.Progress
3538+ (*BrokerErrorMessage)(nil), // 31: vev.wire.v1.BrokerErrorMessage
3539+ (*Shutdown)(nil), // 32: vev.wire.v1.Shutdown
3540+ (*PreviewRoute)(nil), // 33: vev.wire.v1.PreviewRoute
3541+ (*StartPreview)(nil), // 34: vev.wire.v1.StartPreview
3542+ (*CancelPreview)(nil), // 35: vev.wire.v1.CancelPreview
3543+ (*PreviewPublication)(nil), // 36: vev.wire.v1.PreviewPublication
3544+ (*BrokerCatalogSession)(nil), // 37: vev.wire.v1.BrokerCatalogSession
3545+ (*BrokerCatalogTab)(nil), // 38: vev.wire.v1.BrokerCatalogTab
3546+ (*RemoteRegistration)(nil), // 39: vev.wire.v1.RemoteRegistration
3547+ (*ExactTarget)(nil), // 40: vev.wire.v1.ExactTarget
3548+ (*RemotePreviewRequest)(nil), // 41: vev.wire.v1.RemotePreviewRequest
3549+ (*RemotePreview)(nil), // 42: vev.wire.v1.RemotePreview
34563550 }
34573551 var file_broker_proto_depIdxs = []int32{
34583552 0, // 0: vev.wire.v1.BrokerStreamRef.scope:type_name -> vev.wire.v1.BrokerScope
@@ -3467,76 +3561,79 @@ var file_broker_proto_depIdxs = []int32{
34673561 16, // 9: vev.wire.v1.BrokerClientEnvelope.client_stream_data:type_name -> vev.wire.v1.ClientStreamData
34683562 17, // 10: vev.wire.v1.BrokerClientEnvelope.close_stream:type_name -> vev.wire.v1.CloseStream
34693563 13, // 11: vev.wire.v1.BrokerClientEnvelope.update_host_policy:type_name -> vev.wire.v1.UpdateHostPolicy
3470- 33, // 12: vev.wire.v1.BrokerClientEnvelope.start_preview:type_name -> vev.wire.v1.StartPreview
3471- 34, // 13: vev.wire.v1.BrokerClientEnvelope.cancel_preview:type_name -> vev.wire.v1.CancelPreview
3472- 18, // 14: vev.wire.v1.BrokerServerEnvelope.registered:type_name -> vev.wire.v1.Registered
3473- 19, // 15: vev.wire.v1.BrokerServerEnvelope.snapshot_part:type_name -> vev.wire.v1.SnapshotPart
3474- 25, // 16: vev.wire.v1.BrokerServerEnvelope.operation_result:type_name -> vev.wire.v1.OperationResult
3475- 26, // 17: vev.wire.v1.BrokerServerEnvelope.stream_opened:type_name -> vev.wire.v1.StreamOpened
3476- 27, // 18: vev.wire.v1.BrokerServerEnvelope.server_stream_data:type_name -> vev.wire.v1.ServerStreamData
3477- 28, // 19: vev.wire.v1.BrokerServerEnvelope.stream_closed:type_name -> vev.wire.v1.StreamClosed
3478- 29, // 20: vev.wire.v1.BrokerServerEnvelope.progress:type_name -> vev.wire.v1.Progress
3479- 30, // 21: vev.wire.v1.BrokerServerEnvelope.broker_error_message:type_name -> vev.wire.v1.BrokerErrorMessage
3480- 31, // 22: vev.wire.v1.BrokerServerEnvelope.shutdown:type_name -> vev.wire.v1.Shutdown
3481- 35, // 23: vev.wire.v1.BrokerServerEnvelope.preview_publication:type_name -> vev.wire.v1.PreviewPublication
3482- 0, // 24: vev.wire.v1.Subscribe.scope:type_name -> vev.wire.v1.BrokerScope
3483- 0, // 25: vev.wire.v1.Resync.scope:type_name -> vev.wire.v1.BrokerScope
3484- 0, // 26: vev.wire.v1.Unsubscribe.scope:type_name -> vev.wire.v1.BrokerScope
3485- 0, // 27: vev.wire.v1.AddHost.scope:type_name -> vev.wire.v1.BrokerScope
3486- 2, // 28: vev.wire.v1.AddHost.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3487- 0, // 29: vev.wire.v1.RemoveHost.scope:type_name -> vev.wire.v1.BrokerScope
3488- 38, // 30: vev.wire.v1.RemoveHost.registration:type_name -> vev.wire.v1.RemoteRegistration
3489- 0, // 31: vev.wire.v1.UpdateHostPolicy.scope:type_name -> vev.wire.v1.BrokerScope
3490- 38, // 32: vev.wire.v1.UpdateHostPolicy.registration:type_name -> vev.wire.v1.RemoteRegistration
3491- 2, // 33: vev.wire.v1.UpdateHostPolicy.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3492- 0, // 34: vev.wire.v1.Reconcile.scope:type_name -> vev.wire.v1.BrokerScope
3493- 38, // 35: vev.wire.v1.Reconcile.registration:type_name -> vev.wire.v1.RemoteRegistration
3494- 1, // 36: vev.wire.v1.OpenStream.ref:type_name -> vev.wire.v1.BrokerStreamRef
3495- 38, // 37: vev.wire.v1.OpenStream.registration:type_name -> vev.wire.v1.RemoteRegistration
3496- 39, // 38: vev.wire.v1.OpenStream.target:type_name -> vev.wire.v1.ExactTarget
3497- 2, // 39: vev.wire.v1.OpenStream.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3498- 1, // 40: vev.wire.v1.ClientStreamData.ref:type_name -> vev.wire.v1.BrokerStreamRef
3499- 1, // 41: vev.wire.v1.CloseStream.ref:type_name -> vev.wire.v1.BrokerStreamRef
3500- 0, // 42: vev.wire.v1.Registered.scope:type_name -> vev.wire.v1.BrokerScope
3501- 0, // 43: vev.wire.v1.SnapshotPart.scope:type_name -> vev.wire.v1.BrokerScope
3502- 20, // 44: vev.wire.v1.SnapshotPart.begin:type_name -> vev.wire.v1.SnapshotBegin
3503- 21, // 45: vev.wire.v1.SnapshotPart.daemon:type_name -> vev.wire.v1.SnapshotDaemon
3504- 22, // 46: vev.wire.v1.SnapshotPart.session:type_name -> vev.wire.v1.SnapshotSession
3505- 23, // 47: vev.wire.v1.SnapshotPart.tombstone:type_name -> vev.wire.v1.SnapshotTombstone
3506- 24, // 48: vev.wire.v1.SnapshotPart.end:type_name -> vev.wire.v1.SnapshotEnd
3507- 38, // 49: vev.wire.v1.SnapshotDaemon.registration:type_name -> vev.wire.v1.RemoteRegistration
3508- 2, // 50: vev.wire.v1.SnapshotDaemon.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3509- 4, // 51: vev.wire.v1.SnapshotDaemon.last_attempt:type_name -> vev.wire.v1.BrokerTimestamp
3510- 4, // 52: vev.wire.v1.SnapshotDaemon.last_success:type_name -> vev.wire.v1.BrokerTimestamp
3511- 4, // 53: vev.wire.v1.SnapshotDaemon.next_due:type_name -> vev.wire.v1.BrokerTimestamp
3512- 36, // 54: vev.wire.v1.SnapshotSession.session:type_name -> vev.wire.v1.BrokerCatalogSession
3513- 38, // 55: vev.wire.v1.SnapshotTombstone.registration:type_name -> vev.wire.v1.RemoteRegistration
3514- 0, // 56: vev.wire.v1.OperationResult.scope:type_name -> vev.wire.v1.BrokerScope
3515- 3, // 57: vev.wire.v1.OperationResult.error:type_name -> vev.wire.v1.BrokerErrorDetail
3516- 38, // 58: vev.wire.v1.OperationResult.registration:type_name -> vev.wire.v1.RemoteRegistration
3517- 1, // 59: vev.wire.v1.StreamOpened.ref:type_name -> vev.wire.v1.BrokerStreamRef
3518- 1, // 60: vev.wire.v1.ServerStreamData.ref:type_name -> vev.wire.v1.BrokerStreamRef
3519- 1, // 61: vev.wire.v1.StreamClosed.ref:type_name -> vev.wire.v1.BrokerStreamRef
3520- 3, // 62: vev.wire.v1.StreamClosed.error:type_name -> vev.wire.v1.BrokerErrorDetail
3521- 1, // 63: vev.wire.v1.Progress.ref:type_name -> vev.wire.v1.BrokerStreamRef
3522- 0, // 64: vev.wire.v1.BrokerErrorMessage.scope:type_name -> vev.wire.v1.BrokerScope
3523- 3, // 65: vev.wire.v1.BrokerErrorMessage.error:type_name -> vev.wire.v1.BrokerErrorDetail
3524- 0, // 66: vev.wire.v1.Shutdown.scope:type_name -> vev.wire.v1.BrokerScope
3525- 38, // 67: vev.wire.v1.PreviewRoute.registration:type_name -> vev.wire.v1.RemoteRegistration
3526- 2, // 68: vev.wire.v1.PreviewRoute.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3527- 0, // 69: vev.wire.v1.StartPreview.scope:type_name -> vev.wire.v1.BrokerScope
3528- 40, // 70: vev.wire.v1.StartPreview.preview:type_name -> vev.wire.v1.RemotePreviewRequest
3529- 32, // 71: vev.wire.v1.StartPreview.route:type_name -> vev.wire.v1.PreviewRoute
3530- 0, // 72: vev.wire.v1.CancelPreview.scope:type_name -> vev.wire.v1.BrokerScope
3531- 0, // 73: vev.wire.v1.PreviewPublication.scope:type_name -> vev.wire.v1.BrokerScope
3532- 41, // 74: vev.wire.v1.PreviewPublication.preview:type_name -> vev.wire.v1.RemotePreview
3533- 3, // 75: vev.wire.v1.PreviewPublication.error:type_name -> vev.wire.v1.BrokerErrorDetail
3534- 37, // 76: vev.wire.v1.BrokerCatalogSession.tabs:type_name -> vev.wire.v1.BrokerCatalogTab
3535- 77, // [77:77] is the sub-list for method output_type
3536- 77, // [77:77] is the sub-list for method input_type
3537- 77, // [77:77] is the sub-list for extension type_name
3538- 77, // [77:77] is the sub-list for extension extendee
3539- 0, // [0:77] is the sub-list for field type_name
3564+ 34, // 12: vev.wire.v1.BrokerClientEnvelope.start_preview:type_name -> vev.wire.v1.StartPreview
3565+ 35, // 13: vev.wire.v1.BrokerClientEnvelope.cancel_preview:type_name -> vev.wire.v1.CancelPreview
3566+ 18, // 14: vev.wire.v1.BrokerClientEnvelope.stream_window_update:type_name -> vev.wire.v1.StreamWindowUpdate
3567+ 19, // 15: vev.wire.v1.BrokerServerEnvelope.registered:type_name -> vev.wire.v1.Registered
3568+ 20, // 16: vev.wire.v1.BrokerServerEnvelope.snapshot_part:type_name -> vev.wire.v1.SnapshotPart
3569+ 26, // 17: vev.wire.v1.BrokerServerEnvelope.operation_result:type_name -> vev.wire.v1.OperationResult
3570+ 27, // 18: vev.wire.v1.BrokerServerEnvelope.stream_opened:type_name -> vev.wire.v1.StreamOpened
3571+ 28, // 19: vev.wire.v1.BrokerServerEnvelope.server_stream_data:type_name -> vev.wire.v1.ServerStreamData
3572+ 29, // 20: vev.wire.v1.BrokerServerEnvelope.stream_closed:type_name -> vev.wire.v1.StreamClosed
3573+ 30, // 21: vev.wire.v1.BrokerServerEnvelope.progress:type_name -> vev.wire.v1.Progress
3574+ 31, // 22: vev.wire.v1.BrokerServerEnvelope.broker_error_message:type_name -> vev.wire.v1.BrokerErrorMessage
3575+ 32, // 23: vev.wire.v1.BrokerServerEnvelope.shutdown:type_name -> vev.wire.v1.Shutdown
3576+ 36, // 24: vev.wire.v1.BrokerServerEnvelope.preview_publication:type_name -> vev.wire.v1.PreviewPublication
3577+ 18, // 25: vev.wire.v1.BrokerServerEnvelope.stream_window_update:type_name -> vev.wire.v1.StreamWindowUpdate
3578+ 0, // 26: vev.wire.v1.Subscribe.scope:type_name -> vev.wire.v1.BrokerScope
3579+ 0, // 27: vev.wire.v1.Resync.scope:type_name -> vev.wire.v1.BrokerScope
3580+ 0, // 28: vev.wire.v1.Unsubscribe.scope:type_name -> vev.wire.v1.BrokerScope
3581+ 0, // 29: vev.wire.v1.AddHost.scope:type_name -> vev.wire.v1.BrokerScope
3582+ 2, // 30: vev.wire.v1.AddHost.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3583+ 0, // 31: vev.wire.v1.RemoveHost.scope:type_name -> vev.wire.v1.BrokerScope
3584+ 39, // 32: vev.wire.v1.RemoveHost.registration:type_name -> vev.wire.v1.RemoteRegistration
3585+ 0, // 33: vev.wire.v1.UpdateHostPolicy.scope:type_name -> vev.wire.v1.BrokerScope
3586+ 39, // 34: vev.wire.v1.UpdateHostPolicy.registration:type_name -> vev.wire.v1.RemoteRegistration
3587+ 2, // 35: vev.wire.v1.UpdateHostPolicy.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3588+ 0, // 36: vev.wire.v1.Reconcile.scope:type_name -> vev.wire.v1.BrokerScope
3589+ 39, // 37: vev.wire.v1.Reconcile.registration:type_name -> vev.wire.v1.RemoteRegistration
3590+ 1, // 38: vev.wire.v1.OpenStream.ref:type_name -> vev.wire.v1.BrokerStreamRef
3591+ 39, // 39: vev.wire.v1.OpenStream.registration:type_name -> vev.wire.v1.RemoteRegistration
3592+ 40, // 40: vev.wire.v1.OpenStream.target:type_name -> vev.wire.v1.ExactTarget
3593+ 2, // 41: vev.wire.v1.OpenStream.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3594+ 1, // 42: vev.wire.v1.ClientStreamData.ref:type_name -> vev.wire.v1.BrokerStreamRef
3595+ 1, // 43: vev.wire.v1.CloseStream.ref:type_name -> vev.wire.v1.BrokerStreamRef
3596+ 1, // 44: vev.wire.v1.StreamWindowUpdate.ref:type_name -> vev.wire.v1.BrokerStreamRef
3597+ 0, // 45: vev.wire.v1.Registered.scope:type_name -> vev.wire.v1.BrokerScope
3598+ 0, // 46: vev.wire.v1.SnapshotPart.scope:type_name -> vev.wire.v1.BrokerScope
3599+ 21, // 47: vev.wire.v1.SnapshotPart.begin:type_name -> vev.wire.v1.SnapshotBegin
3600+ 22, // 48: vev.wire.v1.SnapshotPart.daemon:type_name -> vev.wire.v1.SnapshotDaemon
3601+ 23, // 49: vev.wire.v1.SnapshotPart.session:type_name -> vev.wire.v1.SnapshotSession
3602+ 24, // 50: vev.wire.v1.SnapshotPart.tombstone:type_name -> vev.wire.v1.SnapshotTombstone
3603+ 25, // 51: vev.wire.v1.SnapshotPart.end:type_name -> vev.wire.v1.SnapshotEnd
3604+ 39, // 52: vev.wire.v1.SnapshotDaemon.registration:type_name -> vev.wire.v1.RemoteRegistration
3605+ 2, // 53: vev.wire.v1.SnapshotDaemon.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3606+ 4, // 54: vev.wire.v1.SnapshotDaemon.last_attempt:type_name -> vev.wire.v1.BrokerTimestamp
3607+ 4, // 55: vev.wire.v1.SnapshotDaemon.last_success:type_name -> vev.wire.v1.BrokerTimestamp
3608+ 4, // 56: vev.wire.v1.SnapshotDaemon.next_due:type_name -> vev.wire.v1.BrokerTimestamp
3609+ 37, // 57: vev.wire.v1.SnapshotSession.session:type_name -> vev.wire.v1.BrokerCatalogSession
3610+ 39, // 58: vev.wire.v1.SnapshotTombstone.registration:type_name -> vev.wire.v1.RemoteRegistration
3611+ 0, // 59: vev.wire.v1.OperationResult.scope:type_name -> vev.wire.v1.BrokerScope
3612+ 3, // 60: vev.wire.v1.OperationResult.error:type_name -> vev.wire.v1.BrokerErrorDetail
3613+ 39, // 61: vev.wire.v1.OperationResult.registration:type_name -> vev.wire.v1.RemoteRegistration
3614+ 1, // 62: vev.wire.v1.StreamOpened.ref:type_name -> vev.wire.v1.BrokerStreamRef
3615+ 1, // 63: vev.wire.v1.ServerStreamData.ref:type_name -> vev.wire.v1.BrokerStreamRef
3616+ 1, // 64: vev.wire.v1.StreamClosed.ref:type_name -> vev.wire.v1.BrokerStreamRef
3617+ 3, // 65: vev.wire.v1.StreamClosed.error:type_name -> vev.wire.v1.BrokerErrorDetail
3618+ 1, // 66: vev.wire.v1.Progress.ref:type_name -> vev.wire.v1.BrokerStreamRef
3619+ 0, // 67: vev.wire.v1.BrokerErrorMessage.scope:type_name -> vev.wire.v1.BrokerScope
3620+ 3, // 68: vev.wire.v1.BrokerErrorMessage.error:type_name -> vev.wire.v1.BrokerErrorDetail
3621+ 0, // 69: vev.wire.v1.Shutdown.scope:type_name -> vev.wire.v1.BrokerScope
3622+ 39, // 70: vev.wire.v1.PreviewRoute.registration:type_name -> vev.wire.v1.RemoteRegistration
3623+ 2, // 71: vev.wire.v1.PreviewRoute.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3624+ 0, // 72: vev.wire.v1.StartPreview.scope:type_name -> vev.wire.v1.BrokerScope
3625+ 41, // 73: vev.wire.v1.StartPreview.preview:type_name -> vev.wire.v1.RemotePreviewRequest
3626+ 33, // 74: vev.wire.v1.StartPreview.route:type_name -> vev.wire.v1.PreviewRoute
3627+ 0, // 75: vev.wire.v1.CancelPreview.scope:type_name -> vev.wire.v1.BrokerScope
3628+ 0, // 76: vev.wire.v1.PreviewPublication.scope:type_name -> vev.wire.v1.BrokerScope
3629+ 42, // 77: vev.wire.v1.PreviewPublication.preview:type_name -> vev.wire.v1.RemotePreview
3630+ 3, // 78: vev.wire.v1.PreviewPublication.error:type_name -> vev.wire.v1.BrokerErrorDetail
3631+ 38, // 79: vev.wire.v1.BrokerCatalogSession.tabs:type_name -> vev.wire.v1.BrokerCatalogTab
3632+ 80, // [80:80] is the sub-list for method output_type
3633+ 80, // [80:80] is the sub-list for method input_type
3634+ 80, // [80:80] is the sub-list for extension type_name
3635+ 80, // [80:80] is the sub-list for extension extendee
3636+ 0, // [0:80] is the sub-list for field type_name
35403637 }
35413638
35423639 func init() { file_broker_proto_init() }
@@ -3560,6 +3657,7 @@ func file_broker_proto_init() {
35603657 (*BrokerClientEnvelope_UpdateHostPolicy)(nil),
35613658 (*BrokerClientEnvelope_StartPreview)(nil),
35623659 (*BrokerClientEnvelope_CancelPreview)(nil),
3660+ (*BrokerClientEnvelope_StreamWindowUpdate)(nil),
35633661 }
35643662 file_broker_proto_msgTypes[6].OneofWrappers = []any{
35653663 (*BrokerServerEnvelope_Registered)(nil),
@@ -3572,15 +3670,16 @@ func file_broker_proto_init() {
35723670 (*BrokerServerEnvelope_BrokerErrorMessage)(nil),
35733671 (*BrokerServerEnvelope_Shutdown)(nil),
35743672 (*BrokerServerEnvelope_PreviewPublication)(nil),
3673+ (*BrokerServerEnvelope_StreamWindowUpdate)(nil),
35753674 }
3576- file_broker_proto_msgTypes[19].OneofWrappers = []any{
3675+ file_broker_proto_msgTypes[20].OneofWrappers = []any{
35773676 (*SnapshotPart_Begin)(nil),
35783677 (*SnapshotPart_Daemon)(nil),
35793678 (*SnapshotPart_Session)(nil),
35803679 (*SnapshotPart_Tombstone)(nil),
35813680 (*SnapshotPart_End)(nil),
35823681 }
3583- file_broker_proto_msgTypes[35].OneofWrappers = []any{
3682+ file_broker_proto_msgTypes[36].OneofWrappers = []any{
35843683 (*PreviewPublication_Preview)(nil),
35853684 (*PreviewPublication_Error)(nil),
35863685 }
@@ -3590,7 +3689,7 @@ func file_broker_proto_init() {
35903689 GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
35913690 RawDescriptor: unsafe.Slice(unsafe.StringData(file_broker_proto_rawDesc), len(file_broker_proto_rawDesc)),
35923691 NumEnums: 0,
3593- NumMessages: 38,
3692+ NumMessages: 39,
35943693 NumExtensions: 0,
35953694 NumServices: 0,
35963695 },
@@ -390,6 +390,7 @@ type BrokerClientEnvelope struct {
390 // *BrokerClientEnvelope_UpdateHostPolicy390 // *BrokerClientEnvelope_UpdateHostPolicy
391 // *BrokerClientEnvelope_StartPreview391 // *BrokerClientEnvelope_StartPreview
392 // *BrokerClientEnvelope_CancelPreview392 // *BrokerClientEnvelope_CancelPreview
393+ // *BrokerClientEnvelope_StreamWindowUpdate
393 Payload isBrokerClientEnvelope_Payload `protobuf_oneof:"payload"`394 Payload isBrokerClientEnvelope_Payload `protobuf_oneof:"payload"`
394 unknownFields protoimpl.UnknownFields395 unknownFields protoimpl.UnknownFields
395 sizeCache protoimpl.SizeCache396 sizeCache protoimpl.SizeCache
@@ -549,6 +550,15 @@ func (x *BrokerClientEnvelope) GetCancelPreview() *CancelPreview {
549 return nil550 return nil
550 }551 }
551 552
553+func (x *BrokerClientEnvelope) GetStreamWindowUpdate() *StreamWindowUpdate {
554+ if x != nil {
555+ if x, ok := x.Payload.(*BrokerClientEnvelope_StreamWindowUpdate); ok {
556+ return x.StreamWindowUpdate
557+ }
558+ }
559+ return nil
560+}
561+
552 type isBrokerClientEnvelope_Payload interface {562 type isBrokerClientEnvelope_Payload interface {
553 isBrokerClientEnvelope_Payload()563 isBrokerClientEnvelope_Payload()
554 }564 }
@@ -605,6 +615,10 @@ type BrokerClientEnvelope_CancelPreview struct {
605 CancelPreview *CancelPreview `protobuf:"bytes,113,opt,name=cancel_preview,json=cancelPreview,proto3,oneof"`615 CancelPreview *CancelPreview `protobuf:"bytes,113,opt,name=cancel_preview,json=cancelPreview,proto3,oneof"`
606 }616 }
607 617
618+type BrokerClientEnvelope_StreamWindowUpdate struct {
619+ StreamWindowUpdate *StreamWindowUpdate `protobuf:"bytes,114,opt,name=stream_window_update,json=streamWindowUpdate,proto3,oneof"`
620+}
621+
608 func (*BrokerClientEnvelope_Register) isBrokerClientEnvelope_Payload() {}622 func (*BrokerClientEnvelope_Register) isBrokerClientEnvelope_Payload() {}
609 623
610 func (*BrokerClientEnvelope_Subscribe) isBrokerClientEnvelope_Payload() {}624 func (*BrokerClientEnvelope_Subscribe) isBrokerClientEnvelope_Payload() {}
@@ -631,6 +645,8 @@ func (*BrokerClientEnvelope_StartPreview) isBrokerClientEnvelope_Payload() {}
631 645
632 func (*BrokerClientEnvelope_CancelPreview) isBrokerClientEnvelope_Payload() {}646 func (*BrokerClientEnvelope_CancelPreview) isBrokerClientEnvelope_Payload() {}
633 647
648+func (*BrokerClientEnvelope_StreamWindowUpdate) isBrokerClientEnvelope_Payload() {}
649+
634 // BrokerServerEnvelope is the closed server-to-client broker union. Exactly650 // BrokerServerEnvelope is the closed server-to-client broker union. Exactly
635 // one variant must be set per envelope.651 // one variant must be set per envelope.
636 type BrokerServerEnvelope struct {652 type BrokerServerEnvelope struct {
@@ -647,6 +663,7 @@ type BrokerServerEnvelope struct {
647 // *BrokerServerEnvelope_BrokerErrorMessage663 // *BrokerServerEnvelope_BrokerErrorMessage
648 // *BrokerServerEnvelope_Shutdown664 // *BrokerServerEnvelope_Shutdown
649 // *BrokerServerEnvelope_PreviewPublication665 // *BrokerServerEnvelope_PreviewPublication
666+ // *BrokerServerEnvelope_StreamWindowUpdate
650 Payload isBrokerServerEnvelope_Payload `protobuf_oneof:"payload"`667 Payload isBrokerServerEnvelope_Payload `protobuf_oneof:"payload"`
651 unknownFields protoimpl.UnknownFields668 unknownFields protoimpl.UnknownFields
652 sizeCache protoimpl.SizeCache669 sizeCache protoimpl.SizeCache
@@ -779,6 +796,15 @@ func (x *BrokerServerEnvelope) GetPreviewPublication() *PreviewPublication {
779 return nil796 return nil
780 }797 }
781 798
799+func (x *BrokerServerEnvelope) GetStreamWindowUpdate() *StreamWindowUpdate {
800+ if x != nil {
801+ if x, ok := x.Payload.(*BrokerServerEnvelope_StreamWindowUpdate); ok {
802+ return x.StreamWindowUpdate
803+ }
804+ }
805+ return nil
806+}
807+
782 type isBrokerServerEnvelope_Payload interface {808 type isBrokerServerEnvelope_Payload interface {
783 isBrokerServerEnvelope_Payload()809 isBrokerServerEnvelope_Payload()
784 }810 }
@@ -823,6 +849,10 @@ type BrokerServerEnvelope_PreviewPublication struct {
823 PreviewPublication *PreviewPublication `protobuf:"bytes,210,opt,name=preview_publication,json=previewPublication,proto3,oneof"`849 PreviewPublication *PreviewPublication `protobuf:"bytes,210,opt,name=preview_publication,json=previewPublication,proto3,oneof"`
824 }850 }
825 851
852+type BrokerServerEnvelope_StreamWindowUpdate struct {
853+ StreamWindowUpdate *StreamWindowUpdate `protobuf:"bytes,211,opt,name=stream_window_update,json=streamWindowUpdate,proto3,oneof"`
854+}
855+
826 func (*BrokerServerEnvelope_Registered) isBrokerServerEnvelope_Payload() {}856 func (*BrokerServerEnvelope_Registered) isBrokerServerEnvelope_Payload() {}
827 857
828 func (*BrokerServerEnvelope_SnapshotPart) isBrokerServerEnvelope_Payload() {}858 func (*BrokerServerEnvelope_SnapshotPart) isBrokerServerEnvelope_Payload() {}
@@ -843,6 +873,8 @@ func (*BrokerServerEnvelope_Shutdown) isBrokerServerEnvelope_Payload() {}
843 873
844 func (*BrokerServerEnvelope_PreviewPublication) isBrokerServerEnvelope_Payload() {}874 func (*BrokerServerEnvelope_PreviewPublication) isBrokerServerEnvelope_Payload() {}
845 875
876+func (*BrokerServerEnvelope_StreamWindowUpdate) isBrokerServerEnvelope_Payload() {}
877+
846 // Register opens one client connection to the broker.878 // Register opens one client connection to the broker.
847 type Register struct {879 type Register struct {
848 state protoimpl.MessageState `protogen:"open.v1"`880 state protoimpl.MessageState `protogen:"open.v1"`
@@ -1563,6 +1595,62 @@ func (x *CloseStream) GetRef() *BrokerStreamRef {
1563 return nil1595 return nil
1564 }1596 }
1565 1597
1598+// StreamWindowUpdate grants the peer credit to send more stream data on one
1599+// logical stream: the receiver consumed that much of its stream window. Each
1600+// direction of a stream has its own window, so a client grants credit for
1601+// ServerStreamData and the server grants credit for ClientStreamData.
1602+type StreamWindowUpdate struct {
1603+ state protoimpl.MessageState `protogen:"open.v1"`
1604+ Ref *BrokerStreamRef `protobuf:"bytes,1,opt,name=ref,proto3" json:"ref,omitempty"`
1605+ Credit uint64 `protobuf:"varint,2,opt,name=credit,proto3" json:"credit,omitempty"`
1606+ unknownFields protoimpl.UnknownFields
1607+ sizeCache protoimpl.SizeCache
1608+}
1609+
1610+func (x *StreamWindowUpdate) Reset() {
1611+ *x = StreamWindowUpdate{}
1612+ mi := &file_broker_proto_msgTypes[18]
1613+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
1614+ ms.StoreMessageInfo(mi)
1615+}
1616+
1617+func (x *StreamWindowUpdate) String() string {
1618+ return protoimpl.X.MessageStringOf(x)
1619+}
1620+
1621+func (*StreamWindowUpdate) ProtoMessage() {}
1622+
1623+func (x *StreamWindowUpdate) ProtoReflect() protoreflect.Message {
1624+ mi := &file_broker_proto_msgTypes[18]
1625+ if x != nil {
1626+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
1627+ if ms.LoadMessageInfo() == nil {
1628+ ms.StoreMessageInfo(mi)
1629+ }
1630+ return ms
1631+ }
1632+ return mi.MessageOf(x)
1633+}
1634+
1635+// Deprecated: Use StreamWindowUpdate.ProtoReflect.Descriptor instead.
1636+func (*StreamWindowUpdate) Descriptor() ([]byte, []int) {
1637+ return file_broker_proto_rawDescGZIP(), []int{18}
1638+}
1639+
1640+func (x *StreamWindowUpdate) GetRef() *BrokerStreamRef {
1641+ if x != nil {
1642+ return x.Ref
1643+ }
1644+ return nil
1645+}
1646+
1647+func (x *StreamWindowUpdate) GetCredit() uint64 {
1648+ if x != nil {
1649+ return x.Credit
1650+ }
1651+ return 0
1652+}
1653+
1566 // Registered confirms one accepted client connection and its assigned scope.1654 // Registered confirms one accepted client connection and its assigned scope.
1567 type Registered struct {1655 type Registered struct {
1568 state protoimpl.MessageState `protogen:"open.v1"`1656 state protoimpl.MessageState `protogen:"open.v1"`
@@ -1575,7 +1663,7 @@ type Registered struct {
1575 1663
1576 func (x *Registered) Reset() {1664 func (x *Registered) Reset() {
1577 *x = Registered{}1665 *x = Registered{}
1578- mi := &file_broker_proto_msgTypes[18]1666+ mi := &file_broker_proto_msgTypes[19]
1579 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))1667 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
1580 ms.StoreMessageInfo(mi)1668 ms.StoreMessageInfo(mi)
1581 }1669 }
@@ -1587,7 +1675,7 @@ func (x *Registered) String() string {
1587 func (*Registered) ProtoMessage() {}1675 func (*Registered) ProtoMessage() {}
1588 1676
1589 func (x *Registered) ProtoReflect() protoreflect.Message {1677 func (x *Registered) ProtoReflect() protoreflect.Message {
1590- mi := &file_broker_proto_msgTypes[18]1678+ mi := &file_broker_proto_msgTypes[19]
1591 if x != nil {1679 if x != nil {
1592 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))1680 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
1593 if ms.LoadMessageInfo() == nil {1681 if ms.LoadMessageInfo() == nil {
@@ -1600,7 +1688,7 @@ func (x *Registered) ProtoReflect() protoreflect.Message {
1600 1688
1601 // Deprecated: Use Registered.ProtoReflect.Descriptor instead.1689 // Deprecated: Use Registered.ProtoReflect.Descriptor instead.
1602 func (*Registered) Descriptor() ([]byte, []int) {1690 func (*Registered) Descriptor() ([]byte, []int) {
1603- return file_broker_proto_rawDescGZIP(), []int{18}1691+ return file_broker_proto_rawDescGZIP(), []int{19}
1604 }1692 }
1605 1693
1606 func (x *Registered) GetScope() *BrokerScope {1694 func (x *Registered) GetScope() *BrokerScope {
@@ -1647,7 +1735,7 @@ type SnapshotPart struct {
1647 1735
1648 func (x *SnapshotPart) Reset() {1736 func (x *SnapshotPart) Reset() {
1649 *x = SnapshotPart{}1737 *x = SnapshotPart{}
1650- mi := &file_broker_proto_msgTypes[19]1738+ mi := &file_broker_proto_msgTypes[20]
1651 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))1739 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
1652 ms.StoreMessageInfo(mi)1740 ms.StoreMessageInfo(mi)
1653 }1741 }
@@ -1659,7 +1747,7 @@ func (x *SnapshotPart) String() string {
1659 func (*SnapshotPart) ProtoMessage() {}1747 func (*SnapshotPart) ProtoMessage() {}
1660 1748
1661 func (x *SnapshotPart) ProtoReflect() protoreflect.Message {1749 func (x *SnapshotPart) ProtoReflect() protoreflect.Message {
1662- mi := &file_broker_proto_msgTypes[19]1750+ mi := &file_broker_proto_msgTypes[20]
1663 if x != nil {1751 if x != nil {
1664 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))1752 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
1665 if ms.LoadMessageInfo() == nil {1753 if ms.LoadMessageInfo() == nil {
@@ -1672,7 +1760,7 @@ func (x *SnapshotPart) ProtoReflect() protoreflect.Message {
1672 1760
1673 // Deprecated: Use SnapshotPart.ProtoReflect.Descriptor instead.1761 // Deprecated: Use SnapshotPart.ProtoReflect.Descriptor instead.
1674 func (*SnapshotPart) Descriptor() ([]byte, []int) {1762 func (*SnapshotPart) Descriptor() ([]byte, []int) {
1675- return file_broker_proto_rawDescGZIP(), []int{19}1763+ return file_broker_proto_rawDescGZIP(), []int{20}
1676 }1764 }
1677 1765
1678 func (x *SnapshotPart) GetScope() *BrokerScope {1766 func (x *SnapshotPart) GetScope() *BrokerScope {
@@ -1805,7 +1893,7 @@ type SnapshotBegin struct {
1805 1893
1806 func (x *SnapshotBegin) Reset() {1894 func (x *SnapshotBegin) Reset() {
1807 *x = SnapshotBegin{}1895 *x = SnapshotBegin{}
1808- mi := &file_broker_proto_msgTypes[20]1896+ mi := &file_broker_proto_msgTypes[21]
1809 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))1897 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
1810 ms.StoreMessageInfo(mi)1898 ms.StoreMessageInfo(mi)
1811 }1899 }
@@ -1817,7 +1905,7 @@ func (x *SnapshotBegin) String() string {
1817 func (*SnapshotBegin) ProtoMessage() {}1905 func (*SnapshotBegin) ProtoMessage() {}
1818 1906
1819 func (x *SnapshotBegin) ProtoReflect() protoreflect.Message {1907 func (x *SnapshotBegin) ProtoReflect() protoreflect.Message {
1820- mi := &file_broker_proto_msgTypes[20]1908+ mi := &file_broker_proto_msgTypes[21]
1821 if x != nil {1909 if x != nil {
1822 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))1910 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
1823 if ms.LoadMessageInfo() == nil {1911 if ms.LoadMessageInfo() == nil {
@@ -1830,7 +1918,7 @@ func (x *SnapshotBegin) ProtoReflect() protoreflect.Message {
1830 1918
1831 // Deprecated: Use SnapshotBegin.ProtoReflect.Descriptor instead.1919 // Deprecated: Use SnapshotBegin.ProtoReflect.Descriptor instead.
1832 func (*SnapshotBegin) Descriptor() ([]byte, []int) {1920 func (*SnapshotBegin) Descriptor() ([]byte, []int) {
1833- return file_broker_proto_rawDescGZIP(), []int{20}1921+ return file_broker_proto_rawDescGZIP(), []int{21}
1834 }1922 }
1835 1923
1836 func (x *SnapshotBegin) GetHostCount() uint32 {1924 func (x *SnapshotBegin) GetHostCount() uint32 {
@@ -1905,7 +1993,7 @@ type SnapshotDaemon struct {
1905 1993
1906 func (x *SnapshotDaemon) Reset() {1994 func (x *SnapshotDaemon) Reset() {
1907 *x = SnapshotDaemon{}1995 *x = SnapshotDaemon{}
1908- mi := &file_broker_proto_msgTypes[21]1996+ mi := &file_broker_proto_msgTypes[22]
1909 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))1997 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
1910 ms.StoreMessageInfo(mi)1998 ms.StoreMessageInfo(mi)
1911 }1999 }
@@ -1917,7 +2005,7 @@ func (x *SnapshotDaemon) String() string {
1917 func (*SnapshotDaemon) ProtoMessage() {}2005 func (*SnapshotDaemon) ProtoMessage() {}
1918 2006
1919 func (x *SnapshotDaemon) ProtoReflect() protoreflect.Message {2007 func (x *SnapshotDaemon) ProtoReflect() protoreflect.Message {
1920- mi := &file_broker_proto_msgTypes[21]2008+ mi := &file_broker_proto_msgTypes[22]
1921 if x != nil {2009 if x != nil {
1922 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2010 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
1923 if ms.LoadMessageInfo() == nil {2011 if ms.LoadMessageInfo() == nil {
@@ -1930,7 +2018,7 @@ func (x *SnapshotDaemon) ProtoReflect() protoreflect.Message {
1930 2018
1931 // Deprecated: Use SnapshotDaemon.ProtoReflect.Descriptor instead.2019 // Deprecated: Use SnapshotDaemon.ProtoReflect.Descriptor instead.
1932 func (*SnapshotDaemon) Descriptor() ([]byte, []int) {2020 func (*SnapshotDaemon) Descriptor() ([]byte, []int) {
1933- return file_broker_proto_rawDescGZIP(), []int{21}2021+ return file_broker_proto_rawDescGZIP(), []int{22}
1934 }2022 }
1935 2023
1936 func (x *SnapshotDaemon) GetHostIndex() uint32 {2024 func (x *SnapshotDaemon) GetHostIndex() uint32 {
@@ -2095,7 +2183,7 @@ type SnapshotSession struct {
2095 2183
2096 func (x *SnapshotSession) Reset() {2184 func (x *SnapshotSession) Reset() {
2097 *x = SnapshotSession{}2185 *x = SnapshotSession{}
2098- mi := &file_broker_proto_msgTypes[22]2186+ mi := &file_broker_proto_msgTypes[23]
2099 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2187 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2100 ms.StoreMessageInfo(mi)2188 ms.StoreMessageInfo(mi)
2101 }2189 }
@@ -2107,7 +2195,7 @@ func (x *SnapshotSession) String() string {
2107 func (*SnapshotSession) ProtoMessage() {}2195 func (*SnapshotSession) ProtoMessage() {}
2108 2196
2109 func (x *SnapshotSession) ProtoReflect() protoreflect.Message {2197 func (x *SnapshotSession) ProtoReflect() protoreflect.Message {
2110- mi := &file_broker_proto_msgTypes[22]2198+ mi := &file_broker_proto_msgTypes[23]
2111 if x != nil {2199 if x != nil {
2112 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2200 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2113 if ms.LoadMessageInfo() == nil {2201 if ms.LoadMessageInfo() == nil {
@@ -2120,7 +2208,7 @@ func (x *SnapshotSession) ProtoReflect() protoreflect.Message {
2120 2208
2121 // Deprecated: Use SnapshotSession.ProtoReflect.Descriptor instead.2209 // Deprecated: Use SnapshotSession.ProtoReflect.Descriptor instead.
2122 func (*SnapshotSession) Descriptor() ([]byte, []int) {2210 func (*SnapshotSession) Descriptor() ([]byte, []int) {
2123- return file_broker_proto_rawDescGZIP(), []int{22}2211+ return file_broker_proto_rawDescGZIP(), []int{23}
2124 }2212 }
2125 2213
2126 func (x *SnapshotSession) GetHostIndex() uint32 {2214 func (x *SnapshotSession) GetHostIndex() uint32 {
@@ -2164,7 +2252,7 @@ type SnapshotTombstone struct {
2164 2252
2165 func (x *SnapshotTombstone) Reset() {2253 func (x *SnapshotTombstone) Reset() {
2166 *x = SnapshotTombstone{}2254 *x = SnapshotTombstone{}
2167- mi := &file_broker_proto_msgTypes[23]2255+ mi := &file_broker_proto_msgTypes[24]
2168 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2256 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2169 ms.StoreMessageInfo(mi)2257 ms.StoreMessageInfo(mi)
2170 }2258 }
@@ -2176,7 +2264,7 @@ func (x *SnapshotTombstone) String() string {
2176 func (*SnapshotTombstone) ProtoMessage() {}2264 func (*SnapshotTombstone) ProtoMessage() {}
2177 2265
2178 func (x *SnapshotTombstone) ProtoReflect() protoreflect.Message {2266 func (x *SnapshotTombstone) ProtoReflect() protoreflect.Message {
2179- mi := &file_broker_proto_msgTypes[23]2267+ mi := &file_broker_proto_msgTypes[24]
2180 if x != nil {2268 if x != nil {
2181 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2269 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2182 if ms.LoadMessageInfo() == nil {2270 if ms.LoadMessageInfo() == nil {
@@ -2189,7 +2277,7 @@ func (x *SnapshotTombstone) ProtoReflect() protoreflect.Message {
2189 2277
2190 // Deprecated: Use SnapshotTombstone.ProtoReflect.Descriptor instead.2278 // Deprecated: Use SnapshotTombstone.ProtoReflect.Descriptor instead.
2191 func (*SnapshotTombstone) Descriptor() ([]byte, []int) {2279 func (*SnapshotTombstone) Descriptor() ([]byte, []int) {
2192- return file_broker_proto_rawDescGZIP(), []int{23}2280+ return file_broker_proto_rawDescGZIP(), []int{24}
2193 }2281 }
2194 2282
2195 func (x *SnapshotTombstone) GetTombstoneIndex() uint32 {2283 func (x *SnapshotTombstone) GetTombstoneIndex() uint32 {
@@ -2222,7 +2310,7 @@ type SnapshotEnd struct {
2222 2310
2223 func (x *SnapshotEnd) Reset() {2311 func (x *SnapshotEnd) Reset() {
2224 *x = SnapshotEnd{}2312 *x = SnapshotEnd{}
2225- mi := &file_broker_proto_msgTypes[24]2313+ mi := &file_broker_proto_msgTypes[25]
2226 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2314 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2227 ms.StoreMessageInfo(mi)2315 ms.StoreMessageInfo(mi)
2228 }2316 }
@@ -2234,7 +2322,7 @@ func (x *SnapshotEnd) String() string {
2234 func (*SnapshotEnd) ProtoMessage() {}2322 func (*SnapshotEnd) ProtoMessage() {}
2235 2323
2236 func (x *SnapshotEnd) ProtoReflect() protoreflect.Message {2324 func (x *SnapshotEnd) ProtoReflect() protoreflect.Message {
2237- mi := &file_broker_proto_msgTypes[24]2325+ mi := &file_broker_proto_msgTypes[25]
2238 if x != nil {2326 if x != nil {
2239 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2327 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2240 if ms.LoadMessageInfo() == nil {2328 if ms.LoadMessageInfo() == nil {
@@ -2247,7 +2335,7 @@ func (x *SnapshotEnd) ProtoReflect() protoreflect.Message {
2247 2335
2248 // Deprecated: Use SnapshotEnd.ProtoReflect.Descriptor instead.2336 // Deprecated: Use SnapshotEnd.ProtoReflect.Descriptor instead.
2249 func (*SnapshotEnd) Descriptor() ([]byte, []int) {2337 func (*SnapshotEnd) Descriptor() ([]byte, []int) {
2250- return file_broker_proto_rawDescGZIP(), []int{24}2338+ return file_broker_proto_rawDescGZIP(), []int{25}
2251 }2339 }
2252 2340
2253 // OperationResult is exactly one completion for one admitted mutating2341 // OperationResult is exactly one completion for one admitted mutating
@@ -2270,7 +2358,7 @@ type OperationResult struct {
2270 2358
2271 func (x *OperationResult) Reset() {2359 func (x *OperationResult) Reset() {
2272 *x = OperationResult{}2360 *x = OperationResult{}
2273- mi := &file_broker_proto_msgTypes[25]2361+ mi := &file_broker_proto_msgTypes[26]
2274 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2362 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2275 ms.StoreMessageInfo(mi)2363 ms.StoreMessageInfo(mi)
2276 }2364 }
@@ -2282,7 +2370,7 @@ func (x *OperationResult) String() string {
2282 func (*OperationResult) ProtoMessage() {}2370 func (*OperationResult) ProtoMessage() {}
2283 2371
2284 func (x *OperationResult) ProtoReflect() protoreflect.Message {2372 func (x *OperationResult) ProtoReflect() protoreflect.Message {
2285- mi := &file_broker_proto_msgTypes[25]2373+ mi := &file_broker_proto_msgTypes[26]
2286 if x != nil {2374 if x != nil {
2287 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2375 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2288 if ms.LoadMessageInfo() == nil {2376 if ms.LoadMessageInfo() == nil {
@@ -2295,7 +2383,7 @@ func (x *OperationResult) ProtoReflect() protoreflect.Message {
2295 2383
2296 // Deprecated: Use OperationResult.ProtoReflect.Descriptor instead.2384 // Deprecated: Use OperationResult.ProtoReflect.Descriptor instead.
2297 func (*OperationResult) Descriptor() ([]byte, []int) {2385 func (*OperationResult) Descriptor() ([]byte, []int) {
2298- return file_broker_proto_rawDescGZIP(), []int{25}2386+ return file_broker_proto_rawDescGZIP(), []int{26}
2299 }2387 }
2300 2388
2301 func (x *OperationResult) GetScope() *BrokerScope {2389 func (x *OperationResult) GetScope() *BrokerScope {
@@ -2350,7 +2438,7 @@ type StreamOpened struct {
2350 2438
2351 func (x *StreamOpened) Reset() {2439 func (x *StreamOpened) Reset() {
2352 *x = StreamOpened{}2440 *x = StreamOpened{}
2353- mi := &file_broker_proto_msgTypes[26]2441+ mi := &file_broker_proto_msgTypes[27]
2354 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2442 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2355 ms.StoreMessageInfo(mi)2443 ms.StoreMessageInfo(mi)
2356 }2444 }
@@ -2362,7 +2450,7 @@ func (x *StreamOpened) String() string {
2362 func (*StreamOpened) ProtoMessage() {}2450 func (*StreamOpened) ProtoMessage() {}
2363 2451
2364 func (x *StreamOpened) ProtoReflect() protoreflect.Message {2452 func (x *StreamOpened) ProtoReflect() protoreflect.Message {
2365- mi := &file_broker_proto_msgTypes[26]2453+ mi := &file_broker_proto_msgTypes[27]
2366 if x != nil {2454 if x != nil {
2367 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2455 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2368 if ms.LoadMessageInfo() == nil {2456 if ms.LoadMessageInfo() == nil {
@@ -2375,7 +2463,7 @@ func (x *StreamOpened) ProtoReflect() protoreflect.Message {
2375 2463
2376 // Deprecated: Use StreamOpened.ProtoReflect.Descriptor instead.2464 // Deprecated: Use StreamOpened.ProtoReflect.Descriptor instead.
2377 func (*StreamOpened) Descriptor() ([]byte, []int) {2465 func (*StreamOpened) Descriptor() ([]byte, []int) {
2378- return file_broker_proto_rawDescGZIP(), []int{26}2466+ return file_broker_proto_rawDescGZIP(), []int{27}
2379 }2467 }
2380 2468
2381 func (x *StreamOpened) GetRef() *BrokerStreamRef {2469 func (x *StreamOpened) GetRef() *BrokerStreamRef {
@@ -2396,7 +2484,7 @@ type ServerStreamData struct {
2396 2484
2397 func (x *ServerStreamData) Reset() {2485 func (x *ServerStreamData) Reset() {
2398 *x = ServerStreamData{}2486 *x = ServerStreamData{}
2399- mi := &file_broker_proto_msgTypes[27]2487+ mi := &file_broker_proto_msgTypes[28]
2400 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2488 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2401 ms.StoreMessageInfo(mi)2489 ms.StoreMessageInfo(mi)
2402 }2490 }
@@ -2408,7 +2496,7 @@ func (x *ServerStreamData) String() string {
2408 func (*ServerStreamData) ProtoMessage() {}2496 func (*ServerStreamData) ProtoMessage() {}
2409 2497
2410 func (x *ServerStreamData) ProtoReflect() protoreflect.Message {2498 func (x *ServerStreamData) ProtoReflect() protoreflect.Message {
2411- mi := &file_broker_proto_msgTypes[27]2499+ mi := &file_broker_proto_msgTypes[28]
2412 if x != nil {2500 if x != nil {
2413 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2501 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2414 if ms.LoadMessageInfo() == nil {2502 if ms.LoadMessageInfo() == nil {
@@ -2421,7 +2509,7 @@ func (x *ServerStreamData) ProtoReflect() protoreflect.Message {
2421 2509
2422 // Deprecated: Use ServerStreamData.ProtoReflect.Descriptor instead.2510 // Deprecated: Use ServerStreamData.ProtoReflect.Descriptor instead.
2423 func (*ServerStreamData) Descriptor() ([]byte, []int) {2511 func (*ServerStreamData) Descriptor() ([]byte, []int) {
2424- return file_broker_proto_rawDescGZIP(), []int{27}2512+ return file_broker_proto_rawDescGZIP(), []int{28}
2425 }2513 }
2426 2514
2427 func (x *ServerStreamData) GetRef() *BrokerStreamRef {2515 func (x *ServerStreamData) GetRef() *BrokerStreamRef {
@@ -2450,7 +2538,7 @@ type StreamClosed struct {
2450 2538
2451 func (x *StreamClosed) Reset() {2539 func (x *StreamClosed) Reset() {
2452 *x = StreamClosed{}2540 *x = StreamClosed{}
2453- mi := &file_broker_proto_msgTypes[28]2541+ mi := &file_broker_proto_msgTypes[29]
2454 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2542 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2455 ms.StoreMessageInfo(mi)2543 ms.StoreMessageInfo(mi)
2456 }2544 }
@@ -2462,7 +2550,7 @@ func (x *StreamClosed) String() string {
2462 func (*StreamClosed) ProtoMessage() {}2550 func (*StreamClosed) ProtoMessage() {}
2463 2551
2464 func (x *StreamClosed) ProtoReflect() protoreflect.Message {2552 func (x *StreamClosed) ProtoReflect() protoreflect.Message {
2465- mi := &file_broker_proto_msgTypes[28]2553+ mi := &file_broker_proto_msgTypes[29]
2466 if x != nil {2554 if x != nil {
2467 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2555 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2468 if ms.LoadMessageInfo() == nil {2556 if ms.LoadMessageInfo() == nil {
@@ -2475,7 +2563,7 @@ func (x *StreamClosed) ProtoReflect() protoreflect.Message {
2475 2563
2476 // Deprecated: Use StreamClosed.ProtoReflect.Descriptor instead.2564 // Deprecated: Use StreamClosed.ProtoReflect.Descriptor instead.
2477 func (*StreamClosed) Descriptor() ([]byte, []int) {2565 func (*StreamClosed) Descriptor() ([]byte, []int) {
2478- return file_broker_proto_rawDescGZIP(), []int{28}2566+ return file_broker_proto_rawDescGZIP(), []int{29}
2479 }2567 }
2480 2568
2481 func (x *StreamClosed) GetRef() *BrokerStreamRef {2569 func (x *StreamClosed) GetRef() *BrokerStreamRef {
@@ -2504,7 +2592,7 @@ type Progress struct {
2504 2592
2505 func (x *Progress) Reset() {2593 func (x *Progress) Reset() {
2506 *x = Progress{}2594 *x = Progress{}
2507- mi := &file_broker_proto_msgTypes[29]2595+ mi := &file_broker_proto_msgTypes[30]
2508 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2596 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2509 ms.StoreMessageInfo(mi)2597 ms.StoreMessageInfo(mi)
2510 }2598 }
@@ -2516,7 +2604,7 @@ func (x *Progress) String() string {
2516 func (*Progress) ProtoMessage() {}2604 func (*Progress) ProtoMessage() {}
2517 2605
2518 func (x *Progress) ProtoReflect() protoreflect.Message {2606 func (x *Progress) ProtoReflect() protoreflect.Message {
2519- mi := &file_broker_proto_msgTypes[29]2607+ mi := &file_broker_proto_msgTypes[30]
2520 if x != nil {2608 if x != nil {
2521 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2609 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2522 if ms.LoadMessageInfo() == nil {2610 if ms.LoadMessageInfo() == nil {
@@ -2529,7 +2617,7 @@ func (x *Progress) ProtoReflect() protoreflect.Message {
2529 2617
2530 // Deprecated: Use Progress.ProtoReflect.Descriptor instead.2618 // Deprecated: Use Progress.ProtoReflect.Descriptor instead.
2531 func (*Progress) Descriptor() ([]byte, []int) {2619 func (*Progress) Descriptor() ([]byte, []int) {
2532- return file_broker_proto_rawDescGZIP(), []int{29}2620+ return file_broker_proto_rawDescGZIP(), []int{30}
2533 }2621 }
2534 2622
2535 func (x *Progress) GetRef() *BrokerStreamRef {2623 func (x *Progress) GetRef() *BrokerStreamRef {
@@ -2564,7 +2652,7 @@ type BrokerErrorMessage struct {
2564 2652
2565 func (x *BrokerErrorMessage) Reset() {2653 func (x *BrokerErrorMessage) Reset() {
2566 *x = BrokerErrorMessage{}2654 *x = BrokerErrorMessage{}
2567- mi := &file_broker_proto_msgTypes[30]2655+ mi := &file_broker_proto_msgTypes[31]
2568 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2656 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2569 ms.StoreMessageInfo(mi)2657 ms.StoreMessageInfo(mi)
2570 }2658 }
@@ -2576,7 +2664,7 @@ func (x *BrokerErrorMessage) String() string {
2576 func (*BrokerErrorMessage) ProtoMessage() {}2664 func (*BrokerErrorMessage) ProtoMessage() {}
2577 2665
2578 func (x *BrokerErrorMessage) ProtoReflect() protoreflect.Message {2666 func (x *BrokerErrorMessage) ProtoReflect() protoreflect.Message {
2579- mi := &file_broker_proto_msgTypes[30]2667+ mi := &file_broker_proto_msgTypes[31]
2580 if x != nil {2668 if x != nil {
2581 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2669 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2582 if ms.LoadMessageInfo() == nil {2670 if ms.LoadMessageInfo() == nil {
@@ -2589,7 +2677,7 @@ func (x *BrokerErrorMessage) ProtoReflect() protoreflect.Message {
2589 2677
2590 // Deprecated: Use BrokerErrorMessage.ProtoReflect.Descriptor instead.2678 // Deprecated: Use BrokerErrorMessage.ProtoReflect.Descriptor instead.
2591 func (*BrokerErrorMessage) Descriptor() ([]byte, []int) {2679 func (*BrokerErrorMessage) Descriptor() ([]byte, []int) {
2592- return file_broker_proto_rawDescGZIP(), []int{30}2680+ return file_broker_proto_rawDescGZIP(), []int{31}
2593 }2681 }
2594 2682
2595 func (x *BrokerErrorMessage) GetScope() *BrokerScope {2683 func (x *BrokerErrorMessage) GetScope() *BrokerScope {
@@ -2619,7 +2707,7 @@ type Shutdown struct {
2619 2707
2620 func (x *Shutdown) Reset() {2708 func (x *Shutdown) Reset() {
2621 *x = Shutdown{}2709 *x = Shutdown{}
2622- mi := &file_broker_proto_msgTypes[31]2710+ mi := &file_broker_proto_msgTypes[32]
2623 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2711 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2624 ms.StoreMessageInfo(mi)2712 ms.StoreMessageInfo(mi)
2625 }2713 }
@@ -2631,7 +2719,7 @@ func (x *Shutdown) String() string {
2631 func (*Shutdown) ProtoMessage() {}2719 func (*Shutdown) ProtoMessage() {}
2632 2720
2633 func (x *Shutdown) ProtoReflect() protoreflect.Message {2721 func (x *Shutdown) ProtoReflect() protoreflect.Message {
2634- mi := &file_broker_proto_msgTypes[31]2722+ mi := &file_broker_proto_msgTypes[32]
2635 if x != nil {2723 if x != nil {
2636 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2724 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2637 if ms.LoadMessageInfo() == nil {2725 if ms.LoadMessageInfo() == nil {
@@ -2644,7 +2732,7 @@ func (x *Shutdown) ProtoReflect() protoreflect.Message {
2644 2732
2645 // Deprecated: Use Shutdown.ProtoReflect.Descriptor instead.2733 // Deprecated: Use Shutdown.ProtoReflect.Descriptor instead.
2646 func (*Shutdown) Descriptor() ([]byte, []int) {2734 func (*Shutdown) Descriptor() ([]byte, []int) {
2647- return file_broker_proto_rawDescGZIP(), []int{31}2735+ return file_broker_proto_rawDescGZIP(), []int{32}
2648 }2736 }
2649 2737
2650 func (x *Shutdown) GetScope() *BrokerScope {2738 func (x *Shutdown) GetScope() *BrokerScope {
@@ -2683,7 +2771,7 @@ type PreviewRoute struct {
2683 2771
2684 func (x *PreviewRoute) Reset() {2772 func (x *PreviewRoute) Reset() {
2685 *x = PreviewRoute{}2773 *x = PreviewRoute{}
2686- mi := &file_broker_proto_msgTypes[32]2774+ mi := &file_broker_proto_msgTypes[33]
2687 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2775 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2688 ms.StoreMessageInfo(mi)2776 ms.StoreMessageInfo(mi)
2689 }2777 }
@@ -2695,7 +2783,7 @@ func (x *PreviewRoute) String() string {
2695 func (*PreviewRoute) ProtoMessage() {}2783 func (*PreviewRoute) ProtoMessage() {}
2696 2784
2697 func (x *PreviewRoute) ProtoReflect() protoreflect.Message {2785 func (x *PreviewRoute) ProtoReflect() protoreflect.Message {
2698- mi := &file_broker_proto_msgTypes[32]2786+ mi := &file_broker_proto_msgTypes[33]
2699 if x != nil {2787 if x != nil {
2700 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2788 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2701 if ms.LoadMessageInfo() == nil {2789 if ms.LoadMessageInfo() == nil {
@@ -2708,7 +2796,7 @@ func (x *PreviewRoute) ProtoReflect() protoreflect.Message {
2708 2796
2709 // Deprecated: Use PreviewRoute.ProtoReflect.Descriptor instead.2797 // Deprecated: Use PreviewRoute.ProtoReflect.Descriptor instead.
2710 func (*PreviewRoute) Descriptor() ([]byte, []int) {2798 func (*PreviewRoute) Descriptor() ([]byte, []int) {
2711- return file_broker_proto_rawDescGZIP(), []int{32}2799+ return file_broker_proto_rawDescGZIP(), []int{33}
2712 }2800 }
2713 2801
2714 func (x *PreviewRoute) GetLocal() bool {2802 func (x *PreviewRoute) GetLocal() bool {
@@ -2756,7 +2844,7 @@ type StartPreview struct {
2756 2844
2757 func (x *StartPreview) Reset() {2845 func (x *StartPreview) Reset() {
2758 *x = StartPreview{}2846 *x = StartPreview{}
2759- mi := &file_broker_proto_msgTypes[33]2847+ mi := &file_broker_proto_msgTypes[34]
2760 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2848 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2761 ms.StoreMessageInfo(mi)2849 ms.StoreMessageInfo(mi)
2762 }2850 }
@@ -2768,7 +2856,7 @@ func (x *StartPreview) String() string {
2768 func (*StartPreview) ProtoMessage() {}2856 func (*StartPreview) ProtoMessage() {}
2769 2857
2770 func (x *StartPreview) ProtoReflect() protoreflect.Message {2858 func (x *StartPreview) ProtoReflect() protoreflect.Message {
2771- mi := &file_broker_proto_msgTypes[33]2859+ mi := &file_broker_proto_msgTypes[34]
2772 if x != nil {2860 if x != nil {
2773 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2861 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2774 if ms.LoadMessageInfo() == nil {2862 if ms.LoadMessageInfo() == nil {
@@ -2781,7 +2869,7 @@ func (x *StartPreview) ProtoReflect() protoreflect.Message {
2781 2869
2782 // Deprecated: Use StartPreview.ProtoReflect.Descriptor instead.2870 // Deprecated: Use StartPreview.ProtoReflect.Descriptor instead.
2783 func (*StartPreview) Descriptor() ([]byte, []int) {2871 func (*StartPreview) Descriptor() ([]byte, []int) {
2784- return file_broker_proto_rawDescGZIP(), []int{33}2872+ return file_broker_proto_rawDescGZIP(), []int{34}
2785 }2873 }
2786 2874
2787 func (x *StartPreview) GetScope() *BrokerScope {2875 func (x *StartPreview) GetScope() *BrokerScope {
@@ -2823,7 +2911,7 @@ type CancelPreview struct {
2823 2911
2824 func (x *CancelPreview) Reset() {2912 func (x *CancelPreview) Reset() {
2825 *x = CancelPreview{}2913 *x = CancelPreview{}
2826- mi := &file_broker_proto_msgTypes[34]2914+ mi := &file_broker_proto_msgTypes[35]
2827 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2915 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2828 ms.StoreMessageInfo(mi)2916 ms.StoreMessageInfo(mi)
2829 }2917 }
@@ -2835,7 +2923,7 @@ func (x *CancelPreview) String() string {
2835 func (*CancelPreview) ProtoMessage() {}2923 func (*CancelPreview) ProtoMessage() {}
2836 2924
2837 func (x *CancelPreview) ProtoReflect() protoreflect.Message {2925 func (x *CancelPreview) ProtoReflect() protoreflect.Message {
2838- mi := &file_broker_proto_msgTypes[34]2926+ mi := &file_broker_proto_msgTypes[35]
2839 if x != nil {2927 if x != nil {
2840 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2928 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2841 if ms.LoadMessageInfo() == nil {2929 if ms.LoadMessageInfo() == nil {
@@ -2848,7 +2936,7 @@ func (x *CancelPreview) ProtoReflect() protoreflect.Message {
2848 2936
2849 // Deprecated: Use CancelPreview.ProtoReflect.Descriptor instead.2937 // Deprecated: Use CancelPreview.ProtoReflect.Descriptor instead.
2850 func (*CancelPreview) Descriptor() ([]byte, []int) {2938 func (*CancelPreview) Descriptor() ([]byte, []int) {
2851- return file_broker_proto_rawDescGZIP(), []int{34}2939+ return file_broker_proto_rawDescGZIP(), []int{35}
2852 }2940 }
2853 2941
2854 func (x *CancelPreview) GetScope() *BrokerScope {2942 func (x *CancelPreview) GetScope() *BrokerScope {
@@ -2882,7 +2970,7 @@ type PreviewPublication struct {
2882 2970
2883 func (x *PreviewPublication) Reset() {2971 func (x *PreviewPublication) Reset() {
2884 *x = PreviewPublication{}2972 *x = PreviewPublication{}
2885- mi := &file_broker_proto_msgTypes[35]2973+ mi := &file_broker_proto_msgTypes[36]
2886 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2974 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2887 ms.StoreMessageInfo(mi)2975 ms.StoreMessageInfo(mi)
2888 }2976 }
@@ -2894,7 +2982,7 @@ func (x *PreviewPublication) String() string {
2894 func (*PreviewPublication) ProtoMessage() {}2982 func (*PreviewPublication) ProtoMessage() {}
2895 2983
2896 func (x *PreviewPublication) ProtoReflect() protoreflect.Message {2984 func (x *PreviewPublication) ProtoReflect() protoreflect.Message {
2897- mi := &file_broker_proto_msgTypes[35]2985+ mi := &file_broker_proto_msgTypes[36]
2898 if x != nil {2986 if x != nil {
2899 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))2987 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2900 if ms.LoadMessageInfo() == nil {2988 if ms.LoadMessageInfo() == nil {
@@ -2907,7 +2995,7 @@ func (x *PreviewPublication) ProtoReflect() protoreflect.Message {
2907 2995
2908 // Deprecated: Use PreviewPublication.ProtoReflect.Descriptor instead.2996 // Deprecated: Use PreviewPublication.ProtoReflect.Descriptor instead.
2909 func (*PreviewPublication) Descriptor() ([]byte, []int) {2997 func (*PreviewPublication) Descriptor() ([]byte, []int) {
2910- return file_broker_proto_rawDescGZIP(), []int{35}2998+ return file_broker_proto_rawDescGZIP(), []int{36}
2911 }2999 }
2912 3000
2913 func (x *PreviewPublication) GetScope() *BrokerScope {3001 func (x *PreviewPublication) GetScope() *BrokerScope {
@@ -2987,7 +3075,7 @@ type BrokerCatalogSession struct {
2987 3075
2988 func (x *BrokerCatalogSession) Reset() {3076 func (x *BrokerCatalogSession) Reset() {
2989 *x = BrokerCatalogSession{}3077 *x = BrokerCatalogSession{}
2990- mi := &file_broker_proto_msgTypes[36]3078+ mi := &file_broker_proto_msgTypes[37]
2991 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))3079 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
2992 ms.StoreMessageInfo(mi)3080 ms.StoreMessageInfo(mi)
2993 }3081 }
@@ -2999,7 +3087,7 @@ func (x *BrokerCatalogSession) String() string {
2999 func (*BrokerCatalogSession) ProtoMessage() {}3087 func (*BrokerCatalogSession) ProtoMessage() {}
3000 3088
3001 func (x *BrokerCatalogSession) ProtoReflect() protoreflect.Message {3089 func (x *BrokerCatalogSession) ProtoReflect() protoreflect.Message {
3002- mi := &file_broker_proto_msgTypes[36]3090+ mi := &file_broker_proto_msgTypes[37]
3003 if x != nil {3091 if x != nil {
3004 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))3092 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
3005 if ms.LoadMessageInfo() == nil {3093 if ms.LoadMessageInfo() == nil {
@@ -3012,7 +3100,7 @@ func (x *BrokerCatalogSession) ProtoReflect() protoreflect.Message {
3012 3100
3013 // Deprecated: Use BrokerCatalogSession.ProtoReflect.Descriptor instead.3101 // Deprecated: Use BrokerCatalogSession.ProtoReflect.Descriptor instead.
3014 func (*BrokerCatalogSession) Descriptor() ([]byte, []int) {3102 func (*BrokerCatalogSession) Descriptor() ([]byte, []int) {
3015- return file_broker_proto_rawDescGZIP(), []int{36}3103+ return file_broker_proto_rawDescGZIP(), []int{37}
3016 }3104 }
3017 3105
3018 func (x *BrokerCatalogSession) GetLifecycleId() []byte {3106 func (x *BrokerCatalogSession) GetLifecycleId() []byte {
@@ -3092,7 +3180,7 @@ type BrokerCatalogTab struct {
3092 3180
3093 func (x *BrokerCatalogTab) Reset() {3181 func (x *BrokerCatalogTab) Reset() {
3094 *x = BrokerCatalogTab{}3182 *x = BrokerCatalogTab{}
3095- mi := &file_broker_proto_msgTypes[37]3183+ mi := &file_broker_proto_msgTypes[38]
3096 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))3184 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
3097 ms.StoreMessageInfo(mi)3185 ms.StoreMessageInfo(mi)
3098 }3186 }
@@ -3104,7 +3192,7 @@ func (x *BrokerCatalogTab) String() string {
3104 func (*BrokerCatalogTab) ProtoMessage() {}3192 func (*BrokerCatalogTab) ProtoMessage() {}
3105 3193
3106 func (x *BrokerCatalogTab) ProtoReflect() protoreflect.Message {3194 func (x *BrokerCatalogTab) ProtoReflect() protoreflect.Message {
3107- mi := &file_broker_proto_msgTypes[37]3195+ mi := &file_broker_proto_msgTypes[38]
3108 if x != nil {3196 if x != nil {
3109 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))3197 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
3110 if ms.LoadMessageInfo() == nil {3198 if ms.LoadMessageInfo() == nil {
@@ -3117,7 +3205,7 @@ func (x *BrokerCatalogTab) ProtoReflect() protoreflect.Message {
3117 3205
3118 // Deprecated: Use BrokerCatalogTab.ProtoReflect.Descriptor instead.3206 // Deprecated: Use BrokerCatalogTab.ProtoReflect.Descriptor instead.
3119 func (*BrokerCatalogTab) Descriptor() ([]byte, []int) {3207 func (*BrokerCatalogTab) Descriptor() ([]byte, []int) {
3120- return file_broker_proto_rawDescGZIP(), []int{37}3208+ return file_broker_proto_rawDescGZIP(), []int{38}
3121 }3209 }
3122 3210
3123 func (x *BrokerCatalogTab) GetId() string {3211 func (x *BrokerCatalogTab) GetId() string {
@@ -3181,7 +3269,7 @@ const file_broker_proto_rawDesc = "" +
3181 "\ffailure_kind\x18\x04 \x01(\rR\vfailureKind\"A\n" +3269 "\ffailure_kind\x18\x04 \x01(\rR\vfailureKind\"A\n" +
3182 "\x0fBrokerTimestamp\x12\x18\n" +3270 "\x0fBrokerTimestamp\x12\x18\n" +
3183 "\aseconds\x18\x01 \x01(\x03R\aseconds\x12\x14\n" +3271 "\aseconds\x18\x01 \x01(\x03R\aseconds\x12\x14\n" +
3184- "\x05nanos\x18\x02 \x01(\x05R\x05nanos\"\xc2\x06\n" +3272+ "\x05nanos\x18\x02 \x01(\x05R\x05nanos\"\x97\a\n" +
3185 "\x14BrokerClientEnvelope\x123\n" +3273 "\x14BrokerClientEnvelope\x123\n" +
3186 "\bregister\x18e \x01(\v2\x15.vev.wire.v1.RegisterH\x00R\bregister\x126\n" +3274 "\bregister\x18e \x01(\v2\x15.vev.wire.v1.RegisterH\x00R\bregister\x126\n" +
3187 "\tsubscribe\x18f \x01(\v2\x16.vev.wire.v1.SubscribeH\x00R\tsubscribe\x12-\n" +3275 "\tsubscribe\x18f \x01(\v2\x16.vev.wire.v1.SubscribeH\x00R\tsubscribe\x12-\n" +
@@ -3197,8 +3285,9 @@ const file_broker_proto_rawDesc = "" +
3197 "\fclose_stream\x18n \x01(\v2\x18.vev.wire.v1.CloseStreamH\x00R\vcloseStream\x12M\n" +3285 "\fclose_stream\x18n \x01(\v2\x18.vev.wire.v1.CloseStreamH\x00R\vcloseStream\x12M\n" +
3198 "\x12update_host_policy\x18o \x01(\v2\x1d.vev.wire.v1.UpdateHostPolicyH\x00R\x10updateHostPolicy\x12@\n" +3286 "\x12update_host_policy\x18o \x01(\v2\x1d.vev.wire.v1.UpdateHostPolicyH\x00R\x10updateHostPolicy\x12@\n" +
3199 "\rstart_preview\x18p \x01(\v2\x19.vev.wire.v1.StartPreviewH\x00R\fstartPreview\x12C\n" +3287 "\rstart_preview\x18p \x01(\v2\x19.vev.wire.v1.StartPreviewH\x00R\fstartPreview\x12C\n" +
3200- "\x0ecancel_preview\x18q \x01(\v2\x1a.vev.wire.v1.CancelPreviewH\x00R\rcancelPreviewB\t\n" +3288+ "\x0ecancel_preview\x18q \x01(\v2\x1a.vev.wire.v1.CancelPreviewH\x00R\rcancelPreview\x12S\n" +
3201- "\apayload\"\xd9\x05\n" +3289+ "\x14stream_window_update\x18r \x01(\v2\x1f.vev.wire.v1.StreamWindowUpdateH\x00R\x12streamWindowUpdateB\t\n" +
3290+ "\apayload\"\xaf\x06\n" +
3202 "\x14BrokerServerEnvelope\x12:\n" +3291 "\x14BrokerServerEnvelope\x12:\n" +
3203 "\n" +3292 "\n" +
3204 "registered\x18\xc9\x01 \x01(\v2\x17.vev.wire.v1.RegisteredH\x00R\n" +3293 "registered\x18\xc9\x01 \x01(\v2\x17.vev.wire.v1.RegisteredH\x00R\n" +
@@ -3211,7 +3300,8 @@ const file_broker_proto_rawDesc = "" +
3211 "\bprogress\x18\xcf\x01 \x01(\v2\x15.vev.wire.v1.ProgressH\x00R\bprogress\x12T\n" +3300 "\bprogress\x18\xcf\x01 \x01(\v2\x15.vev.wire.v1.ProgressH\x00R\bprogress\x12T\n" +
3212 "\x14broker_error_message\x18\xd0\x01 \x01(\v2\x1f.vev.wire.v1.BrokerErrorMessageH\x00R\x12brokerErrorMessage\x124\n" +3301 "\x14broker_error_message\x18\xd0\x01 \x01(\v2\x1f.vev.wire.v1.BrokerErrorMessageH\x00R\x12brokerErrorMessage\x124\n" +
3213 "\bshutdown\x18\xd1\x01 \x01(\v2\x15.vev.wire.v1.ShutdownH\x00R\bshutdown\x12S\n" +3302 "\bshutdown\x18\xd1\x01 \x01(\v2\x15.vev.wire.v1.ShutdownH\x00R\bshutdown\x12S\n" +
3214- "\x13preview_publication\x18\xd2\x01 \x01(\v2\x1f.vev.wire.v1.PreviewPublicationH\x00R\x12previewPublicationB\t\n" +3303+ "\x13preview_publication\x18\xd2\x01 \x01(\v2\x1f.vev.wire.v1.PreviewPublicationH\x00R\x12previewPublication\x12T\n" +
3304+ "\x14stream_window_update\x18\xd3\x01 \x01(\v2\x1f.vev.wire.v1.StreamWindowUpdateH\x00R\x12streamWindowUpdateB\t\n" +
3215 "\apayload\" \n" +3305 "\apayload\" \n" +
3216 "\bRegister\x12\x14\n" +3306 "\bRegister\x12\x14\n" +
3217 "\x05build\x18\x01 \x01(\tR\x05build\"u\n" +3307 "\x05build\x18\x01 \x01(\tR\x05build\"u\n" +
@@ -3268,7 +3358,10 @@ const file_broker_proto_rawDesc = "" +
3268 "\x03ref\x18\x01 \x01(\v2\x1c.vev.wire.v1.BrokerStreamRefR\x03ref\x12\x12\n" +3358 "\x03ref\x18\x01 \x01(\v2\x1c.vev.wire.v1.BrokerStreamRefR\x03ref\x12\x12\n" +
3269 "\x04data\x18\x02 \x01(\fR\x04data\"=\n" +3359 "\x04data\x18\x02 \x01(\fR\x04data\"=\n" +
3270 "\vCloseStream\x12.\n" +3360 "\vCloseStream\x12.\n" +
3271- "\x03ref\x18\x01 \x01(\v2\x1c.vev.wire.v1.BrokerStreamRefR\x03ref\"n\n" +3361+ "\x03ref\x18\x01 \x01(\v2\x1c.vev.wire.v1.BrokerStreamRefR\x03ref\"\\\n" +
3362+ "\x12StreamWindowUpdate\x12.\n" +
3363+ "\x03ref\x18\x01 \x01(\v2\x1c.vev.wire.v1.BrokerStreamRefR\x03ref\x12\x16\n" +
3364+ "\x06credit\x18\x02 \x01(\x04R\x06credit\"n\n" +
3272 "\n" +3365 "\n" +
3273 "Registered\x12.\n" +3366 "Registered\x12.\n" +
3274 "\x05scope\x18\x01 \x01(\v2\x18.vev.wire.v1.BrokerScopeR\x05scope\x12\x14\n" +3367 "\x05scope\x18\x01 \x01(\v2\x18.vev.wire.v1.BrokerScopeR\x05scope\x12\x14\n" +
@@ -3409,7 +3502,7 @@ func file_broker_proto_rawDescGZIP() []byte {
3409 return file_broker_proto_rawDescData3502 return file_broker_proto_rawDescData
3410 }3503 }
3411 3504
3412-var file_broker_proto_msgTypes = make([]protoimpl.MessageInfo, 38)3505+var file_broker_proto_msgTypes = make([]protoimpl.MessageInfo, 39)
3413 var file_broker_proto_goTypes = []any{3506 var file_broker_proto_goTypes = []any{
3414 (*BrokerScope)(nil), // 0: vev.wire.v1.BrokerScope3507 (*BrokerScope)(nil), // 0: vev.wire.v1.BrokerScope
3415 (*BrokerStreamRef)(nil), // 1: vev.wire.v1.BrokerStreamRef3508 (*BrokerStreamRef)(nil), // 1: vev.wire.v1.BrokerStreamRef
@@ -3429,30 +3522,31 @@ var file_broker_proto_goTypes = []any{
3429 (*OpenStream)(nil), // 15: vev.wire.v1.OpenStream3522 (*OpenStream)(nil), // 15: vev.wire.v1.OpenStream
3430 (*ClientStreamData)(nil), // 16: vev.wire.v1.ClientStreamData3523 (*ClientStreamData)(nil), // 16: vev.wire.v1.ClientStreamData
3431 (*CloseStream)(nil), // 17: vev.wire.v1.CloseStream3524 (*CloseStream)(nil), // 17: vev.wire.v1.CloseStream
3432- (*Registered)(nil), // 18: vev.wire.v1.Registered3525+ (*StreamWindowUpdate)(nil), // 18: vev.wire.v1.StreamWindowUpdate
3433- (*SnapshotPart)(nil), // 19: vev.wire.v1.SnapshotPart3526+ (*Registered)(nil), // 19: vev.wire.v1.Registered
3434- (*SnapshotBegin)(nil), // 20: vev.wire.v1.SnapshotBegin3527+ (*SnapshotPart)(nil), // 20: vev.wire.v1.SnapshotPart
3435- (*SnapshotDaemon)(nil), // 21: vev.wire.v1.SnapshotDaemon3528+ (*SnapshotBegin)(nil), // 21: vev.wire.v1.SnapshotBegin
3436- (*SnapshotSession)(nil), // 22: vev.wire.v1.SnapshotSession3529+ (*SnapshotDaemon)(nil), // 22: vev.wire.v1.SnapshotDaemon
3437- (*SnapshotTombstone)(nil), // 23: vev.wire.v1.SnapshotTombstone3530+ (*SnapshotSession)(nil), // 23: vev.wire.v1.SnapshotSession
3438- (*SnapshotEnd)(nil), // 24: vev.wire.v1.SnapshotEnd3531+ (*SnapshotTombstone)(nil), // 24: vev.wire.v1.SnapshotTombstone
3439- (*OperationResult)(nil), // 25: vev.wire.v1.OperationResult3532+ (*SnapshotEnd)(nil), // 25: vev.wire.v1.SnapshotEnd
3440- (*StreamOpened)(nil), // 26: vev.wire.v1.StreamOpened3533+ (*OperationResult)(nil), // 26: vev.wire.v1.OperationResult
3441- (*ServerStreamData)(nil), // 27: vev.wire.v1.ServerStreamData3534+ (*StreamOpened)(nil), // 27: vev.wire.v1.StreamOpened
3442- (*StreamClosed)(nil), // 28: vev.wire.v1.StreamClosed3535+ (*ServerStreamData)(nil), // 28: vev.wire.v1.ServerStreamData
3443- (*Progress)(nil), // 29: vev.wire.v1.Progress3536+ (*StreamClosed)(nil), // 29: vev.wire.v1.StreamClosed
3444- (*BrokerErrorMessage)(nil), // 30: vev.wire.v1.BrokerErrorMessage3537+ (*Progress)(nil), // 30: vev.wire.v1.Progress
3445- (*Shutdown)(nil), // 31: vev.wire.v1.Shutdown3538+ (*BrokerErrorMessage)(nil), // 31: vev.wire.v1.BrokerErrorMessage
3446- (*PreviewRoute)(nil), // 32: vev.wire.v1.PreviewRoute3539+ (*Shutdown)(nil), // 32: vev.wire.v1.Shutdown
3447- (*StartPreview)(nil), // 33: vev.wire.v1.StartPreview3540+ (*PreviewRoute)(nil), // 33: vev.wire.v1.PreviewRoute
3448- (*CancelPreview)(nil), // 34: vev.wire.v1.CancelPreview3541+ (*StartPreview)(nil), // 34: vev.wire.v1.StartPreview
3449- (*PreviewPublication)(nil), // 35: vev.wire.v1.PreviewPublication3542+ (*CancelPreview)(nil), // 35: vev.wire.v1.CancelPreview
3450- (*BrokerCatalogSession)(nil), // 36: vev.wire.v1.BrokerCatalogSession3543+ (*PreviewPublication)(nil), // 36: vev.wire.v1.PreviewPublication
3451- (*BrokerCatalogTab)(nil), // 37: vev.wire.v1.BrokerCatalogTab3544+ (*BrokerCatalogSession)(nil), // 37: vev.wire.v1.BrokerCatalogSession
3452- (*RemoteRegistration)(nil), // 38: vev.wire.v1.RemoteRegistration3545+ (*BrokerCatalogTab)(nil), // 38: vev.wire.v1.BrokerCatalogTab
3453- (*ExactTarget)(nil), // 39: vev.wire.v1.ExactTarget3546+ (*RemoteRegistration)(nil), // 39: vev.wire.v1.RemoteRegistration
3454- (*RemotePreviewRequest)(nil), // 40: vev.wire.v1.RemotePreviewRequest3547+ (*ExactTarget)(nil), // 40: vev.wire.v1.ExactTarget
3455- (*RemotePreview)(nil), // 41: vev.wire.v1.RemotePreview3548+ (*RemotePreviewRequest)(nil), // 41: vev.wire.v1.RemotePreviewRequest
3549+ (*RemotePreview)(nil), // 42: vev.wire.v1.RemotePreview
3456 }3550 }
3457 var file_broker_proto_depIdxs = []int32{3551 var file_broker_proto_depIdxs = []int32{
3458 0, // 0: vev.wire.v1.BrokerStreamRef.scope:type_name -> vev.wire.v1.BrokerScope3552 0, // 0: vev.wire.v1.BrokerStreamRef.scope:type_name -> vev.wire.v1.BrokerScope
@@ -3467,76 +3561,79 @@ var file_broker_proto_depIdxs = []int32{
3467 16, // 9: vev.wire.v1.BrokerClientEnvelope.client_stream_data:type_name -> vev.wire.v1.ClientStreamData3561 16, // 9: vev.wire.v1.BrokerClientEnvelope.client_stream_data:type_name -> vev.wire.v1.ClientStreamData
3468 17, // 10: vev.wire.v1.BrokerClientEnvelope.close_stream:type_name -> vev.wire.v1.CloseStream3562 17, // 10: vev.wire.v1.BrokerClientEnvelope.close_stream:type_name -> vev.wire.v1.CloseStream
3469 13, // 11: vev.wire.v1.BrokerClientEnvelope.update_host_policy:type_name -> vev.wire.v1.UpdateHostPolicy3563 13, // 11: vev.wire.v1.BrokerClientEnvelope.update_host_policy:type_name -> vev.wire.v1.UpdateHostPolicy
3470- 33, // 12: vev.wire.v1.BrokerClientEnvelope.start_preview:type_name -> vev.wire.v1.StartPreview3564+ 34, // 12: vev.wire.v1.BrokerClientEnvelope.start_preview:type_name -> vev.wire.v1.StartPreview
3471- 34, // 13: vev.wire.v1.BrokerClientEnvelope.cancel_preview:type_name -> vev.wire.v1.CancelPreview3565+ 35, // 13: vev.wire.v1.BrokerClientEnvelope.cancel_preview:type_name -> vev.wire.v1.CancelPreview
3472- 18, // 14: vev.wire.v1.BrokerServerEnvelope.registered:type_name -> vev.wire.v1.Registered3566+ 18, // 14: vev.wire.v1.BrokerClientEnvelope.stream_window_update:type_name -> vev.wire.v1.StreamWindowUpdate
3473- 19, // 15: vev.wire.v1.BrokerServerEnvelope.snapshot_part:type_name -> vev.wire.v1.SnapshotPart3567+ 19, // 15: vev.wire.v1.BrokerServerEnvelope.registered:type_name -> vev.wire.v1.Registered
3474- 25, // 16: vev.wire.v1.BrokerServerEnvelope.operation_result:type_name -> vev.wire.v1.OperationResult3568+ 20, // 16: vev.wire.v1.BrokerServerEnvelope.snapshot_part:type_name -> vev.wire.v1.SnapshotPart
3475- 26, // 17: vev.wire.v1.BrokerServerEnvelope.stream_opened:type_name -> vev.wire.v1.StreamOpened3569+ 26, // 17: vev.wire.v1.BrokerServerEnvelope.operation_result:type_name -> vev.wire.v1.OperationResult
3476- 27, // 18: vev.wire.v1.BrokerServerEnvelope.server_stream_data:type_name -> vev.wire.v1.ServerStreamData3570+ 27, // 18: vev.wire.v1.BrokerServerEnvelope.stream_opened:type_name -> vev.wire.v1.StreamOpened
3477- 28, // 19: vev.wire.v1.BrokerServerEnvelope.stream_closed:type_name -> vev.wire.v1.StreamClosed3571+ 28, // 19: vev.wire.v1.BrokerServerEnvelope.server_stream_data:type_name -> vev.wire.v1.ServerStreamData
3478- 29, // 20: vev.wire.v1.BrokerServerEnvelope.progress:type_name -> vev.wire.v1.Progress3572+ 29, // 20: vev.wire.v1.BrokerServerEnvelope.stream_closed:type_name -> vev.wire.v1.StreamClosed
3479- 30, // 21: vev.wire.v1.BrokerServerEnvelope.broker_error_message:type_name -> vev.wire.v1.BrokerErrorMessage3573+ 30, // 21: vev.wire.v1.BrokerServerEnvelope.progress:type_name -> vev.wire.v1.Progress
3480- 31, // 22: vev.wire.v1.BrokerServerEnvelope.shutdown:type_name -> vev.wire.v1.Shutdown3574+ 31, // 22: vev.wire.v1.BrokerServerEnvelope.broker_error_message:type_name -> vev.wire.v1.BrokerErrorMessage
3481- 35, // 23: vev.wire.v1.BrokerServerEnvelope.preview_publication:type_name -> vev.wire.v1.PreviewPublication3575+ 32, // 23: vev.wire.v1.BrokerServerEnvelope.shutdown:type_name -> vev.wire.v1.Shutdown
3482- 0, // 24: vev.wire.v1.Subscribe.scope:type_name -> vev.wire.v1.BrokerScope3576+ 36, // 24: vev.wire.v1.BrokerServerEnvelope.preview_publication:type_name -> vev.wire.v1.PreviewPublication
3483- 0, // 25: vev.wire.v1.Resync.scope:type_name -> vev.wire.v1.BrokerScope3577+ 18, // 25: vev.wire.v1.BrokerServerEnvelope.stream_window_update:type_name -> vev.wire.v1.StreamWindowUpdate
3484- 0, // 26: vev.wire.v1.Unsubscribe.scope:type_name -> vev.wire.v1.BrokerScope3578+ 0, // 26: vev.wire.v1.Subscribe.scope:type_name -> vev.wire.v1.BrokerScope
3485- 0, // 27: vev.wire.v1.AddHost.scope:type_name -> vev.wire.v1.BrokerScope3579+ 0, // 27: vev.wire.v1.Resync.scope:type_name -> vev.wire.v1.BrokerScope
3486- 2, // 28: vev.wire.v1.AddHost.policy:type_name -> vev.wire.v1.BrokerWirePolicy3580+ 0, // 28: vev.wire.v1.Unsubscribe.scope:type_name -> vev.wire.v1.BrokerScope
3487- 0, // 29: vev.wire.v1.RemoveHost.scope:type_name -> vev.wire.v1.BrokerScope3581+ 0, // 29: vev.wire.v1.AddHost.scope:type_name -> vev.wire.v1.BrokerScope
3488- 38, // 30: vev.wire.v1.RemoveHost.registration:type_name -> vev.wire.v1.RemoteRegistration3582+ 2, // 30: vev.wire.v1.AddHost.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3489- 0, // 31: vev.wire.v1.UpdateHostPolicy.scope:type_name -> vev.wire.v1.BrokerScope3583+ 0, // 31: vev.wire.v1.RemoveHost.scope:type_name -> vev.wire.v1.BrokerScope
3490- 38, // 32: vev.wire.v1.UpdateHostPolicy.registration:type_name -> vev.wire.v1.RemoteRegistration3584+ 39, // 32: vev.wire.v1.RemoveHost.registration:type_name -> vev.wire.v1.RemoteRegistration
3491- 2, // 33: vev.wire.v1.UpdateHostPolicy.policy:type_name -> vev.wire.v1.BrokerWirePolicy3585+ 0, // 33: vev.wire.v1.UpdateHostPolicy.scope:type_name -> vev.wire.v1.BrokerScope
3492- 0, // 34: vev.wire.v1.Reconcile.scope:type_name -> vev.wire.v1.BrokerScope3586+ 39, // 34: vev.wire.v1.UpdateHostPolicy.registration:type_name -> vev.wire.v1.RemoteRegistration
3493- 38, // 35: vev.wire.v1.Reconcile.registration:type_name -> vev.wire.v1.RemoteRegistration3587+ 2, // 35: vev.wire.v1.UpdateHostPolicy.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3494- 1, // 36: vev.wire.v1.OpenStream.ref:type_name -> vev.wire.v1.BrokerStreamRef3588+ 0, // 36: vev.wire.v1.Reconcile.scope:type_name -> vev.wire.v1.BrokerScope
3495- 38, // 37: vev.wire.v1.OpenStream.registration:type_name -> vev.wire.v1.RemoteRegistration3589+ 39, // 37: vev.wire.v1.Reconcile.registration:type_name -> vev.wire.v1.RemoteRegistration
3496- 39, // 38: vev.wire.v1.OpenStream.target:type_name -> vev.wire.v1.ExactTarget3590+ 1, // 38: vev.wire.v1.OpenStream.ref:type_name -> vev.wire.v1.BrokerStreamRef
3497- 2, // 39: vev.wire.v1.OpenStream.policy:type_name -> vev.wire.v1.BrokerWirePolicy3591+ 39, // 39: vev.wire.v1.OpenStream.registration:type_name -> vev.wire.v1.RemoteRegistration
3498- 1, // 40: vev.wire.v1.ClientStreamData.ref:type_name -> vev.wire.v1.BrokerStreamRef3592+ 40, // 40: vev.wire.v1.OpenStream.target:type_name -> vev.wire.v1.ExactTarget
3499- 1, // 41: vev.wire.v1.CloseStream.ref:type_name -> vev.wire.v1.BrokerStreamRef3593+ 2, // 41: vev.wire.v1.OpenStream.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3500- 0, // 42: vev.wire.v1.Registered.scope:type_name -> vev.wire.v1.BrokerScope3594+ 1, // 42: vev.wire.v1.ClientStreamData.ref:type_name -> vev.wire.v1.BrokerStreamRef
3501- 0, // 43: vev.wire.v1.SnapshotPart.scope:type_name -> vev.wire.v1.BrokerScope3595+ 1, // 43: vev.wire.v1.CloseStream.ref:type_name -> vev.wire.v1.BrokerStreamRef
3502- 20, // 44: vev.wire.v1.SnapshotPart.begin:type_name -> vev.wire.v1.SnapshotBegin3596+ 1, // 44: vev.wire.v1.StreamWindowUpdate.ref:type_name -> vev.wire.v1.BrokerStreamRef
3503- 21, // 45: vev.wire.v1.SnapshotPart.daemon:type_name -> vev.wire.v1.SnapshotDaemon3597+ 0, // 45: vev.wire.v1.Registered.scope:type_name -> vev.wire.v1.BrokerScope
3504- 22, // 46: vev.wire.v1.SnapshotPart.session:type_name -> vev.wire.v1.SnapshotSession3598+ 0, // 46: vev.wire.v1.SnapshotPart.scope:type_name -> vev.wire.v1.BrokerScope
3505- 23, // 47: vev.wire.v1.SnapshotPart.tombstone:type_name -> vev.wire.v1.SnapshotTombstone3599+ 21, // 47: vev.wire.v1.SnapshotPart.begin:type_name -> vev.wire.v1.SnapshotBegin
3506- 24, // 48: vev.wire.v1.SnapshotPart.end:type_name -> vev.wire.v1.SnapshotEnd3600+ 22, // 48: vev.wire.v1.SnapshotPart.daemon:type_name -> vev.wire.v1.SnapshotDaemon
3507- 38, // 49: vev.wire.v1.SnapshotDaemon.registration:type_name -> vev.wire.v1.RemoteRegistration3601+ 23, // 49: vev.wire.v1.SnapshotPart.session:type_name -> vev.wire.v1.SnapshotSession
3508- 2, // 50: vev.wire.v1.SnapshotDaemon.policy:type_name -> vev.wire.v1.BrokerWirePolicy3602+ 24, // 50: vev.wire.v1.SnapshotPart.tombstone:type_name -> vev.wire.v1.SnapshotTombstone
3509- 4, // 51: vev.wire.v1.SnapshotDaemon.last_attempt:type_name -> vev.wire.v1.BrokerTimestamp3603+ 25, // 51: vev.wire.v1.SnapshotPart.end:type_name -> vev.wire.v1.SnapshotEnd
3510- 4, // 52: vev.wire.v1.SnapshotDaemon.last_success:type_name -> vev.wire.v1.BrokerTimestamp3604+ 39, // 52: vev.wire.v1.SnapshotDaemon.registration:type_name -> vev.wire.v1.RemoteRegistration
3511- 4, // 53: vev.wire.v1.SnapshotDaemon.next_due:type_name -> vev.wire.v1.BrokerTimestamp3605+ 2, // 53: vev.wire.v1.SnapshotDaemon.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3512- 36, // 54: vev.wire.v1.SnapshotSession.session:type_name -> vev.wire.v1.BrokerCatalogSession3606+ 4, // 54: vev.wire.v1.SnapshotDaemon.last_attempt:type_name -> vev.wire.v1.BrokerTimestamp
3513- 38, // 55: vev.wire.v1.SnapshotTombstone.registration:type_name -> vev.wire.v1.RemoteRegistration3607+ 4, // 55: vev.wire.v1.SnapshotDaemon.last_success:type_name -> vev.wire.v1.BrokerTimestamp
3514- 0, // 56: vev.wire.v1.OperationResult.scope:type_name -> vev.wire.v1.BrokerScope3608+ 4, // 56: vev.wire.v1.SnapshotDaemon.next_due:type_name -> vev.wire.v1.BrokerTimestamp
3515- 3, // 57: vev.wire.v1.OperationResult.error:type_name -> vev.wire.v1.BrokerErrorDetail3609+ 37, // 57: vev.wire.v1.SnapshotSession.session:type_name -> vev.wire.v1.BrokerCatalogSession
3516- 38, // 58: vev.wire.v1.OperationResult.registration:type_name -> vev.wire.v1.RemoteRegistration3610+ 39, // 58: vev.wire.v1.SnapshotTombstone.registration:type_name -> vev.wire.v1.RemoteRegistration
3517- 1, // 59: vev.wire.v1.StreamOpened.ref:type_name -> vev.wire.v1.BrokerStreamRef3611+ 0, // 59: vev.wire.v1.OperationResult.scope:type_name -> vev.wire.v1.BrokerScope
3518- 1, // 60: vev.wire.v1.ServerStreamData.ref:type_name -> vev.wire.v1.BrokerStreamRef3612+ 3, // 60: vev.wire.v1.OperationResult.error:type_name -> vev.wire.v1.BrokerErrorDetail
3519- 1, // 61: vev.wire.v1.StreamClosed.ref:type_name -> vev.wire.v1.BrokerStreamRef3613+ 39, // 61: vev.wire.v1.OperationResult.registration:type_name -> vev.wire.v1.RemoteRegistration
3520- 3, // 62: vev.wire.v1.StreamClosed.error:type_name -> vev.wire.v1.BrokerErrorDetail3614+ 1, // 62: vev.wire.v1.StreamOpened.ref:type_name -> vev.wire.v1.BrokerStreamRef
3521- 1, // 63: vev.wire.v1.Progress.ref:type_name -> vev.wire.v1.BrokerStreamRef3615+ 1, // 63: vev.wire.v1.ServerStreamData.ref:type_name -> vev.wire.v1.BrokerStreamRef
3522- 0, // 64: vev.wire.v1.BrokerErrorMessage.scope:type_name -> vev.wire.v1.BrokerScope3616+ 1, // 64: vev.wire.v1.StreamClosed.ref:type_name -> vev.wire.v1.BrokerStreamRef
3523- 3, // 65: vev.wire.v1.BrokerErrorMessage.error:type_name -> vev.wire.v1.BrokerErrorDetail3617+ 3, // 65: vev.wire.v1.StreamClosed.error:type_name -> vev.wire.v1.BrokerErrorDetail
3524- 0, // 66: vev.wire.v1.Shutdown.scope:type_name -> vev.wire.v1.BrokerScope3618+ 1, // 66: vev.wire.v1.Progress.ref:type_name -> vev.wire.v1.BrokerStreamRef
3525- 38, // 67: vev.wire.v1.PreviewRoute.registration:type_name -> vev.wire.v1.RemoteRegistration3619+ 0, // 67: vev.wire.v1.BrokerErrorMessage.scope:type_name -> vev.wire.v1.BrokerScope
3526- 2, // 68: vev.wire.v1.PreviewRoute.policy:type_name -> vev.wire.v1.BrokerWirePolicy3620+ 3, // 68: vev.wire.v1.BrokerErrorMessage.error:type_name -> vev.wire.v1.BrokerErrorDetail
3527- 0, // 69: vev.wire.v1.StartPreview.scope:type_name -> vev.wire.v1.BrokerScope3621+ 0, // 69: vev.wire.v1.Shutdown.scope:type_name -> vev.wire.v1.BrokerScope
3528- 40, // 70: vev.wire.v1.StartPreview.preview:type_name -> vev.wire.v1.RemotePreviewRequest3622+ 39, // 70: vev.wire.v1.PreviewRoute.registration:type_name -> vev.wire.v1.RemoteRegistration
3529- 32, // 71: vev.wire.v1.StartPreview.route:type_name -> vev.wire.v1.PreviewRoute3623+ 2, // 71: vev.wire.v1.PreviewRoute.policy:type_name -> vev.wire.v1.BrokerWirePolicy
3530- 0, // 72: vev.wire.v1.CancelPreview.scope:type_name -> vev.wire.v1.BrokerScope3624+ 0, // 72: vev.wire.v1.StartPreview.scope:type_name -> vev.wire.v1.BrokerScope
3531- 0, // 73: vev.wire.v1.PreviewPublication.scope:type_name -> vev.wire.v1.BrokerScope3625+ 41, // 73: vev.wire.v1.StartPreview.preview:type_name -> vev.wire.v1.RemotePreviewRequest
3532- 41, // 74: vev.wire.v1.PreviewPublication.preview:type_name -> vev.wire.v1.RemotePreview3626+ 33, // 74: vev.wire.v1.StartPreview.route:type_name -> vev.wire.v1.PreviewRoute
3533- 3, // 75: vev.wire.v1.PreviewPublication.error:type_name -> vev.wire.v1.BrokerErrorDetail3627+ 0, // 75: vev.wire.v1.CancelPreview.scope:type_name -> vev.wire.v1.BrokerScope
3534- 37, // 76: vev.wire.v1.BrokerCatalogSession.tabs:type_name -> vev.wire.v1.BrokerCatalogTab3628+ 0, // 76: vev.wire.v1.PreviewPublication.scope:type_name -> vev.wire.v1.BrokerScope
3535- 77, // [77:77] is the sub-list for method output_type3629+ 42, // 77: vev.wire.v1.PreviewPublication.preview:type_name -> vev.wire.v1.RemotePreview
3536- 77, // [77:77] is the sub-list for method input_type3630+ 3, // 78: vev.wire.v1.PreviewPublication.error:type_name -> vev.wire.v1.BrokerErrorDetail
3537- 77, // [77:77] is the sub-list for extension type_name3631+ 38, // 79: vev.wire.v1.BrokerCatalogSession.tabs:type_name -> vev.wire.v1.BrokerCatalogTab
3538- 77, // [77:77] is the sub-list for extension extendee3632+ 80, // [80:80] is the sub-list for method output_type
3539- 0, // [0:77] is the sub-list for field type_name3633+ 80, // [80:80] is the sub-list for method input_type
3634+ 80, // [80:80] is the sub-list for extension type_name
3635+ 80, // [80:80] is the sub-list for extension extendee
3636+ 0, // [0:80] is the sub-list for field type_name
3540 }3637 }
3541 3638
3542 func init() { file_broker_proto_init() }3639 func init() { file_broker_proto_init() }
@@ -3560,6 +3657,7 @@ func file_broker_proto_init() {
3560 (*BrokerClientEnvelope_UpdateHostPolicy)(nil),3657 (*BrokerClientEnvelope_UpdateHostPolicy)(nil),
3561 (*BrokerClientEnvelope_StartPreview)(nil),3658 (*BrokerClientEnvelope_StartPreview)(nil),
3562 (*BrokerClientEnvelope_CancelPreview)(nil),3659 (*BrokerClientEnvelope_CancelPreview)(nil),
3660+ (*BrokerClientEnvelope_StreamWindowUpdate)(nil),
3563 }3661 }
3564 file_broker_proto_msgTypes[6].OneofWrappers = []any{3662 file_broker_proto_msgTypes[6].OneofWrappers = []any{
3565 (*BrokerServerEnvelope_Registered)(nil),3663 (*BrokerServerEnvelope_Registered)(nil),
@@ -3572,15 +3670,16 @@ func file_broker_proto_init() {
3572 (*BrokerServerEnvelope_BrokerErrorMessage)(nil),3670 (*BrokerServerEnvelope_BrokerErrorMessage)(nil),
3573 (*BrokerServerEnvelope_Shutdown)(nil),3671 (*BrokerServerEnvelope_Shutdown)(nil),
3574 (*BrokerServerEnvelope_PreviewPublication)(nil),3672 (*BrokerServerEnvelope_PreviewPublication)(nil),
3673+ (*BrokerServerEnvelope_StreamWindowUpdate)(nil),
3575 }3674 }
3576- file_broker_proto_msgTypes[19].OneofWrappers = []any{3675+ file_broker_proto_msgTypes[20].OneofWrappers = []any{
3577 (*SnapshotPart_Begin)(nil),3676 (*SnapshotPart_Begin)(nil),
3578 (*SnapshotPart_Daemon)(nil),3677 (*SnapshotPart_Daemon)(nil),
3579 (*SnapshotPart_Session)(nil),3678 (*SnapshotPart_Session)(nil),
3580 (*SnapshotPart_Tombstone)(nil),3679 (*SnapshotPart_Tombstone)(nil),
3581 (*SnapshotPart_End)(nil),3680 (*SnapshotPart_End)(nil),
3582 }3681 }
3583- file_broker_proto_msgTypes[35].OneofWrappers = []any{3682+ file_broker_proto_msgTypes[36].OneofWrappers = []any{
3584 (*PreviewPublication_Preview)(nil),3683 (*PreviewPublication_Preview)(nil),
3585 (*PreviewPublication_Error)(nil),3684 (*PreviewPublication_Error)(nil),
3586 }3685 }
@@ -3590,7 +3689,7 @@ func file_broker_proto_init() {
3590 GoPackagePath: reflect.TypeOf(x{}).PkgPath(),3689 GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
3591 RawDescriptor: unsafe.Slice(unsafe.StringData(file_broker_proto_rawDesc), len(file_broker_proto_rawDesc)),3690 RawDescriptor: unsafe.Slice(unsafe.StringData(file_broker_proto_rawDesc), len(file_broker_proto_rawDesc)),
3592 NumEnums: 0,3691 NumEnums: 0,
3593- NumMessages: 38,3692+ NumMessages: 39,
3594 NumExtensions: 0,3693 NumExtensions: 0,
3595 NumServices: 0,3694 NumServices: 0,
3596 },3695 },
M internal/protocol/wire/broker_test.go +8 -2
@@ -20,7 +20,7 @@ var brokerClientTags = map[string]protoreflect.FieldNumber{
2020 "register": 101, "subscribe": 102, "resync": 103, "unsubscribe": 104,
2121 "add_host": 105, "remove_host": 106, "reconcile": 107, "open_stream": 108,
2222 "client_stream_data": 109, "close_stream": 110, "update_host_policy": 111,
23- "start_preview": 112, "cancel_preview": 113,
23+ "start_preview": 112, "cancel_preview": 113, "stream_window_update": 114,
2424 }
2525
2626 // brokerServerTags is the frozen server tag inventory.
@@ -28,7 +28,7 @@ var brokerServerTags = map[string]protoreflect.FieldNumber{
2828 "registered": 201, "snapshot_part": 202, "operation_result": 203,
2929 "stream_opened": 204, "server_stream_data": 205, "stream_closed": 206,
3030 "progress": 207, "broker_error_message": 208, "shutdown": 209,
31- "preview_publication": 210,
31+ "preview_publication": 210, "stream_window_update": 211,
3232 }
3333
3434 func oneofTags(t *testing.T, message proto.Message) map[string]protoreflect.FieldNumber {
@@ -194,6 +194,9 @@ func brokerClientSamples() map[string]*BrokerClientEnvelope {
194194 "cancel_preview": {Payload: &BrokerClientEnvelope_CancelPreview{CancelPreview: &CancelPreview{
195195 Scope: brokerScope(), Generation: 3,
196196 }}},
197+ "stream_window_update": {Payload: &BrokerClientEnvelope_StreamWindowUpdate{StreamWindowUpdate: &StreamWindowUpdate{
198+ Ref: brokerRef(), Credit: 4096,
199+ }}},
197200 }
198201 }
199202
@@ -241,6 +244,9 @@ func brokerServerSamples() map[string]*BrokerServerEnvelope {
241244 Scope: brokerScope(), Generation: 3,
242245 Result: &PreviewPublication_Error{Error: &BrokerErrorDetail{Code: 1, Text: "unavailable"}},
243246 }}},
247+ "stream_window_update": {Payload: &BrokerServerEnvelope_StreamWindowUpdate{StreamWindowUpdate: &StreamWindowUpdate{
248+ Ref: brokerRef(), Credit: 4096,
249+ }}},
244250 }
245251 }
246252
@@ -20,7 +20,7 @@ var brokerClientTags = map[string]protoreflect.FieldNumber{
20 "register": 101, "subscribe": 102, "resync": 103, "unsubscribe": 104,20 "register": 101, "subscribe": 102, "resync": 103, "unsubscribe": 104,
21 "add_host": 105, "remove_host": 106, "reconcile": 107, "open_stream": 108,21 "add_host": 105, "remove_host": 106, "reconcile": 107, "open_stream": 108,
22 "client_stream_data": 109, "close_stream": 110, "update_host_policy": 111,22 "client_stream_data": 109, "close_stream": 110, "update_host_policy": 111,
23- "start_preview": 112, "cancel_preview": 113,23+ "start_preview": 112, "cancel_preview": 113, "stream_window_update": 114,
24 }24 }
25 25
26 // brokerServerTags is the frozen server tag inventory.26 // brokerServerTags is the frozen server tag inventory.
@@ -28,7 +28,7 @@ var brokerServerTags = map[string]protoreflect.FieldNumber{
28 "registered": 201, "snapshot_part": 202, "operation_result": 203,28 "registered": 201, "snapshot_part": 202, "operation_result": 203,
29 "stream_opened": 204, "server_stream_data": 205, "stream_closed": 206,29 "stream_opened": 204, "server_stream_data": 205, "stream_closed": 206,
30 "progress": 207, "broker_error_message": 208, "shutdown": 209,30 "progress": 207, "broker_error_message": 208, "shutdown": 209,
31- "preview_publication": 210,31+ "preview_publication": 210, "stream_window_update": 211,
32 }32 }
33 33
34 func oneofTags(t *testing.T, message proto.Message) map[string]protoreflect.FieldNumber {34 func oneofTags(t *testing.T, message proto.Message) map[string]protoreflect.FieldNumber {
@@ -194,6 +194,9 @@ func brokerClientSamples() map[string]*BrokerClientEnvelope {
194 "cancel_preview": {Payload: &BrokerClientEnvelope_CancelPreview{CancelPreview: &CancelPreview{194 "cancel_preview": {Payload: &BrokerClientEnvelope_CancelPreview{CancelPreview: &CancelPreview{
195 Scope: brokerScope(), Generation: 3,195 Scope: brokerScope(), Generation: 3,
196 }}},196 }}},
197+ "stream_window_update": {Payload: &BrokerClientEnvelope_StreamWindowUpdate{StreamWindowUpdate: &StreamWindowUpdate{
198+ Ref: brokerRef(), Credit: 4096,
199+ }}},
197 }200 }
198 }201 }
199 202
@@ -241,6 +244,9 @@ func brokerServerSamples() map[string]*BrokerServerEnvelope {
241 Scope: brokerScope(), Generation: 3,244 Scope: brokerScope(), Generation: 3,
242 Result: &PreviewPublication_Error{Error: &BrokerErrorDetail{Code: 1, Text: "unavailable"}},245 Result: &PreviewPublication_Error{Error: &BrokerErrorDetail{Code: 1, Text: "unavailable"}},
243 }}},246 }}},
247+ "stream_window_update": {Payload: &BrokerServerEnvelope_StreamWindowUpdate{StreamWindowUpdate: &StreamWindowUpdate{
248+ Ref: brokerRef(), Credit: 4096,
249+ }}},
244 }250 }
245 }251 }
246 252
M internal/protocol/wire/envelope_inventory_test.go +2 -2
@@ -15,8 +15,8 @@ import (
1515 // shares a payload type except route navigation failure, and the preamble
1616 // constants agree with the schema authority.
1717 func TestEnvelopeInventoryProvesDirectionAndSemanticPath(t *testing.T) {
18- if protocol.Version != 65 {
19- t.Fatalf("protocol.Version = %d, want 65", protocol.Version)
18+ if protocol.Version != 66 {
19+ t.Fatalf("protocol.Version = %d, want 66", protocol.Version)
2020 }
2121 if ProtocolEpoch != 1 {
2222 t.Fatalf("ProtocolEpoch = %d, want 1", ProtocolEpoch)
@@ -15,8 +15,8 @@ import (
15 // shares a payload type except route navigation failure, and the preamble15 // shares a payload type except route navigation failure, and the preamble
16 // constants agree with the schema authority.16 // constants agree with the schema authority.
17 func TestEnvelopeInventoryProvesDirectionAndSemanticPath(t *testing.T) {17 func TestEnvelopeInventoryProvesDirectionAndSemanticPath(t *testing.T) {
18- if protocol.Version != 65 {18+ if protocol.Version != 66 {
19- t.Fatalf("protocol.Version = %d, want 65", protocol.Version)19+ t.Fatalf("protocol.Version = %d, want 66", protocol.Version)
20 }20 }
21 if ProtocolEpoch != 1 {21 if ProtocolEpoch != 1 {
22 t.Fatalf("ProtocolEpoch = %d, want 1", ProtocolEpoch)22 t.Fatalf("ProtocolEpoch = %d, want 1", ProtocolEpoch)
M internal/protocol/wire/schema/broker.proto +11 -0
@@ -89,6 +89,7 @@ message BrokerClientEnvelope {
8989 UpdateHostPolicy update_host_policy = 111;
9090 StartPreview start_preview = 112;
9191 CancelPreview cancel_preview = 113;
92+ StreamWindowUpdate stream_window_update = 114;
9293 }
9394 }
9495
@@ -106,6 +107,7 @@ message BrokerServerEnvelope {
106107 BrokerErrorMessage broker_error_message = 208;
107108 Shutdown shutdown = 209;
108109 PreviewPublication preview_publication = 210;
110+ StreamWindowUpdate stream_window_update = 211;
109111 }
110112 }
111113
@@ -221,6 +223,15 @@ message CloseStream {
221223 BrokerStreamRef ref = 1;
222224 }
223225
226+// StreamWindowUpdate grants the peer credit to send more stream data on one
227+// logical stream: the receiver consumed that much of its stream window. Each
228+// direction of a stream has its own window, so a client grants credit for
229+// ServerStreamData and the server grants credit for ClientStreamData.
230+message StreamWindowUpdate {
231+ BrokerStreamRef ref = 1;
232+ uint64 credit = 2;
233+}
234+
224235 // Registered confirms one accepted client connection and its assigned scope.
225236 message Registered {
226237 BrokerScope scope = 1;
@@ -89,6 +89,7 @@ message BrokerClientEnvelope {
89 UpdateHostPolicy update_host_policy = 111;89 UpdateHostPolicy update_host_policy = 111;
90 StartPreview start_preview = 112;90 StartPreview start_preview = 112;
91 CancelPreview cancel_preview = 113;91 CancelPreview cancel_preview = 113;
92+ StreamWindowUpdate stream_window_update = 114;
92 }93 }
93 }94 }
94 95
@@ -106,6 +107,7 @@ message BrokerServerEnvelope {
106 BrokerErrorMessage broker_error_message = 208;107 BrokerErrorMessage broker_error_message = 208;
107 Shutdown shutdown = 209;108 Shutdown shutdown = 209;
108 PreviewPublication preview_publication = 210;109 PreviewPublication preview_publication = 210;
110+ StreamWindowUpdate stream_window_update = 211;
109 }111 }
110 }112 }
111 113
@@ -221,6 +223,15 @@ message CloseStream {
221 BrokerStreamRef ref = 1;223 BrokerStreamRef ref = 1;
222 }224 }
223 225
226+// StreamWindowUpdate grants the peer credit to send more stream data on one
227+// logical stream: the receiver consumed that much of its stream window. Each
228+// direction of a stream has its own window, so a client grants credit for
229+// ServerStreamData and the server grants credit for ClientStreamData.
230+message StreamWindowUpdate {
231+ BrokerStreamRef ref = 1;
232+ uint64 credit = 2;
233+}
234+
224 // Registered confirms one accepted client connection and its assigned scope.235 // Registered confirms one accepted client connection and its assigned scope.
225 message Registered {236 message Registered {
226 BrokerScope scope = 1;237 BrokerScope scope = 1;

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 12

Tags 11

↑↓ moveenter openesc close