messages.go RawHistoryFolder

1package daemonmux
2
3import (
4	"errors"
5
6	"github.com/bnema/vev/internal/domain"
7	"github.com/bnema/vev/internal/ports"
8	"github.com/bnema/vev/internal/protocol"
9)
10
11var (
12	// ErrWrongDirection reports a daemonmux message presented to the wrong
13	// directional codec. Direction is a wire property of the envelope oneof:
14	// a client envelope never decodes as daemon output and vice versa.
15	ErrWrongDirection = errors.New("daemonmux: wrong message direction")
16	// ErrInvalidMessage reports a daemonmux message that fails semantic
17	// validation: bad stream identity, text, taxonomy, bound, environment,
18	// policy, or error detail.
19	ErrInvalidMessage = errors.New("daemonmux: invalid message")
20	// ErrTooLarge reports a stateless bound refusal established by limits.go:
21	// an envelope, chunk, environment, policy token, or error text above its
22	// ceiling.
23	ErrTooLarge     = errors.New("daemonmux: message exceeds bound")
24	errConvertRange = errors.New("daemonmux: wire value out of semantic range")
25)
26
27// ClientMessage is the closed set of broker-to-daemon daemonmux messages.
28// Every variant converts to exactly one MuxClientEnvelope payload.
29type ClientMessage interface{ muxClientMessage() }
30
31// ServerMessage is the closed set of daemon-to-broker daemonmux messages.
32// Every variant converts to exactly one MuxServerEnvelope payload.
33type ServerMessage interface{ muxServerMessage() }
34
35// PhysicalStreamID identifies one logical stream multiplexed over one
36// physical daemon connection. It is asserted by the opening side and never
37// crosses a physical connection; the engine (not this codec) enforces that a
38// connection's IDs are strictly increasing, so the codec only rejects zero.
39type PhysicalStreamID uint64
40
41// Validate rejects the zero value: a stream is never routed without an
42// explicit physical identity.
43func (id PhysicalStreamID) Validate() error {
44	if id == 0 {
45		return errors.New("daemonmux: physical stream ID is zero")
46	}
47	return nil
48}
49
50// StreamRef is the full identity of one multiplexed logical stream: the
51// mux-local physical stream, the broker epoch and client connection that own
52// it, and the broker client stream it carries. It is carried by MuxOpen,
53// MuxOpened, and MuxRefused only; later frames are routed by the physical
54// stream ID alone.
55type StreamRef struct {
56	Physical   PhysicalStreamID
57	Epoch      ports.BrokerEpoch
58	Connection ports.BrokerConnectionID
59	Client     ports.BrokerStreamID
60}
61
62// Validate enforces the complete reference: a nonzero physical and broker
63// stream, a nonzero epoch, and a nonzero 16-byte connection identity.
64func (r StreamRef) Validate() error {
65	if err := r.Physical.Validate(); err != nil {
66		return err
67	}
68	if r.Epoch == 0 {
69		return errors.New("daemonmux: stream ref has no broker epoch")
70	}
71	if err := r.Connection.Validate(); err != nil {
72		return err
73	}
74	return r.Client.Validate()
75}
76
77// Open asks the daemon to open one independently cancellable logical stream
78// over the physical connection. Env is the per-request session environment
79// and is never inherited from the broker process environment. StartMode is
80// the broker's explicit daemon-start authorization, propagated unchanged so a
81// transport can never widen it into a spawn.
82type Open struct {
83	Ref          StreamRef
84	Purpose      ports.BrokerStreamPurpose
85	Admission    ports.BrokerStreamAdmission
86	Name         string
87	Local        bool
88	Endpoint     string
89	Registration domain.RemoteRegistration
90	Target       protocol.ExactSessionTarget
91	Env          []string
92	Policy       ports.BrokerPolicy
93	StartMode    ports.BrokerDaemonStartMode
94}
95
96func (Open) muxClientMessage() {}
97
98// Data carries one opaque stream frame. It travels in both directions over
99// the same wire payload.
100type Data struct {
101	Physical PhysicalStreamID
102	Data     []byte
103}
104
105func (Data) muxClientMessage() {}
106func (Data) muxServerMessage() {}
107
108// Close ends one logical stream. It travels in both directions over the same
109// wire payload.
110type Close struct {
111	Physical PhysicalStreamID
112}
113
114func (Close) muxClientMessage() {}
115func (Close) muxServerMessage() {}
116
117// Reset aborts one logical stream. It travels in both directions over the
118// same wire payload. HasError=false means no detail at all: encode refuses a
119// nonzero Error rather than silently dropping it.
120type Reset struct {
121	Physical PhysicalStreamID
122	Error    ErrorDetail
123	HasError bool
124}
125
126func (Reset) muxClientMessage() {}
127func (Reset) muxServerMessage() {}
128
129// WindowUpdate returns receive credit for one stream: the receiver consumed
130// Data frames worth Credit credit bytes (payload plus MuxChunkCreditOverhead
131// per frame, see chunkCredit), so the sender may spend that many more. It
132// travels in both directions over the same wire payload.
133type WindowUpdate struct {
134	Physical PhysicalStreamID
135	Credit   uint64
136}
137
138func (WindowUpdate) muxClientMessage() {}
139func (WindowUpdate) muxServerMessage() {}
140
141// Opened confirms one logical stream is established.
142type Opened struct {
143	Ref StreamRef
144}
145
146func (Opened) muxServerMessage() {}
147
148// Refused refuses one logical stream open. The typed error is mandatory: a
149// refusal without a reason could not be classified.
150type Refused struct {
151	Ref   StreamRef
152	Error ErrorDetail
153}
154
155func (Refused) muxServerMessage() {}
156
157// MaxAdmissionCode is the highest admission-refusal code carried on
158// ErrorDetail. The taxonomy is closed: 0 is none, 1 limit, 2 closed, 3 stale
159// connection or stream, 4 invalid request (mirroring
160// ports.BrokerAdmissionError).
161const MaxAdmissionCode uint32 = 4
162
163// MaxFailureKind bounds ErrorDetail.FailureKind to the domain
164// transport-failure taxonomy. The zero value (RemoteFailureNone) is valid.
165const MaxFailureKind = domain.RemoteFailureInvalidResponse
166
167// ErrorDetail is the typed daemonmux failure carried to the broker: a closed
168// error code plus bounded display text, the admission refusal (if any), and
169// the sanitized transport cause. The underlying diagnostic cause is local-only
170// and never travels on this wire.
171type ErrorDetail struct {
172	Code ports.BrokerErrorCode
173	Text string
174	// AdmissionCode is the closed admission-refusal taxonomy: 0 is none,
175	// 1 limit, 2 closed, 3 stale connection or stream, 4 invalid request.
176	AdmissionCode uint32
177	FailureKind   domain.RemoteFailureKind
178}
179
180// validate enforces the transport contract of one ErrorDetail: a closed
181// error code, bounded presentation-safe text, an admission code within the
182// closed refusal taxonomy, and a failure kind within the domain taxonomy.
183func (d ErrorDetail) validate() error {
184	if err := d.Code.Validate(); err != nil {
185		return ErrInvalidMessage
186	}
187	if d.AdmissionCode > MaxAdmissionCode {
188		return ErrInvalidMessage
189	}
190	if d.FailureKind > MaxFailureKind {
191		return ErrInvalidMessage
192	}
193	return validateDisplayText(d.Text, ports.BrokerMaxErrorBytes)
194}

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