Skip to content

Implement ConnectionManager — persistent gRPC dial + reconnect loop #16

@infraax

Description

@infraax

Task: ConnectionManager

Parent epic: #4 (M1 — Robot Connection)
Depends on: #14 (SDK), #15 (Registry)

What to do

Create internal/brain/connection.go — wraps one vector-go-sdk connection to one robot. Handles the persistent dial, reconnection on failure, and exposes the SDK client.

type ConnectionManager struct {
    ESN     string
    IP      string
    // ...
}

func NewConnectionManager(esn, ip string, logger *slog.Logger) *ConnectionManager
func (c *ConnectionManager) Start(ctx context.Context) error  // begins connect + reconnect loop
func (c *ConnectionManager) Client() *vectorpb.ExternalInterfaceClient // nil if not connected
func (c *ConnectionManager) IsConnected() bool
func (c *ConnectionManager) State() api.RobotState           // last known state snapshot
func (c *ConnectionManager) Shutdown(ctx context.Context) error

Reconnect logic

  • On disconnect: wait 2s, retry. Backoff up to 30s max.
  • Log every reconnect attempt at INFO level.
  • Never panic on connection failure — always retry.
  • One connection per robot. Do not create a second.

Notes

  • Use the WirePod source as reference for how it connects to Vector via the SDK.
  • The connection uses TLS with certs from WirePod's provisioning — check how WirePod/chipper handles cert loading.
  • RESERVE_BEHAVIORS is acquired in a separate task (Acquire and hold RESERVE_BEHAVIORS behavior control #17) after connection is established.

Definition of done

ConnectionManager.Start() dials robot 008093b9, IsConnected() returns true, survives a WirePod restart (reconnects automatically).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions