app

package
v1.16.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 23, 2026 License: MIT Imports: 15 Imported by: 0

README

app

Start and stop services gracefully, using errgroup to ensure that multiple services are started properly at the same time.


Example of use

import "github.com/Eric-Guo/sponge/pkg/app"

func main() {
    initApp()
    services := CreateServices()
    closes := Close(services)

    a := app.New(services, closes)
    a.Run()
}

func initApp() {
    // get configuration

    // initializing log

    // initializing database

    // ......
}

func CreateServices() []app.IServer {
    var servers []app.IServer

    // create an HTTP service
    httpAddr := ":8080" // or get from configuration
    httpServer := server.NewHTTPServer(
        httpAddr,
        server.WithHTTPIsProd(true), // run in release mode
    )
    servers = append(servers, httpServer)

    // create a gRPC service (optional)
    // grpcServer := server.NewGRPCServer(
    //
    // )
    // servers = append(servers, grpcServer)

    return servers
}

func Close(servers []app.IServer) []app.Close {
    var closes []app.Close

    // close servers
    for _, s := range servers {
        closes = append(closes, s.Stop)
    }

    // close other resources (database, logger, tracing, etc.)
    closes = append(closes, func() error {
        // TODO: call db.Close()
        return nil
    })

    return closes
}

Local upstream processes

NewUpstreamServer(UpstreamConfig{...}) implements IServer for a local command. It supports quoted arguments, a working directory, extra environment variables, a target PORT, and a configurable shutdown signal. Add the supervisor to the services passed to app.New; initialize the application logger before starting services. A UNIX socket setting takes precedence over exporting the target port.

Supervising an upstream application

Applications hosting a supervised Rails/Puma process can use os.Exit(app.New(servers, closes).RunWithExitCode()). This additive lifecycle method shuts down on any service completion, including a successful child exit, and runs every closer before returning. Put the upstream closer first so signals reach it before HTTP connections drain. Parent termination signals override the upstream's configured StopSignal; an upstream killed by a signal returns 128 + signal, while a child that handles the signal and exits normally retains its chosen exit code. UpstreamServer.ExitCode() exposes the final status. The existing Run() behavior remains available for other Sponge applications.

Documentation

Overview

Package app is starting and stopping services gracefully, using golang.org/x/sync/errgroup to ensure that multiple services are started properly at the same time.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type App

type App struct {
	// contains filtered or unexported fields
}

App servers

func New

func New(servers []IServer, closes []Close) *App

New create an app

func (*App) Run

func (a *App) Run()

Run servers

func (*App) RunWithExitCode

func (a *App) RunWithExitCode() int

RunWithExitCode runs services with process-supervisor semantics: any completed service triggers cleanup, including an upstream that exits successfully. It returns the child's status after cleanup so main can pass it to os.Exit. Run retains the existing framework lifecycle for applications that prefer it.

type Close

type Close func() error

Close app close

type IServer

type IServer interface {
	Start() error
	Stop() error
	String() string
}

IServer server interface

type UpstreamConfig

type UpstreamConfig struct {
	Args             []string          `yaml:"args" json:"args"`
	Command          string            `yaml:"command" json:"command"`
	Enabled          bool              `yaml:"enabled" json:"enabled"`
	Env              map[string]string `yaml:"env" json:"env"`
	StopSignal       string            `yaml:"stopSignal" json:"stopSignal"`
	TargetBindSocket string            `yaml:"targetBindSocket" json:"targetBindSocket"`
	TargetPort       int               `yaml:"targetPort" json:"targetPort"`
	WorkingDirectory string            `yaml:"workingDirectory" json:"workingDirectory"`
}

UpstreamConfig configures a supervised local process.

type UpstreamServer

type UpstreamServer struct {
	// contains filtered or unexported fields
}

UpstreamServer supervises an upstream command, relaying logs and signals.

func NewUpstreamServer

func NewUpstreamServer(cfg UpstreamConfig) *UpstreamServer

NewUpstreamServer creates a supervisor for the configured upstream command.

func (*UpstreamServer) ExitCode

func (s *UpstreamServer) ExitCode() int

ExitCode returns the upstream's exit status after Start or Stop completes. Unix signal deaths use the shell convention 128 + signal number.

func (*UpstreamServer) SetShutdownSignal

func (s *UpstreamServer) SetShutdownSignal(sig os.Signal)

SetShutdownSignal relays the parent's terminating signal during Stop.

func (*UpstreamServer) Start

func (s *UpstreamServer) Start() error

Start launches the upstream command and blocks until it exits.

func (*UpstreamServer) Stop

func (s *UpstreamServer) Stop() error

Stop attempts to gracefully stop the upstream process.

func (*UpstreamServer) String

func (s *UpstreamServer) String() string

String implements app.IServer for logging purposes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL