package socket import ( protoSocket "git.toki-labs.com/toki/proto-socket/go" altv1 "git.toki-labs.com/toki/alt/packages/contracts/gen/go/alt/v1" ) type sessionHandler struct { requestType string register func(*protoSocket.WsClient) } // sessionHandlers returns the handlers registered on every worker session. // Hello is always present; market and backtest command/query handlers attach // through the same registry instead of bespoke registration paths. func sessionHandlers(deps Deps) []sessionHandler { handlers := []sessionHandler{ helloHandler(deps), } handlers = append(handlers, marketHandlers(deps)...) handlers = append(handlers, backtestHandlers(deps)...) handlers = append(handlers, paperHandlers(deps)...) handlers = append(handlers, liveHandlers(deps)...) return handlers } // registerSessionHandlers builds the OnClientConnected callback bound to the // given dependencies. func registerSessionHandlers(deps Deps) func(*protoSocket.WsClient) { handlers := sessionHandlers(deps) return func(client *protoSocket.WsClient) { registerHandlers(client, handlers) } } func registerHandlers(client *protoSocket.WsClient, handlers []sessionHandler) { for _, handler := range handlers { if handler.register == nil { continue } handler.register(client) } } func helloHandler(deps Deps) sessionHandler { return sessionHandler{ requestType: protoSocket.TypeNameOf(&altv1.HelloRequest{}), register: func(client *protoSocket.WsClient) { protoSocket.AddRequestListenerTyped[*altv1.HelloRequest, *altv1.HelloResponse]( &client.Communicator, func(req *altv1.HelloRequest) (*altv1.HelloResponse, error) { return handleHello(deps, req) }, ) }, } } func handleHello(deps Deps, req *altv1.HelloRequest) (*altv1.HelloResponse, error) { protocolVersion := req.GetAltProtocolVersion() if protocolVersion == "" { protocolVersion = defaultAltProtocolVersion } return &altv1.HelloResponse{ ServerName: serverName, ServerVersion: serverVersion, AltProtocolVersion: protocolVersion, Capabilities: capabilitiesForDeps(deps), }, nil } func capabilitiesForDeps(deps Deps) []string { caps := []string{"hello"} if deps.Instruments != nil && deps.Bars != nil { caps = append(caps, "market-read") } if deps.DailyBarImporter != nil { caps = append(caps, "market-import") } if deps.MonthlyAggregator != nil { caps = append(caps, "monthly-aggregate") } if deps.Analysis != nil && deps.Results != nil { caps = append(caps, "backtest-read") } if deps.Starter != nil { caps = append(caps, "backtest-start", "worker-execution") } if deps.Paper != nil { caps = append(caps, "paper-trading") } if deps.Live != nil { caps = append(caps, "live-trading") } if deps.RefreshStatus != nil { caps = append(caps, "scheduler") } return caps }