defer boot.Stop()
if url, ok := boot.WaitReady(); ok {
fmt.Fprintln(stdout, url)
- <-ctx.Done() // wait for signal
+ // Wait for signal/crash + orderly shutdown
+ <-boot.done
return 0
} else {
return 1
done chan struct{}
healthChecker *health.Aggregator
tasksReady map[string]chan bool
+ waitShutdown sync.WaitGroup
tempdir string
configfile string
boot.healthChecker = &health.Aggregator{Cluster: boot.cluster}
<-boot.ctx.Done()
boot.logger.Info("shutting down")
+ boot.waitShutdown.Wait()
return boot.ctx.Err()
}
}
func (boot *Booter) WaitReady() (*arvados.URL, bool) {
+ ticker := time.NewTicker(time.Second)
+ defer ticker.Stop()
for waiting := true; waiting; {
- time.Sleep(time.Second)
- if boot.ctx.Err() != nil {
+ select {
+ case <-ticker.C:
+ case <-boot.ctx.Done():
return nil, false
}
if boot.healthChecker == nil {
}
}
}
+ boot.waitShutdown.Add(1)
go func() {
+ defer boot.waitShutdown.Done()
fail(boot.RunProgram(ctx, ".", nil, nil, nginx,
"-g", "error_log stderr info;",
"-g", "pid "+filepath.Join(boot.tempdir, "nginx.pid")+";",
if err != nil {
return fmt.Errorf("bug: no InternalURLs for component %q: %v", runner, runner.svc.InternalURLs)
}
+ boot.waitShutdown.Add(1)
go func() {
+ defer boot.waitShutdown.Done()
err = boot.RunProgram(ctx, runner.src, nil, nil, "bundle", "exec",
"passenger", "start",
"-p", port,
port := boot.cluster.PostgreSQL.Connection["port"]
+ boot.waitShutdown.Add(1)
go func() {
+ defer boot.waitShutdown.Done()
fail(boot.RunProgram(ctx, boot.tempdir, nil, nil, filepath.Join(bindir, "postgres"),
"-l", // enable ssl
"-D", datadir, // data dir
func (runner runGoProgram) Run(ctx context.Context, fail func(error), boot *Booter) error {
boot.wait(ctx, runner.depends...)
- boot.RunProgram(ctx, runner.src, nil, nil, "go", "install")
+ err := boot.RunProgram(ctx, runner.src, nil, nil, "go", "install")
+ if err != nil {
+ return err
+ }
if ctx.Err() != nil {
return ctx.Err()
}
// Run one for each URL
for u := range runner.svc.InternalURLs {
u := u
+ boot.waitShutdown.Add(1)
go func() {
+ defer boot.waitShutdown.Done()
fail(boot.RunProgram(ctx, boot.tempdir, nil, []string{"ARVADOS_SERVICE_INTERNAL_URL=" + u.String()}, basename))
}()
}
} else {
// Just run one
+ boot.waitShutdown.Add(1)
go func() {
+ defer boot.waitShutdown.Done()
fail(boot.RunProgram(ctx, boot.tempdir, nil, nil, basename))
}()
}