github.com/vishnupahwa/lakctl@v0.0.2-alpha/cmd/commands/start.go (about)

     1  package commands
     2  
     3  import (
     4  	"context"
     5  	"github.com/vishnupahwa/lakctl/cmd/commands/options"
     6  	"github.com/vishnupahwa/lakctl/control"
     7  	"log"
     8  	"os"
     9  	"os/signal"
    10  	"syscall"
    11  
    12  	"github.com/spf13/cobra"
    13  )
    14  
    15  // addStart adds the primary start command to a top level command.
    16  //This is the entrypoint command for starting a controlled application.
    17  func addStart(topLevel *cobra.Command) {
    18  	serverOpts := &options.Server{}
    19  	runOpts := &options.Run{}
    20  
    21  	startCmd := &cobra.Command{
    22  		Use:   "start",
    23  		Short: "Start an application and an HTTP server to control it",
    24  		Long: `Start an application and an HTTP server in order to control it.
    25  
    26  Usage:
    27  $ lakctl start --run "go run main.go Hello World"
    28  
    29  Stopping the running application:
    30  $ curl http://localhost:8008/stop
    31  
    32  Starting the application:
    33  $ curl http://localhost:8008/start
    34  
    35  Restarting the application substituting the --run flag:
    36  $ curl -X POST --data '{"old":"World", "new":"世界"}' localhost:8008/restart
    37  
    38  N.B. The start and restart endpoints will always try and start or substitute the command given in the '--run' flag.
    39  `,
    40  		Run: func(cmd *cobra.Command, args []string) {
    41  			ctx := sigContext()
    42  			err := control.Start(ctx, runOpts, serverOpts)
    43  			if err != nil {
    44  				log.Fatal(err)
    45  			}
    46  		},
    47  		Aliases: []string{"init", "run"},
    48  	}
    49  
    50  	options.AddServerArgs(startCmd, serverOpts)
    51  	options.AddRunArg(startCmd, runOpts)
    52  	topLevel.AddCommand(startCmd)
    53  }
    54  
    55  // sigContext creates a context which will be cancelled on a SIGINT or SIGTERM
    56  func sigContext() context.Context {
    57  	signals := make(chan os.Signal)
    58  	signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
    59  	ctx, cancelCtx := context.WithCancel(context.Background())
    60  	go cancelIfNotified(signals, cancelCtx)
    61  	return ctx
    62  }
    63  
    64  func cancelIfNotified(signals chan os.Signal, cancelCtx context.CancelFunc) {
    65  	<-signals
    66  	cancelCtx()
    67  }