feat: Added ping command
This commit is contained in:
@@ -158,8 +158,14 @@ type ServerCommand struct {
|
||||
RunStep *RunStepCmd `json:"run_step,omitempty"`
|
||||
CleanupWorkspace *CleanupWorkspaceCmd `json:"cleanup_workspace,omitempty"`
|
||||
OpenProxy *OpenProxyCmd `json:"open_proxy,omitempty"`
|
||||
Ping *PingCmd `json:"ping,omitempty"`
|
||||
}
|
||||
|
||||
// PingCmd is a server-originated liveness beat. It carries nothing and expects
|
||||
// no reply: its arrival is the entire message. See the .proto for why gRPC
|
||||
// keepalive is not sufficient on its own.
|
||||
type PingCmd struct{}
|
||||
|
||||
type CleanupWorkspaceCmd struct {
|
||||
WorkspaceId string `json:"workspace_id"`
|
||||
}
|
||||
|
||||
@@ -212,11 +212,27 @@ func (s *vantageServer) CommandStream(stream pb.Vantage_CommandStreamServer) err
|
||||
}
|
||||
}()
|
||||
|
||||
// The heartbeat is what lets the agent tell a live stream from an orphaned
|
||||
// one. gRPC keepalive cannot: behind an L7 proxy the agent's connection
|
||||
// terminates at the proxy, which answers pings on its own behalf, so a dead
|
||||
// pod leaves the agent blocked in Recv forever with commands vanishing into
|
||||
// a stream nobody is serving. A message that originates here is the only
|
||||
// thing that proves this process is still on the other end.
|
||||
ping := time.NewTicker(pingInterval)
|
||||
defer ping.Stop()
|
||||
|
||||
ctx := stream.Context()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case <-ping.C:
|
||||
// A failed send is the point: it is how this side learns the stream
|
||||
// is gone, which runs the deferred release and frees the agent's
|
||||
// presence claim for whichever pod it reconnects to.
|
||||
if err := stream.Send(&pb.ServerCommand{Ping: &pb.PingCmd{}}); err != nil {
|
||||
return err
|
||||
}
|
||||
case cmd, ok := <-ch:
|
||||
if !ok {
|
||||
return nil
|
||||
@@ -228,6 +244,11 @@ func (s *vantageServer) CommandStream(stream pb.Vantage_CommandStreamServer) err
|
||||
}
|
||||
}
|
||||
|
||||
// How often the server beats on an idle command stream. Comfortably under the
|
||||
// agent's staleness threshold, so a single dropped beat does not cost a
|
||||
// reconnect.
|
||||
const pingInterval = 20 * time.Second
|
||||
|
||||
// StartGRPC serves the agent API until stop is called.
|
||||
//
|
||||
// It returns a stop function rather than serving forever because an abrupt exit
|
||||
|
||||
Reference in New Issue
Block a user