c8b3a2281a
Proto foundation + gateway-side of the size/backpressure pass: - IPC-02: add GatewayHello.max_frame_bytes (regen Generated/); gateway sends its negotiated worker-frame max in the handshake so the worker can adopt it instead of a hard-coded default. Worker read-half lands separately. - IPC-03: give the pipe frame max envelope-overhead headroom above the public gRPC cap (WorkerFrameProtocolOptions.EnvelopeOverheadReserveBytes = 64 KiB; default Worker.MaxMessageBytes bumped to 16 MiB + reserve), cross-validate the headroom at startup, and pre-check command envelope size in WorkerClient so an oversized command fails only that correlation (ResourceExhausted) instead of faulting the whole session. - IPC-04: reject DrainEvents max_events above a public ceiling in the request validator (worker per-reply cap lands with the worker half). Docs: GatewayConfiguration, WorkerFrameProtocol, gateway.md. Tests: headroom validation, DrainEvents bound, oversized-command per-command failure (pipe-harness, verified on windev).
139 lines
4.2 KiB
Protocol Buffer
139 lines
4.2 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.
|
|
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;
|
|
}
|