diff --git a/README.md b/README.md index dbfc3f2..c7cc2ca 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,16 @@ docker run --rm -p 8080:8080 -it nicumicle/parallelhttp Open in browser: 👉 [http://localhost:8080](http://localhost:8080) -### ▶️ Option B — Run the UI from Go +### ▶️ Option B — Run the UI from cli + +```shell +./parallelhttp --serve --port=8080 +``` + +Open in browser: +👉 [http://localhost:8080](http://localhost:8080) + +### ▶️ Option C — Run the UI from Go ```shell go run cmd/service/main.go @@ -117,6 +126,8 @@ CLI Flags -method string GET POST PUT PATCH DELETE (default: GET) -parallel int Number of parallel requests (default: 1) -timeout duration Request timeout (default: 10s) + -serve bool Starts the HTTP server + -port int Port for the HTTP Server(default: 8080) ``` Example diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 5989a88..46351e5 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -6,23 +6,31 @@ import ( "flag" "fmt" "log" + "net" + "net/http" + "os" + "os/signal" "strings" "time" "gopkg.in/yaml.v2" + "github.com/nicumicle/parallel/internal/api" "github.com/nicumicle/parallel/internal/parallelhttp" ) func main() { + ctx := context.Background() var format string // Init flags method := flag.String("method", "GET", "Request Method. Default GET.") endpoint := flag.String("endpoint", "", "Request endpoint to be called.") parallel := flag.Int("parallel", 1, "Number of parallel calls. Default 1.") - duration := flag.Duration("duration", 0, "Max duration for all calls. Example: 0->no limit, 1ms, 1s, 10m") + duration := flag.Duration("duration", 0, "Max duration for all calls. Example: 0->no limit, 1ms, 1s, 10m. Default 0.") timeout := flag.Duration("timeout", 0*time.Second, "Request timeout. Default 10s") + serve := flag.Bool("serve", false, "Starts the HTTP server.") + port := flag.Int("port", 8080, "HTTP server port. Default 8080.") flag.StringVar(&format, "format", "json", "Response format. One of: text, yaml, json. Default json.") flag.Parse() @@ -32,9 +40,19 @@ func main() { Parallel: *parallel, Duration: *duration, } + + // HTTP Server + if serve != nil && *serve { + if err := runHTTP(ctx, *port); err != nil { + log.Fatalf("Error: %s", err.Error()) + } + + return + } + p := parallelhttp.New(*timeout) - r, err := p.Run(context.Background(), input) + r, err := p.Run(ctx, input) if err != nil { log.Fatalf("[ERROR]: %s\n", err.Error()) } @@ -86,3 +104,31 @@ func main() { fmt.Println(string(result)) } } + +func runHTTP(ctx context.Context, port int) error { + ctx, stop := signal.NotifyContext(ctx, os.Interrupt) + defer stop() + + srv := &http.Server{ + Addr: fmt.Sprintf(":%d", port), + BaseContext: func(l net.Listener) context.Context { return ctx }, + ReadTimeout: time.Second * 30, + WriteTimeout: time.Second * 30, + Handler: api.NewAPI(), + } + + srvErr := make(chan error, 1) + go func() { + log.Printf("Server started at: %d\n", port) + srvErr <- srv.ListenAndServe() + }() + + select { + case err := <-srvErr: + return err + case <-ctx.Done(): + stop() + } + + return srv.Shutdown(context.Background()) +}