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

Parallel grouper terminates unexpectedly #34

Open
antonu17 opened this issue Aug 17, 2019 · 0 comments
Open

Parallel grouper terminates unexpectedly #34

antonu17 opened this issue Aug 17, 2019 · 0 comments

Comments

@antonu17
Copy link

antonu17 commented Aug 17, 2019

Hi @tedsuo,
First of all, I want to thank you for this library. I was looking for something like this and stumbled upon it.
While testing if the library suits my use case, I think I've found a bug or at least an unexpected behavior.
Let me share a sample of code that demonstrates it:

package main

import (
	"fmt"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/grouper"
	"github.com/tedsuo/ifrit/sigmon"
	"log"
	"os"
	"syscall"
	"time"
)

func main() {
	log.Print("start")
	duration, _ := time.ParseDuration("10s")
	runner := &sleepRunner{duration: duration}
	group := grouper.NewParallel(nil, grouper.Members{
		{
			Name:   "sleeper",
			Runner: runner,
		},
	})

	rc := <-ifrit.Invoke(sigmon.New(group, syscall.SIGUSR1)).Wait()
	log.Print("finish: ", rc)
}

type sleepRunner struct {
	duration time.Duration
}

func (r *sleepRunner) Run(signals <-chan os.Signal, ready chan<- struct{}) error {
	close(ready)
	wake := time.Tick(r.duration)
	log.Print("sleepRunner started")
	for {
		select {
		case sig := <-signals:
			log.Print("got signal: ", sig)
			if sig == os.Interrupt {
				return fmt.Errorf("interrupted")
			}
		case <-wake:
			log.Print("sleepRunner finished")
			return nil
		}
	}
}

If I run this code in a shell, and start sending USR1 signal to the process, the process ends:

$ go run main.go
2019/08/17 21:10:00 start
2019/08/17 21:10:00 sleepRunner started
2019/08/17 21:10:04 got signal: user defined signal 1
2019/08/17 21:10:05 got signal: user defined signal 1
2019/08/17 21:10:05 finish: <nil> # Notice, the process died after 5 seconds. If I don't send signals, it holds for 10 seconds, as required by duration.

# while this process is running I send signal USR1 from the separate shell like this:
$ pkill -USR1 main
$ pkill -USR1 main
...

No matter what signal I set to be propagated via sigmon (I tried USR1, USR2, URG), parallel grouper always dies on the second signal.

I'm pretty sure the bug is somewhere in grouper package, because if I run runner instead of group, like rc := <-ifrit.Invoke(sigmon.New(runner, syscall.SIGUSR1)).Wait(), it doesn't die after the second signal.

PS.
Update: I'm using go version go1.12.7 darwin/amd64

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant