Skip to content

Commit

Permalink
feat: use goroutines to start services
Browse files Browse the repository at this point in the history
  • Loading branch information
torives committed Sep 28, 2023
1 parent f87562d commit 1c7d222
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 59 deletions.
52 changes: 0 additions & 52 deletions cmd/cartesi-node/full.go

This file was deleted.

7 changes: 4 additions & 3 deletions cmd/cartesi-node/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@

package main

import "github.com/spf13/cobra"
import (
"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
Use: "cartesi-node [reader|validator|full|no-backend]",
Use: "cartesi-node [reader|validator|no-backend]",
Run: func(cmd *cobra.Command, args []string) { cmd.Usage() },
}

func init() {
rootCmd.AddCommand(reader)
rootCmd.AddCommand(validator)
rootCmd.AddCommand(full)
rootCmd.AddCommand(noBackend)
}
59 changes: 55 additions & 4 deletions cmd/cartesi-node/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,63 @@

package main

import "github.com/spf13/cobra"
import (
"context"
"fmt"
"time"

s "github.com/cartesi/rollups-node/internal/pkg/services"
"github.com/spf13/cobra"
)

var validator = &cobra.Command{
Use: "validator",
Short: "Starts the node in validator mode",
Run: func(cmd *cobra.Command, args []string) {
println("TODO")
},
Run: runValidatorNode,
}

const DefaultServiceTimeout = 1 * time.Minute

func runValidatorNode(cmd *cobra.Command, args []string) {
services := []s.Service{
&s.GraphQLService{},
}

// start services
ctx, cancel := context.WithCancel(context.Background())
exit := make(chan struct{})
for _, service := range services {
service := service
go func() {
if err := service.Start(ctx); err != nil {
msg := "main: service '%v' exited with error: %v\n"
fmt.Printf(msg, service.String(), err)
} else {
msg := "main: service '%v' exited successfully\n"
fmt.Printf(msg, service.String())
}
exit <- struct{}{}
}()
}

// wait for first service to exit
<-exit

// send stop message to all other services and wait for them to finish
// or timeout
wait := make(chan struct{})
go func() {
cancel()
for i := 0; i < len(services)-1; i++ {
<-exit
}
wait <- struct{}{}
}()

select {
case <-wait:
fmt.Println("main: all services exited")
case <-time.After(DefaultServiceTimeout):
fmt.Println("main: exited after timeout")
}
}
42 changes: 42 additions & 0 deletions internal/pkg/services/graphql-service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// (c) Cartesi and individual authors (see AUTHORS)
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)

package services

import (
"context"
"fmt"
"os"
"os/exec"
"syscall"
)

const serviceName = "cartesi-rollups-graphql-server"

type GraphQLService struct{}

func (g *GraphQLService) Start(ctx context.Context) error {
cmd := exec.Command(serviceName)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout

if err := cmd.Start(); err != nil {
return err
}

go func() {
<-ctx.Done()
fmt.Printf("%v: %v\n", g.String(), ctx.Err())
cmd.Process.Signal(syscall.SIGTERM)
}()

err := cmd.Wait()
if err != nil && cmd.ProcessState.ExitCode() != int(syscall.SIGTERM) {
return err
}
return nil
}

func (g *GraphQLService) String() string {
return serviceName
}
16 changes: 16 additions & 0 deletions internal/pkg/services/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// (c) Cartesi and individual authors (see AUTHORS)
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)

package services

import (
"context"
"fmt"
)

type Service interface {
fmt.Stringer

// Start a service that should run until the context is canceled
Start(ctx context.Context) error
}

0 comments on commit 1c7d222

Please sign in to comment.