diff options
-rw-r--r-- | .travis.yml | 2 | ||||
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | cmd/rr/cmd/serve.go | 11 | ||||
-rw-r--r-- | server.go | 2 | ||||
-rw-r--r-- | server_config.go | 3 | ||||
-rw-r--r-- | service/env/environment.go | 16 | ||||
-rw-r--r-- | service/env/service.go | 14 | ||||
-rw-r--r-- | service/env/service_test.go | 17 | ||||
-rw-r--r-- | service/http/service.go | 17 | ||||
-rw-r--r-- | util/fasttime.go | 5 | ||||
-rw-r--r-- | util/fasttime_test.go | 1 | ||||
-rw-r--r-- | util/state_test.go | 31 |
12 files changed, 105 insertions, 15 deletions
diff --git a/.travis.yml b/.travis.yml index 6dd312df..b5f520d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,7 @@ install: script: - go test -race -v -coverprofile=lib.txt -covermode=atomic + - go test ./util -race -v -coverprofile=util.txt -covermode=atomic - go test ./service -race -v -coverprofile=service.txt -covermode=atomic - go test ./service/env -race -v -coverprofile=env.txt -covermode=atomic - go test ./service/rpc -race -v -coverprofile=rpc.txt -covermode=atomic @@ -28,6 +29,7 @@ script: after_success: - bash <(curl -s https://codecov.io/bash) -f lib.txt + - bash <(curl -s https://codecov.io/bash) -f util.txt - bash <(curl -s https://codecov.io/bash) -f service.txt - bash <(curl -s https://codecov.io/bash) -f env.txt - bash <(curl -s https://codecov.io/bash) -f rpc.txt @@ -10,6 +10,7 @@ uninstall: rm -f /usr/local/bin/rr test: go test -v -race -cover + go test -v -race -cover ./util go test -v -race -cover ./service go test -v -race -cover ./service/env go test -v -race -cover ./service/rpc diff --git a/cmd/rr/cmd/serve.go b/cmd/rr/cmd/serve.go index 8028395a..31dd6039 100644 --- a/cmd/rr/cmd/serve.go +++ b/cmd/rr/cmd/serve.go @@ -36,14 +36,21 @@ func init() { Run: serveHandler, }) - signal.Notify(stopSignal, os.Interrupt, os.Kill, syscall.SIGTERM) + signal.Notify(stopSignal, os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGINT) } func serveHandler(cmd *cobra.Command, args []string) { + stopped := make(chan interface{}) + go func() { <-stopSignal Container.Stop() + close(stopped) }() - Container.Serve() + if err := Container.Serve(); err != nil { + return + } + + <-stopped } @@ -131,7 +131,7 @@ func (s *Server) Reconfigure(cfg *ServerConfig) error { return err } - s.pool.Listen(s.poolListener) + pool.Listen(s.poolListener) s.mu.Lock() s.cfg.Pool, s.pool = cfg.Pool, pool diff --git a/server_config.go b/server_config.go index 454b7992..199ce27b 100644 --- a/server_config.go +++ b/server_config.go @@ -75,6 +75,9 @@ func (cfg *ServerConfig) makeCommand() func() *exec.Cmd { var cmd = strings.Split(cfg.Command, " ") return func() *exec.Cmd { cmd := exec.Command(cmd[0], cmd[1:]...) + + cmd.SysProcAttr = &syscall.SysProcAttr{CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP} + cmd.Env = append(os.Environ(), fmt.Sprintf("RR_RELAY=%s", cfg.Relay)) cmd.Env = append(cmd.Env, cfg.env...) return cmd diff --git a/service/env/environment.go b/service/env/environment.go index 52a5bcf4..fe8f1dd8 100644 --- a/service/env/environment.go +++ b/service/env/environment.go @@ -3,9 +3,21 @@ package env // Environment aggregates list of environment variables. This interface can be used in custom implementation to drive // values from external sources. type Environment interface { - // GetEnv must return list of env variables. - GetEnv() (map[string]string, error) + Setter + Getter + + // Copy all environment values. + Copy(setter Setter) error +} +// Setter provides ability to set environment value. +type Setter interface { // SetEnv sets or creates environment value. SetEnv(key, value string) } + +// Setter provides ability to set environment value. +type Getter interface { + // GetEnv must return list of env variables. + GetEnv() (map[string]string, error) +} diff --git a/service/env/service.go b/service/env/service.go index 4d1327d4..83175b36 100644 --- a/service/env/service.go +++ b/service/env/service.go @@ -39,3 +39,17 @@ func (s *Service) GetEnv() (map[string]string, error) { func (s *Service) SetEnv(key, value string) { s.values[key] = value } + +// Copy all environment values. +func (s *Service) Copy(setter Setter) error { + values, err := s.GetEnv() + if err != nil { + return err + } + + for k, v := range values { + setter.SetEnv(k, v) + } + + return nil +} diff --git a/service/env/service_test.go b/service/env/service_test.go index 61fecd28..c20bb76c 100644 --- a/service/env/service_test.go +++ b/service/env/service_test.go @@ -49,3 +49,20 @@ func Test_Set(t *testing.T) { assert.Equal(t, "value-new", values["key"]) assert.Equal(t, "new", values["other"]) } + +func Test_Copy(t *testing.T) { + s1 := NewService(map[string]string{"RR": "version"}) + s2 := NewService(map[string]string{}) + + s1.SetEnv("key", "value-new") + s1.SetEnv("other", "new") + + assert.NoError(t, s1.Copy(s2)) + + values, err := s2.GetEnv() + assert.NoError(t, err) + assert.Len(t, values, 3) + assert.Equal(t, "version", values["RR"]) + assert.Equal(t, "value-new", values["key"]) + assert.Equal(t, "new", values["other"]) +} diff --git a/service/http/service.go b/service/http/service.go index e8e8eb51..ad59f887 100644 --- a/service/http/service.go +++ b/service/http/service.go @@ -54,7 +54,9 @@ func (s *Service) Init(cfg *Config, r *rpc.Service, e env.Environment) (bool, er s.cfg = cfg s.env = e if r != nil { - r.Register(ID, &rpcServer{s}) + if err := r.Register(ID, &rpcServer{s}); err != nil { + return false, err + } } return true, nil @@ -65,18 +67,13 @@ func (s *Service) Serve() error { s.mu.Lock() if s.env != nil { - values, err := s.env.GetEnv() - if err != nil { - return err - } - - for k, v := range values { - s.cfg.Workers.SetEnv(k, v) + if err := s.env.Copy(s.cfg.Workers); err != nil { + return nil } - - s.cfg.Workers.SetEnv("RR_HTTP", "true") } + s.cfg.Workers.SetEnv("RR_HTTP", "true") + s.rr = roadrunner.NewServer(s.cfg.Workers) s.rr.Listen(s.throw) diff --git a/util/fasttime.go b/util/fasttime.go new file mode 100644 index 00000000..a18924cb --- /dev/null +++ b/util/fasttime.go @@ -0,0 +1,5 @@ +package util + +// FastTime provides current unix time using specified resolution with reduced number of syscalls. +type FastTime struct { +} diff --git a/util/fasttime_test.go b/util/fasttime_test.go new file mode 100644 index 00000000..c7d86821 --- /dev/null +++ b/util/fasttime_test.go @@ -0,0 +1 @@ +package util diff --git a/util/state_test.go b/util/state_test.go new file mode 100644 index 00000000..2e988e5e --- /dev/null +++ b/util/state_test.go @@ -0,0 +1,31 @@ +package util + +import ( + "github.com/spiral/roadrunner" + "github.com/stretchr/testify/assert" + "runtime" + "testing" + "time" +) + +func TestServerState(t *testing.T) { + rr := roadrunner.NewServer( + &roadrunner.ServerConfig{ + Command: "php ../tests/client.php echo tcp", + Relay: "tcp://:9007", + RelayTimeout: 10 * time.Second, + Pool: &roadrunner.Config{ + NumWorkers: int64(runtime.NumCPU()), + AllocateTimeout: time.Second, + DestroyTimeout: time.Second, + }, + }) + defer rr.Stop() + + assert.NoError(t, rr.Start()) + + state, err := ServerState(rr) + assert.NoError(t, err) + + assert.Len(t, state, runtime.NumCPU()) +} |