@@ -30,10 +30,12 @@ const (
30
30
)
31
31
32
32
type Process struct {
33
- ID string
34
- config ModelConfig
35
- cmd * exec.Cmd
36
- logMonitor * LogMonitor
33
+ ID string
34
+ config ModelConfig
35
+ cmd * exec.Cmd
36
+
37
+ processLogger * LogMonitor
38
+ proxyLogger * LogMonitor
37
39
38
40
healthCheckTimeout int
39
41
healthCheckLoopInterval time.Duration
@@ -53,13 +55,14 @@ type Process struct {
53
55
shutdownCancel context.CancelFunc
54
56
}
55
57
56
- func NewProcess (ID string , healthCheckTimeout int , config ModelConfig , logMonitor * LogMonitor ) * Process {
58
+ func NewProcess (ID string , healthCheckTimeout int , config ModelConfig , processLogger * LogMonitor , proxyLogger * LogMonitor ) * Process {
57
59
ctx , cancel := context .WithCancel (context .Background ())
58
60
return & Process {
59
61
ID : ID ,
60
62
config : config ,
61
63
cmd : nil ,
62
- logMonitor : logMonitor ,
64
+ processLogger : processLogger ,
65
+ proxyLogger : proxyLogger ,
63
66
healthCheckTimeout : healthCheckTimeout ,
64
67
healthCheckLoopInterval : 5 * time .Second , /* default, can not be set by user - used for testing */
65
68
state : StateStopped ,
@@ -68,6 +71,11 @@ func NewProcess(ID string, healthCheckTimeout int, config ModelConfig, logMonito
68
71
}
69
72
}
70
73
74
+ // LogMonitor returns the log monitor associated with the process.
75
+ func (p * Process ) LogMonitor () * LogMonitor {
76
+ return p .processLogger
77
+ }
78
+
71
79
// custom error types for swapping state
72
80
var (
73
81
ErrExpectedStateMismatch = errors .New ("expected state mismatch" )
@@ -85,9 +93,11 @@ func (p *Process) swapState(expectedState, newState ProcessState) (ProcessState,
85
93
}
86
94
87
95
if ! isValidTransition (p .state , newState ) {
96
+ p .proxyLogger .Warnf ("Invalid state transition from %s to %s" , p .state , newState )
88
97
return p .state , ErrInvalidStateTransition
89
98
}
90
99
100
+ p .proxyLogger .Debugf ("State transition from %s to %s" , expectedState , newState )
91
101
p .state = newState
92
102
return p .state , nil
93
103
}
@@ -152,8 +162,8 @@ func (p *Process) start() error {
152
162
defer p .waitStarting .Done ()
153
163
154
164
p .cmd = exec .Command (args [0 ], args [1 :]... )
155
- p .cmd .Stdout = p .logMonitor
156
- p .cmd .Stderr = p .logMonitor
165
+ p .cmd .Stdout = p .processLogger
166
+ p .cmd .Stderr = p .processLogger
157
167
p .cmd .Env = p .config .Env
158
168
159
169
err = p .cmd .Start ()
@@ -214,15 +224,16 @@ func (p *Process) start() error {
214
224
return errors .New ("health check interrupted due to shutdown" )
215
225
default :
216
226
if err := p .checkHealthEndpoint (healthURL ); err == nil {
227
+ p .proxyLogger .Infof ("Health check passed on %s" , healthURL )
217
228
cancelHealthCheck ()
218
229
break loop
219
230
} else {
220
231
if strings .Contains (err .Error (), "connection refused" ) {
221
232
endTime , _ := checkDeadline .Deadline ()
222
233
ttl := time .Until (endTime )
223
- fmt . Fprintf ( p . logMonitor , "!!! Connection refused on %s, ttl %.0fs\n " , healthURL , ttl .Seconds ())
234
+ p . proxyLogger . Infof ( " Connection refused on %s, retrying in %.0fs" , healthURL , ttl .Seconds ())
224
235
} else {
225
- fmt . Fprintf ( p . logMonitor , "!!! Health check error: %v \n " , err )
236
+ p . proxyLogger . Infof ( " Health check error on %s, %v" , healthURL , err )
226
237
}
227
238
}
228
239
}
@@ -246,7 +257,8 @@ func (p *Process) start() error {
246
257
p .inFlightRequests .Wait ()
247
258
248
259
if time .Since (p .lastRequestHandled ) > maxDuration {
249
- fmt .Fprintf (p .logMonitor , "!!! Unloading model %s, TTL of %ds reached.\n " , p .ID , p .config .UnloadAfter )
260
+
261
+ p .proxyLogger .Infof ("Unloading model %s, TTL of %ds reached." , p .ID , p .config .UnloadAfter )
250
262
p .Stop ()
251
263
return
252
264
}
@@ -267,15 +279,15 @@ func (p *Process) Stop() {
267
279
268
280
// calling Stop() when state is invalid is a no-op
269
281
if curState , err := p .swapState (StateReady , StateStopping ); err != nil {
270
- fmt . Fprintf ( p . logMonitor , "!!! Info - Stop() Ready -> StateStopping err: %v, current state: %v\n " , err , curState )
282
+ p . proxyLogger . Infof ( " Stop() Ready -> StateStopping err: %v, current state: %v" , err , curState )
271
283
return
272
284
}
273
285
274
286
// stop the process with a graceful exit timeout
275
287
p .stopCommand (5 * time .Second )
276
288
277
289
if curState , err := p .swapState (StateStopping , StateStopped ); err != nil {
278
- fmt . Fprintf ( p . logMonitor , "!!! Info - Stop() StateStopping -> StateStopped err: %v, current state: %v\n " , err , curState )
290
+ p . proxyLogger . Infof ( " Stop() StateStopping -> StateStopped err: %v, current state: %v" , err , curState )
279
291
}
280
292
}
281
293
@@ -300,33 +312,32 @@ func (p *Process) stopCommand(sigtermTTL time.Duration) {
300
312
}()
301
313
302
314
if p .cmd == nil || p .cmd .Process == nil {
303
- fmt . Fprintf ( p . logMonitor , "!!! process [%s] cmd or cmd.Process is nil" , p .ID )
315
+ p . proxyLogger . Warnf ( "Process [%s] cmd or cmd.Process is nil" , p .ID )
304
316
return
305
317
}
306
318
307
319
if err := p .terminateProcess (); err != nil {
308
- fmt . Fprintf ( p . logMonitor , "!!! failed to gracefully terminate process [%s]: %v\n " , p .ID , err )
320
+ p . proxyLogger . Infof ( "Failed to gracefully terminate process [%s]: %v" , p .ID , err )
309
321
}
310
322
311
323
select {
312
324
case <- sigtermTimeout .Done ():
313
- fmt . Fprintf ( p . logMonitor , "!!! process [%s] timed out waiting to stop, sending KILL signal\n " , p .ID )
325
+ p . proxyLogger . Infof ( "Process [%s] timed out waiting to stop, sending KILL signal" , p .ID )
314
326
p .cmd .Process .Kill ()
315
327
case err := <- sigtermNormal :
316
328
if err != nil {
317
329
if errno , ok := err .(syscall.Errno ); ok {
318
- fmt . Fprintf ( p . logMonitor , "!!! process [%s] errno >> %v\n " , p .ID , errno )
330
+ p . proxyLogger . Errorf ( "Process [%s] errno >> %v" , p .ID , errno )
319
331
} else if exitError , ok := err .(* exec.ExitError ); ok {
320
332
if strings .Contains (exitError .String (), "signal: terminated" ) {
321
- fmt . Fprintf ( p . logMonitor , "!!! process [%s] stopped OK\n " , p .ID )
333
+ p . proxyLogger . Infof ( "Process [%s] stopped OK" , p .ID )
322
334
} else if strings .Contains (exitError .String (), "signal: interrupt" ) {
323
- fmt . Fprintf ( p . logMonitor , "!!! process [%s] interrupted OK\n " , p .ID )
335
+ p . proxyLogger . Infof ( "Process [%s] interrupted OK" , p .ID )
324
336
} else {
325
- fmt . Fprintf ( p . logMonitor , "!!! process [%s] ExitError >> %v, exit code: %d\n " , p .ID , exitError , exitError .ExitCode ())
337
+ p . proxyLogger . Warnf ( "Process [%s] ExitError >> %v, exit code: %d" , p .ID , exitError , exitError .ExitCode ())
326
338
}
327
-
328
339
} else {
329
- fmt . Fprintf ( p . logMonitor , "!!! process [%s] exited >> %v\n " , p .ID , err )
340
+ p . proxyLogger . Errorf ( "Process [%s] exited >> %v" , p .ID , err )
330
341
}
331
342
}
332
343
}
0 commit comments