summaryrefslogtreecommitdiff
path: root/internal/cli/serve/command.go
diff options
context:
space:
mode:
authorValery Piashchynski <[email protected]>2022-01-15 12:08:20 +0300
committerValery Piashchynski <[email protected]>2022-01-15 12:08:20 +0300
commit5254c8eb27311e2a8a53a4c90c3829cf1238c563 (patch)
treeb51c9a4c1dd4c25adc511498ce0380a7078c5572 /internal/cli/serve/command.go
parent13609dd03dd0d2fa85b9fb850be787bf4e2ea67f (diff)
Repository content update
Signed-off-by: Valery Piashchynski <[email protected]>
Diffstat (limited to 'internal/cli/serve/command.go')
-rw-r--r--internal/cli/serve/command.go104
1 files changed, 104 insertions, 0 deletions
diff --git a/internal/cli/serve/command.go b/internal/cli/serve/command.go
new file mode 100644
index 00000000..6679d795
--- /dev/null
+++ b/internal/cli/serve/command.go
@@ -0,0 +1,104 @@
+package serve
+
+import (
+ "fmt"
+ "os"
+ "os/signal"
+ "syscall"
+
+ "github.com/spiral/roadrunner-binary/v2/internal/container"
+ "github.com/spiral/roadrunner-binary/v2/internal/meta"
+
+ "github.com/spf13/cobra"
+ "github.com/spiral/errors"
+ configImpl "github.com/spiral/roadrunner-plugins/v2/config"
+)
+
+// NewCommand creates `serve` command.
+func NewCommand(cfgPlugin *configImpl.Plugin) *cobra.Command { //nolint:funlen
+ return &cobra.Command{
+ Use: "serve",
+ Short: "Start RoadRunner server",
+ RunE: func(*cobra.Command, []string) error {
+ const op = errors.Op("handle_serve_command")
+
+ // create endure container config
+ containerCfg, err := container.NewConfig(cfgPlugin)
+ if err != nil {
+ return errors.E(op, err)
+ }
+
+ // set the grace period which would be same for all the plugins
+ cfgPlugin.Timeout = containerCfg.GracePeriod
+ cfgPlugin.Version = meta.Version()
+
+ // create endure container
+ endureContainer, err := container.NewContainer(*containerCfg)
+ if err != nil {
+ return errors.E(op, err)
+ }
+
+ // register config plugin
+ if err = endureContainer.Register(cfgPlugin); err != nil {
+ return errors.E(op, err)
+ }
+
+ // register another container plugins
+ for i, plugins := 0, container.Plugins(); i < len(plugins); i++ {
+ if err = endureContainer.Register(plugins[i]); err != nil {
+ return errors.E(op, err)
+ }
+ }
+
+ // init container and all services
+ if err = endureContainer.Init(); err != nil {
+ return errors.E(op, err)
+ }
+
+ // start serving the graph
+ errCh, err := endureContainer.Serve()
+ if err != nil {
+ return errors.E(op, err)
+ }
+
+ oss, stop := make(chan os.Signal, 2), make(chan struct{}, 1) //nolint:gomnd
+ signal.Notify(oss, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)
+
+ go func() {
+ // first catch - stop the container
+ <-oss
+ // send signal to stop execution
+ stop <- struct{}{}
+
+ // after first hit we are waiting for the second
+ // second catch - exit from the process
+ <-oss
+ fmt.Println("exit forced")
+ os.Exit(1)
+ }()
+
+ fmt.Printf("[INFO] RoadRunner server started; version: %s, buildtime: %s\n", meta.Version(), meta.BuildTime())
+
+ for {
+ select {
+ case e := <-errCh:
+ fmt.Printf("error occurred: %v, plugin: %s\n", e.Error, e.VertexID)
+
+ // return error, container already stopped internally
+ if !containerCfg.RetryOnFail {
+ return errors.E(op, e.Error)
+ }
+
+ case <-stop: // stop the container after first signal
+ fmt.Printf("stop signal received, grace timeout is: %d seconds\n", uint64(containerCfg.GracePeriod.Seconds()))
+
+ if err = endureContainer.Stop(); err != nil {
+ fmt.Printf("error occurred during the stopping container: %v\n", err)
+ }
+
+ return nil
+ }
+ }
+ },
+ }
+}