### gRPC Server Component Management in Go Source: https://context7.com/gojekfarm/xrun/llms.txt This snippet demonstrates how to wrap a gRPC server with lifecycle management using the xrun library. It includes listener creation, pre-start and pre-stop hooks, and graceful shutdown. Dependencies include the standard Go context, log, os, signal packages, and the google.golang.org/grpc and github.com/gojekfarm/xrun libraries. ```go package main import ( "context" "fmt" "log" "os" "os/signal" "google.golang.org/grpc" "github.com/gojekfarm/xrun" xgrpc "github.com/gojekfarm/xrun/component/x/grpc" ) // Assume you have protobuf definitions and implementations // type MyServiceServer struct { ... } // func (s *MyServiceServer) SomeRPC(ctx context.Context, req *Request) (*Response, error) { ... } func main() { grpcServer := grpc.NewServer() // Register your gRPC services here // pb.RegisterMyServiceServer(grpcServer, &MyServiceServer{}) component := xgrpc.Server(xgrpc.Options{ Server: grpcServer, NewListener: xgrpc.NewListener(":50051"), PreStart: func() { log.Println("gRPC server starting on :50051") }, PreStop: func() { log.Println("gRPC server initiating graceful stop") }, PostStop: func() { log.Println("gRPC server stopped") }, }) ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) defer stop() if err := component.Run(ctx); err != nil { fmt.Fprintf(os.Stderr, "gRPC server error: %v\n", err) os.Exit(1) } } ``` -------------------------------- ### Create HTTPServer Component with Lifecycle Hooks (Go) Source: https://context7.com/gojekfarm/xrun/llms.txt Demonstrates how to create an HTTP server component using xrun, including pre-start and pre-stop lifecycle hooks. It sets up basic health and data endpoints and handles OS interrupt signals for graceful shutdown. ```go package main import ( "context" "fmt" "log" "net/http" "os" "os/signal" "github.com/gojekfarm/xrun" "github.com/gojekfarm/xrun/component" ) func main() { mux := http.NewServeMux() mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) fmt.Fprintf(w, `{"status":"healthy"}`) }) mux.HandleFunc("/api/data", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, `{"data":"example"}`) }) server := &http.Server{ Addr: ":9090", Handler: mux, } httpComponent := component.HTTPServer(component.HTTPServerOptions{ Server: server, PreStart: func() { log.Println("Server starting on http://localhost:9090") log.Println("Endpoints: /health, /api/data") }, PreStop: func() { log.Println("Received shutdown signal, closing server...") }, }) ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) defer stop() if err := httpComponent.Run(ctx); err != nil { log.Fatalf("HTTP server error: %v", err) } } ``` -------------------------------- ### Manage Nested Managers with xrun (Go) Source: https://context7.com/gojekfarm/xrun/llms.txt Illustrates how to create a hierarchical structure of components using nested managers. It defines separate managers for API services and background jobs, then combines them under a root manager, demonstrating independent lifecycle control and shutdown sequencing. ```go package main import ( "context" "fmt" "net/http" "os" "os/signal" "time" "github.com/gojekfarm/xrun" "github.com/gojekfarm/xrun/component" ) func main() { // API services manager apiManager := xrun.NewManager(xrun.ShutdownTimeout(10 * time.Second)) apiManager.Add(component.HTTPServer(component.HTTPServerOptions{ Server: &http.Server{Addr: ":8080"}, })) apiManager.Add(component.HTTPServer(component.HTTPServerOptions{ Server: &http.Server{Addr: ":8081"}, })) // Background jobs manager jobsManager := xrun.NewManager(xrun.ShutdownTimeout(30 * time.Second)) jobsManager.Add(xrun.ComponentFunc(func(ctx context.Context) error { fmt.Println("Job processor started") <-ctx.Done() time.Sleep(2 * time.Second) // Simulate cleanup fmt.Println("Job processor stopped") return nil })) // Root manager coordinates both rootManager := xrun.NewManager(xrun.ShutdownTimeout(45 * time.Second)) if err := rootManager.Add(apiManager); err != nil { panic(err) } if err := rootManager.Add(jobsManager); err != nil { panic(err) } ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) defer stop() fmt.Println("Starting nested component hierarchy...") if err := rootManager.Run(ctx); err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } } ``` -------------------------------- ### Manage Multiple Components with Manager in Go Source: https://context7.com/gojekfarm/xrun/llms.txt Illustrates using the xrun.Manager to orchestrate multiple components, including an HTTP server and a background worker. The Manager handles concurrent startup and graceful shutdown with a configurable timeout, responding to interrupt signals. ```go package main import ( "context" "fmt" "net/http" "os" "os/signal" "time" "github.com/gojekfarm/xrun" "github.com/gojekfarm/xrun/component" ) func main() { // Create manager with 30-second shutdown timeout m := xrun.NewManager(xrun.ShutdownTimeout(30 * time.Second)) // Add HTTP server component server := &http.Server{ Addr: ":8080", Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello from xrun!") }), } if err := m.Add(component.HTTPServer(component.HTTPServerOptions{ Server: server, PreStart: func() { fmt.Println("HTTP server starting on :8080") }, PreStop: func() { fmt.Println("HTTP server shutting down") }, })); err != nil { panic(err) } // Add background worker component if err := m.Add(xrun.ComponentFunc(func(ctx context.Context) error { ticker := time.NewTicker(2 * time.Second) defer ticker.Stop() for { select { case <-ctx.Done(): fmt.Println("Worker cleanup complete") return nil case <-ticker.C: fmt.Println("Worker processing batch") } } })); err != nil { panic(err) } // Run until interrupt signal ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) defer stop() fmt.Println("Starting all components...") if err := m.Run(ctx); err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } } ``` -------------------------------- ### Compose Multiple Components with xrun.All (Go) Source: https://context7.com/gojekfarm/xrun/llms.txt Shows a simplified way to compose multiple components, including HTTP servers and background tasks, using the `xrun.All` utility. It defines two HTTP servers and a health check component, then runs them concurrently with a specified shutdown timeout. ```go package main import ( "context" "fmt" "net/http" "os" "os/signal" "time" "github.com/gojekfarm/xrun" "github.com/gojekfarm/xrun/component" ) func main() { httpServer := &http.Server{ Addr: ":3000", Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) fmt.Fprintf(w, "API v1") }), } metricsServer := &http.Server{ Addr: ":9091", Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) fmt.Fprintf(w, "# HELP requests_total Total requests\n# TYPE requests_total counter\nrequests_total 42\n") }), } healthCheck := xrun.ComponentFunc(func(ctx context.Context) error { ticker := time.NewTicker(10 * time.Second) defer ticker.Stop() for { select { case <-ctx.Done(): return nil case <-ticker.C: fmt.Println("Health check: all systems operational") } } }) ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) defer stop() // Run all components with 15-second shutdown timeout if err := xrun.All( 15*time.Second, component.HTTPServer(component.HTTPServerOptions{Server: httpServer}), component.HTTPServer(component.HTTPServerOptions{Server: metricsServer}), healthCheck, ).Run(ctx); err != nil { fmt.Fprintf(os.Stderr, "application error: %v\n", err) os.Exit(1) } } ``` -------------------------------- ### Use ComponentFunc for Inline Components in Go Source: https://context7.com/gojekfarm/xrun/llms.txt Shows how to use the xrun.ComponentFunc helper to define components inline, avoiding the need for separate struct definitions. This is ideal for simple or one-off components and integrates with signal handling for graceful termination. ```go package main import ( "context" "fmt" "os" "os/signal" "time" "github.com/gojekfarm/xrun" ) func main() { // Define a component inline using ComponentFunc ticker := xrun.ComponentFunc(func(ctx context.Context) error { t := time.NewTicker(500 * time.Millisecond) defer t.Stop() count := 0 for { select { case <-ctx.Done(): fmt.Printf("Ticker stopped after %d ticks\n", count) return nil case <-t.C: count++ fmt.Printf("Tick %d\n", count) } } }) ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) defer stop() if err := ticker.Run(ctx); err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } } ``` -------------------------------- ### Implement Component Interface in Go Source: https://context7.com/gojekfarm/xrun/llms.txt Demonstrates how to implement the xrun.Component interface by defining a custom struct with a blocking Run method that handles context cancellation for graceful shutdown. This is suitable for background tasks or services. ```go package main import ( "context" "fmt" "time" ) // Custom component implementing xrun.Component interface type Worker struct { name string } func (w *Worker) Run(ctx context.Context) error { ticker := time.NewTicker(1 * time.Second) defer ticker.Stop() fmt.Printf("%s started\n", w.name) for { select { case <-ctx.Done(): fmt.Printf("%s stopping\n", w.name) return nil case <-ticker.C: fmt.Printf("%s tick\n", w.name) } } } func main() { worker := &Worker{name: "background-worker"} ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := worker.Run(ctx); err != nil { fmt.Printf("worker failed: %v\n", err) } } ``` -------------------------------- ### Configure Shutdown Timeout for xrun Manager in Go Source: https://context7.com/gojekfarm/xrun/llms.txt This Go code demonstrates how to configure the shutdown timeout for an xrun Manager. It shows how to create a manager with no timeout and one with a specific duration (5 seconds). A slow-stopping component (10 seconds) is added to illustrate the timeout behavior. Dependencies include standard Go packages and the github.com/gojekfarm/xrun library. ```go package main import ( "context" "fmt" "net/http" "os" "os/signal" "time" "github.com/gojekfarm/xrun" "github.com/gojekfarm/xrun/component" ) func main() { // Manager with no timeout - waits indefinitely infiniteManager := xrun.NewManager(xrun.ShutdownTimeout(xrun.NoTimeout)) // Manager with 5-second timeout timeoutManager := xrun.NewManager(xrun.ShutdownTimeout(5 * time.Second)) // Add a slow-stopping component slowComponent := xrun.ComponentFunc(func(ctx context.Context) error { <-ctx.Done() fmt.Println("Starting slow cleanup...") time.Sleep(10 * time.Second) // Takes 10 seconds to clean up fmt.Println("Cleanup complete") return nil }) timeoutManager.Add(slowComponent) timeoutManager.Add(component.HTTPServer(component.HTTPServerOptions{ Server: &http.Server{Addr: ":8080"}, })) ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) defer stop() // Will timeout after 5 seconds even if slowComponent isn't done if err := timeoutManager.Run(ctx); err != nil { // Error will indicate timeout exceeded fmt.Fprintf(os.Stderr, "shutdown error: %v\n", err) os.Exit(1) } } ``` -------------------------------- ### Error Handling and Aggregation with xrun in Go Source: https://context7.com/gojekfarm/xrun/llms.txt This Go code illustrates how the xrun Manager aggregates errors from multiple failing components. It sets up a manager with a timeout and adds three components: one that fails immediately, one that fails after a delay, and one that succeeds. When Run is called, the manager collects all errors and returns them as a joined error. Dependencies include standard Go packages and the github.com/gojekfarm/xrun library. ```go package main import ( "context" "errors" "fmt" "os" "os/signal" "time" "github.com/gojekfarm/xrun" ) func main() { m := xrun.NewManager(xrun.ShutdownTimeout(10 * time.Second)) // Component that fails immediately failingComponent := xrun.ComponentFunc(func(ctx context.Context) error { return errors.New("database connection failed") }) // Component that fails after some time delayedFailure := xrun.ComponentFunc(func(ctx context.Context) error { time.Sleep(2 * time.Second) return errors.New("cache initialization failed") }) // Component that succeeds successfulComponent := xrun.ComponentFunc(func(ctx context.Context) error { <-ctx.Done() return nil }) m.Add(failingComponent) m.Add(delayedFailure) m.Add(successfulComponent) ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) defer stop() if err := m.Run(ctx); err != nil { // err will contain both error messages joined together fmt.Fprintf(os.Stderr, "Components failed:\n%v\n", err) // Check for specific errors if errors.Is(err, context.Canceled) { fmt.Println("Context was cancelled") } os.Exit(1) } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.