2
This commit is contained in:
@@ -39,6 +39,11 @@ type runtimeConfig struct {
|
||||
StreamShards int `json:"stream_shards"`
|
||||
}
|
||||
|
||||
type controlForwardResponse struct {
|
||||
Payload json.RawMessage `json:"payload,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
type routeBundleConfig struct {
|
||||
SchemaVersion string `json:"schema_version"`
|
||||
RouteAuthority string `json:"route_authority"`
|
||||
@@ -386,6 +391,82 @@ func (m *Manager) ReceivePacket(timeoutMillis int) ([]byte, error) {
|
||||
return packet, nil
|
||||
}
|
||||
|
||||
func (m *Manager) ControlRequest(payloadJSON string) (string, error) {
|
||||
m.opMu.Lock()
|
||||
defer m.opMu.Unlock()
|
||||
if err := m.ensureConnectedLocked(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
m.mu.Lock()
|
||||
transport := m.transport
|
||||
cfg := m.cfg
|
||||
endpointAddress := m.endpoint
|
||||
m.mu.Unlock()
|
||||
if transport == nil || endpointAddress == "" {
|
||||
return "", fmt.Errorf("fabric control runtime is not connected")
|
||||
}
|
||||
endpoint := endpointConfig{Address: endpointAddress}
|
||||
for _, candidate := range cfg.Endpoints {
|
||||
if strings.TrimSpace(candidate.Address) == endpointAddress {
|
||||
endpoint = candidate
|
||||
break
|
||||
}
|
||||
}
|
||||
target := mesh.FabricTransportTarget{
|
||||
EndpointID: firstNonEmpty(endpoint.EndpointID, endpoint.Address),
|
||||
PeerID: firstNonEmpty(endpoint.NodeID, cfg.ExitNodeID),
|
||||
Endpoint: endpoint.Address,
|
||||
Transport: firstNonEmpty(endpoint.Transport, "direct_quic"),
|
||||
PeerCertSHA256: firstNonEmpty(endpoint.PeerCertSHA256, endpoint.TLSCertSHA256),
|
||||
Timeout: 8 * time.Second,
|
||||
OutboundBuffer: 16,
|
||||
InboundBuffer: 16,
|
||||
ErrorBuffer: 8,
|
||||
}
|
||||
carrier, selected, err := mesh.FabricTransportForTarget(target, transport)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
session, err := carrier.Connect(ctx, selected)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer session.Close()
|
||||
if err := session.Send(ctx, fabricproto.Frame{
|
||||
Type: fabricproto.FrameData,
|
||||
TrafficClass: fabricproto.TrafficClassReliable,
|
||||
StreamID: mesh.FabricControlForwardQUICStreamID,
|
||||
Sequence: uint64(time.Now().UnixNano()),
|
||||
Payload: []byte(payloadJSON),
|
||||
}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return "", ctx.Err()
|
||||
case err := <-session.Errors():
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
case frame := <-session.Frames():
|
||||
if frame.Type != fabricproto.FrameData || frame.StreamID != mesh.FabricControlForwardQUICStreamID {
|
||||
continue
|
||||
}
|
||||
var response controlForwardResponse
|
||||
if err := json.Unmarshal(frame.Payload, &response); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if response.Error != "" {
|
||||
return "", fmt.Errorf(response.Error)
|
||||
}
|
||||
return string(response.Payload), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) Reconnect() error {
|
||||
m.opMu.Lock()
|
||||
defer m.opMu.Unlock()
|
||||
|
||||
Reference in New Issue
Block a user