@@ -24,10 +24,13 @@ import (
24
24
"net"
25
25
"net/http"
26
26
"net/http/pprof"
27
+ "os"
28
+ "os/signal"
27
29
"runtime"
28
30
runpprof "runtime/pprof"
29
31
"strconv"
30
32
"strings"
33
+ "syscall"
31
34
"time"
32
35
33
36
"github.com/prometheus/client_golang/prometheus/promhttp"
@@ -49,8 +52,8 @@ func NewAgentCommand(a *Agent, o *options.GrpcProxyAgentOptions) *cobra.Command
49
52
Use : "agent" ,
50
53
Long : `A gRPC agent, Connects to the proxy and then allows traffic to be forwarded to it.` ,
51
54
RunE : func (cmd * cobra.Command , args []string ) error {
52
- stopCh := make ( chan struct {} )
53
- return a .Run (o , stopCh )
55
+ drainCh , stopCh := SetupSignalHandler ( )
56
+ return a .Run (o , drainCh , stopCh )
54
57
},
55
58
}
56
59
@@ -64,13 +67,13 @@ type Agent struct {
64
67
cs * agent.ClientSet
65
68
}
66
69
67
- func (a * Agent ) Run (o * options.GrpcProxyAgentOptions , stopCh <- chan struct {}) error {
70
+ func (a * Agent ) Run (o * options.GrpcProxyAgentOptions , drainCh , stopCh <- chan struct {}) error {
68
71
o .Print ()
69
72
if err := o .Validate (); err != nil {
70
73
return fmt .Errorf ("failed to validate agent options with %v" , err )
71
74
}
72
75
73
- cs , err := a .runProxyConnection (o , stopCh )
76
+ cs , err := a .runProxyConnection (o , drainCh , stopCh )
74
77
if err != nil {
75
78
return fmt .Errorf ("failed to run proxy connection with %v" , err )
76
79
}
@@ -92,7 +95,31 @@ func (a *Agent) Run(o *options.GrpcProxyAgentOptions, stopCh <-chan struct{}) er
92
95
return nil
93
96
}
94
97
95
- func (a * Agent ) runProxyConnection (o * options.GrpcProxyAgentOptions , stopCh <- chan struct {}) (* agent.ClientSet , error ) {
98
+ var shutdownSignals = []os.Signal {os .Interrupt , syscall .SIGTERM }
99
+
100
+ func SetupSignalHandler () (drainCh , stopCh <- chan struct {}) {
101
+ drain := make (chan struct {})
102
+ stop := make (chan struct {})
103
+ c := make (chan os.Signal , 2 )
104
+ signal .Notify (c , shutdownSignals ... )
105
+ labels := runpprof .Labels (
106
+ "core" , "signalHandler" ,
107
+ )
108
+ go runpprof .Do (context .Background (), labels , func (context.Context ) { handleSignals (c , drain , stop ) })
109
+
110
+ return drain , stop
111
+ }
112
+
113
+ func handleSignals (signalCh chan os.Signal , drainCh , stopCh chan struct {}) {
114
+ s := <- signalCh
115
+ klog .V (2 ).InfoS ("Received first signal" , "signal" , s )
116
+ close (drainCh )
117
+ s = <- signalCh
118
+ klog .V (2 ).InfoS ("Received second signal" , "signal" , s )
119
+ close (stopCh )
120
+ }
121
+
122
+ func (a * Agent ) runProxyConnection (o * options.GrpcProxyAgentOptions , drainCh , stopCh <- chan struct {}) (* agent.ClientSet , error ) {
96
123
var tlsConfig * tls.Config
97
124
var err error
98
125
if tlsConfig , err = util .GetClientTLSConfig (o .CaCert , o .AgentCert , o .AgentKey , o .ProxyServerHost , o .AlpnProtos ); err != nil {
@@ -106,7 +133,7 @@ func (a *Agent) runProxyConnection(o *options.GrpcProxyAgentOptions, stopCh <-ch
106
133
}),
107
134
}
108
135
cc := o .ClientSetConfig (dialOptions ... )
109
- cs := cc .NewAgentClientSet (stopCh )
136
+ cs := cc .NewAgentClientSet (drainCh , stopCh )
110
137
cs .Serve ()
111
138
112
139
return cs , nil
0 commit comments