diff --git a/example_test.go b/example_test.go index 333236d..0c8eb43 100644 --- a/example_test.go +++ b/example_test.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a MIT license // that can be found in the LICENSE file. +//go:build linux || dragonfly || freebsd || netbsd || openbsd || darwin + package asynq_test import ( diff --git a/server_test.go b/server_test.go index 724b48a..e8657e1 100644 --- a/server_test.go +++ b/server_test.go @@ -7,6 +7,8 @@ package asynq import ( "context" "fmt" + "os" + "runtime" "syscall" "testing" "time" @@ -58,27 +60,49 @@ func TestServerRun(t *testing.T) { ignoreOpt := goleak.IgnoreTopFunction("github.com/redis/go-redis/v9/internal/pool.(*ConnPool).reaper") defer goleak.VerifyNone(t, ignoreOpt) - srv := NewServer(RedisClientOpt{Addr: ":6379"}, Config{LogLevel: testLogLevel}) - + signalWindows := make(chan struct{}) done := make(chan struct{}) + go func() { + defer close(done) + + mux := NewServeMux() + srv := NewServer(RedisClientOpt{Addr: ":6379"}, Config{LogLevel: testLogLevel}) + if err := srv.Start(mux); err != nil { + t.Error("start server:", err) + } + if runtime.GOOS == "windows" { + <-signalWindows + } else { + srv.waitForSignals() + } + srv.Shutdown() + }() + time.Sleep(1 * time.Second) + // Make sure server exits when receiving TERM signal. go func() { - time.Sleep(2 * time.Second) - syscall.Kill(syscall.Getpid(), syscall.SIGTERM) - done <- struct{}{} - }() + if runtime.GOOS == "windows" { + // It is not implemented to signal Interrupt on Windows + signalWindows <- struct{}{} + return + } - go func() { - select { - case <-time.After(10 * time.Second): - panic("server did not stop after receiving TERM signal") - case <-done: + p, err := os.FindProcess(os.Getpid()) + if err != nil { + t.Error("find process:", err) + return + } + err = p.Signal(syscall.SIGTERM) + if err != nil { + t.Error("signal:", err) + return } }() - mux := NewServeMux() - if err := srv.Run(mux); err != nil { - t.Fatal(err) + select { + case <-time.After(10 * time.Second): + t.Error("stop server: server did not stop after receiving TERM signal") + case <-done: } } diff --git a/signals_windows.go b/signals_windows.go index 007e8cd..49cbbd1 100644 --- a/signals_windows.go +++ b/signals_windows.go @@ -5,8 +5,7 @@ package asynq import ( "os" "os/signal" - - "golang.org/x/sys/windows" + "syscall" ) // waitForSignals waits for signals and handles them. @@ -14,16 +13,17 @@ import ( // SIGTERM and SIGINT will signal the process to exit. // // Note: Currently SIGTSTP is not supported for windows build. +// Note: Currently Ctrl-C on Windows signals syscall.SIGINT, not windows.SIGINT func (srv *Server) waitForSignals() { srv.logger.Info("Send signal TERM or INT to terminate the process") sigs := make(chan os.Signal, 1) - signal.Notify(sigs, windows.SIGTERM, windows.SIGINT) + signal.Notify(sigs, syscall.SIGTERM, syscall.SIGINT) <-sigs } func (s *Scheduler) waitForSignals() { s.logger.Info("Send signal TERM or INT to stop the scheduler") sigs := make(chan os.Signal, 1) - signal.Notify(sigs, windows.SIGTERM, windows.SIGINT) + signal.Notify(sigs, syscall.SIGTERM, syscall.SIGINT) <-sigs }