Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: run on Windows #877

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
50 changes: 37 additions & 13 deletions server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ package asynq
import (
"context"
"fmt"
"os"
"runtime"
"syscall"
"testing"
"time"
Expand Down Expand Up @@ -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{})
// Make sure server exits when receiving TERM signal.
go func() {
time.Sleep(2 * time.Second)
syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
done <- struct{}{}
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() {
select {
case <-time.After(10 * time.Second):
panic("server did not stop after receiving TERM signal")
case <-done:
if runtime.GOOS == "windows" {
// It is not implemented to signal Interrupt on Windows
signalWindows <- struct{}{}
return
}

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:
}
}

Expand Down
8 changes: 4 additions & 4 deletions signals_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@ package asynq
import (
"os"
"os/signal"

"golang.org/x/sys/windows"
"syscall"
)

// waitForSignals waits for signals and handles them.
// It handles SIGTERM and SIGINT.
// 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
}
Loading