Files
mxaccessgw/clients/rust/protos/mxaccess_worker.proto
T
Joseph Doherty eacdd2d453 fix(IPC-23,IPC-24,IPC-25,IPC-32): proto-comment regen wave + codegen-freshness guards
Proto comments (comment-only, no wire change):
- mxaccess_worker.proto GatewayHello.max_frame_bytes: every worker->gateway frame
  must serialize within the negotiated max; reply builders truncate (IPC-23).
- mxaccess_gateway.proto DrainEventsReply: count-cap + byte-cap, drain-until-empty
  caller contract (IPC-23).
- mxaccess_gateway.proto ReplayGap.oldest_available_sequence: empty-ring value is
  highest-observed+1, oldest-1 resume formula stays valid (GWC-25 deferred amendment).

Regen wave: Contracts/Generated (C# XML doc), rust vendored protos (byte-copy),
Go bindings (worker binding was genuinely stale - lacked MaxFrameBytes entirely),
Python worker _pb2 (real descriptor delta), Java aggregates (javadoc, zero
protobuf-version churn under the pinned toolchain), client descriptor set.

IPC-24: pinned Java toolchain regenerates with no gencode-version churn, so the
unconditional churn-revert step in ci.yml is a fossil - deleted it; git diff is
now a true message-level drift gate for the single-file Java aggregates.

IPC-25: pin protoc-gen-go v1.36.11 / protoc-gen-go-grpc 1.6.2 in the Go generate
script (+ fix a latent pwsh-7 parse bug); add Check 4 to check-codegen.ps1
(regenerate Go+Python bindings, fail on diff, tool-missing fails not skips); add
the pinned-generator installs to the portable CI job.

IPC-32: relabel check-codegen banners 1/4..4/4 (folded into the Check 4 edit).

Docs: ClientProtoGeneration.md, Contracts.md, GatewayTesting.md, build.gradle
checkGeneratedClean caveat. Tracking: IPC-23/24/25/32 -> Done, GWC-25 proto note
resolved, change-log 2026-08-07.
2026-08-07 07:41:18 -04:00

142 lines
4.4 KiB
Protocol Buffer

syntax = "proto3";
package mxaccess_worker.v1;
option csharp_namespace = "ZB.MOM.WW.MxGateway.Contracts.Proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "mxaccess_gateway.proto";
// Wire-compatibility policy (ProtobufStyleGuide): this contract evolves
// additively only. Never renumber or repurpose an existing field number or
// enum value. When a field or enum value is removed, add a `reserved` range
// (and `reserved` name) covering it in the same change so a future editor
// cannot accidentally reuse the retired tag. There are no `reserved`
// declarations today because no field or enum value has ever been removed.
// Gateway-to-worker IPC envelope. Named-pipe framing prepends a little-endian
// uint32 payload length to this protobuf payload.
message WorkerEnvelope {
uint32 protocol_version = 1;
string session_id = 2;
uint64 sequence = 3;
string correlation_id = 4;
oneof body {
GatewayHello gateway_hello = 10;
WorkerHello worker_hello = 11;
WorkerReady worker_ready = 12;
WorkerCommand worker_command = 13;
WorkerCommandReply worker_command_reply = 14;
WorkerCancel worker_cancel = 15;
WorkerShutdown worker_shutdown = 16;
WorkerShutdownAck worker_shutdown_ack = 17;
WorkerEvent worker_event = 18;
WorkerHeartbeat worker_heartbeat = 19;
WorkerFault worker_fault = 20;
}
}
message GatewayHello {
uint32 supported_protocol_version = 1;
string nonce = 2;
string gateway_version = 3;
// Maximum worker-frame payload size, in bytes, negotiated by the gateway from its
// configured pipe limit. The worker adopts this as its frame-protocol MaxMessageBytes
// instead of a hard-coded default; 0 (an older gateway that never set the field) means
// "use the worker's built-in default". Sits above the public gRPC cap by an
// envelope-overhead margin so an accepted gRPC payload always fits one worker frame.
// Every worker->gateway frame — events, heartbeats, faults, and control replies
// including DrainEvents — must serialize within this limit; reply builders truncate
// to fit rather than emit an oversized frame.
uint32 max_frame_bytes = 4;
}
message WorkerHello {
uint32 protocol_version = 1;
string nonce = 2;
int32 worker_process_id = 3;
string worker_version = 4;
}
message WorkerReady {
int32 worker_process_id = 1;
string mxaccess_progid = 2;
string mxaccess_clsid = 3;
google.protobuf.Timestamp ready_timestamp = 4;
}
message WorkerCommand {
mxaccess_gateway.v1.MxCommand command = 1;
google.protobuf.Timestamp enqueue_timestamp = 2;
}
message WorkerCommandReply {
mxaccess_gateway.v1.MxCommandReply reply = 1;
google.protobuf.Timestamp completed_timestamp = 2;
}
message WorkerCancel {
string reason = 1;
}
message WorkerShutdown {
google.protobuf.Duration grace_period = 1;
string reason = 2;
}
message WorkerShutdownAck {
mxaccess_gateway.v1.ProtocolStatus status = 1;
}
message WorkerEvent {
mxaccess_gateway.v1.MxEvent event = 1;
}
message WorkerHeartbeat {
int32 worker_process_id = 1;
WorkerState state = 2;
google.protobuf.Timestamp last_sta_activity_timestamp = 3;
uint32 pending_command_count = 4;
uint32 outbound_event_queue_depth = 5;
uint64 last_event_sequence = 6;
string current_command_correlation_id = 7;
}
message WorkerFault {
WorkerFaultCategory category = 1;
string command_method = 2;
optional int32 hresult = 3;
string exception_type = 4;
string diagnostic_message = 5;
mxaccess_gateway.v1.ProtocolStatus protocol_status = 6;
}
enum WorkerState {
WORKER_STATE_UNSPECIFIED = 0;
WORKER_STATE_STARTING = 1;
WORKER_STATE_HANDSHAKING = 2;
WORKER_STATE_INITIALIZING_STA = 3;
WORKER_STATE_READY = 4;
WORKER_STATE_EXECUTING_COMMAND = 5;
WORKER_STATE_SHUTTING_DOWN = 6;
WORKER_STATE_STOPPED = 7;
WORKER_STATE_FAULTED = 8;
}
enum WorkerFaultCategory {
WORKER_FAULT_CATEGORY_UNSPECIFIED = 0;
WORKER_FAULT_CATEGORY_INVALID_ARGUMENTS = 1;
WORKER_FAULT_CATEGORY_GATEWAY_AUTHENTICATION_FAILED = 2;
WORKER_FAULT_CATEGORY_PROTOCOL_MISMATCH = 3;
WORKER_FAULT_CATEGORY_PROTOCOL_VIOLATION = 4;
WORKER_FAULT_CATEGORY_PIPE_DISCONNECTED = 5;
WORKER_FAULT_CATEGORY_MXACCESS_CREATION_FAILED = 6;
WORKER_FAULT_CATEGORY_MXACCESS_COMMAND_FAILED = 7;
WORKER_FAULT_CATEGORY_MXACCESS_EVENT_CONVERSION_FAILED = 8;
WORKER_FAULT_CATEGORY_STA_HUNG = 9;
WORKER_FAULT_CATEGORY_QUEUE_OVERFLOW = 10;
WORKER_FAULT_CATEGORY_SHUTDOWN_TIMEOUT = 11;
}