@@ -3,16 +3,23 @@ package runtime
3
3
import (
4
4
"context"
5
5
"fmt"
6
+ "io/fs"
6
7
"os"
7
8
"strconv"
8
9
"strings"
9
10
"syscall"
10
11
"time"
11
12
)
12
13
13
- const pidFile = "/etc/nginx/nginx.pid"
14
+ const (
15
+ pidFile = "/etc/nginx/nginx.pid"
16
+ pidFileTimeout = 5 * time .Second
17
+ )
14
18
15
- type readFileFunc func (string ) ([]byte , error )
19
+ type (
20
+ readFileFunc func (string ) ([]byte , error )
21
+ checkFileFunc func (string ) (fs.FileInfo , error )
22
+ )
16
23
17
24
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . Manager
18
25
@@ -31,13 +38,8 @@ func NewManagerImpl() *ManagerImpl {
31
38
}
32
39
33
40
func (m * ManagerImpl ) Reload (ctx context.Context ) error {
34
- // FIXME(pleshakov): Before reload attempt, make sure NGINX is running.
35
- // If the gateway container starts before NGINX container (which is possible),
36
- // then it is possible that a reload can be attempted when NGINX is not running yet.
37
- // Make sure to prevent this case, so we don't get an error.
38
-
39
41
// We find the main NGINX PID on every reload because it will change if the NGINX container is restarted.
40
- pid , err := findMainProcess (os .ReadFile )
42
+ pid , err := findMainProcess (os .Stat , os . ReadFile , pidFileTimeout )
41
43
if err != nil {
42
44
return fmt .Errorf ("failed to find NGINX main process: %w" , err )
43
45
}
@@ -65,8 +67,22 @@ func (m *ManagerImpl) Reload(ctx context.Context) error {
65
67
return nil
66
68
}
67
69
68
- func findMainProcess (readFile readFileFunc ) (int , error ) {
69
- content , err := readFile (pidFile )
70
+ func findMainProcess (checkFile checkFileFunc , readFile readFileFunc , timeout time.Duration ) (int , error ) {
71
+ startTime := time .Now ()
72
+ deadline := startTime .Add (timeout )
73
+
74
+ fileCheck := func () (content []byte , err error ) {
75
+ for time .Now ().Before (deadline ) {
76
+ _ , err := checkFile (pidFile )
77
+ if err == nil {
78
+ return readFile (pidFile )
79
+ }
80
+ time .Sleep (1 * time .Second )
81
+ }
82
+ return nil , fmt .Errorf ("timeout waiting for pid file to appear" )
83
+ }
84
+
85
+ content , err := fileCheck ()
70
86
if err != nil {
71
87
return 0 , err
72
88
}
0 commit comments