goblin

package module
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Feb 27, 2026 License: MIT Imports: 8 Imported by: 0

README

goblin - service manager

GoDoc Go Report Card License

goblin is a lightweight, powerful service management tool built for simplicity and efficiency.

Service Interface

In your codebase you just need to implement the Service interface to pass it into Goblin. Goblin will handle the rest.

type Service interface {
    ID() string
    Serve() error
    Shutdown(ctx context.Context) error
}
Implementation Contract

When implementing the Service interface, you must honor a critical contract:

  • Shutdown() is a promise: When your Shutdown(ctx) method returns (with or without error), it must guarantee that Serve() will exit shortly after. Goblin waits for the Serve() goroutine to complete after calling Shutdown(). If Serve() does not return, the entire shutdown process will hang indefinitely.

  • Example of correct implementation (HTTP server):

    func (s *MyServer) Shutdown(ctx context.Context) error {
        return s.httpServer.Shutdown(ctx)  // Guaranteed to stop Serve()
    }
    
  • Example of incorrect implementation (will hang):

    func (s *MyServer) Shutdown(ctx context.Context) error {
        s.logger.Info("shutting down")
        return nil  // Returns immediately but Serve() is still running!
    }
    
Logging behavior

By default, Goblin logs simple text messages. To customize logging (e.g., disable logs or use JSON format), pass a logger instance via goblin.WithLogger(logger).

Example Usage
// Simple usage with defaults
myService := &MyService{}
srv := NewHTTPServer(addr, handler)

if err := goblin.Run(myService, srv); err != nil {
    // handle error
}

Use RunContext to run the services with a custom context.Context.

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

if err := goblin.RunContext(ctx, myService, srv); err != nil {
    // handle error
}

For configuration, use the With builder pattern:

logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))

if err := goblin.With(
    goblin.WithLogger(logger),
    goblin.WithShutdownTimeout(time.Second * 8),
).Run(myService, srv); err != nil {
    logger.Error("goblin run", "cause", err)
}

Or with custom context:

if err := goblin.With(
    goblin.WithLogger(logger),
    goblin.WithShutdownTimeout(time.Second * 8),
).RunContext(ctx, myService, srv); err != nil {
    logger.Error("goblin run", "cause", err)
}
License

Licensed under the MIT License. See LICENSE for more.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Run added in v0.2.0

func Run(srvs ...Service) error

func RunContext added in v0.2.0

func RunContext(ctx context.Context, srvs ...Service) error

Types

type Builder added in v0.4.0

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

func With added in v0.3.1

func With(opts ...Option) Builder

func (Builder) Run added in v0.4.0

func (b Builder) Run(srvs ...Service) error

func (Builder) RunContext added in v0.4.0

func (b Builder) RunContext(ctx context.Context, srvs ...Service) error

type Config

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

type Option

type Option func(*Config)

func WithLogger added in v0.4.0

func WithLogger(logger *slog.Logger) Option

func WithNopLogger added in v0.4.0

func WithNopLogger() Option

func WithShutdownTimeout added in v0.3.0

func WithShutdownTimeout(t time.Duration) Option

type Service added in v0.2.0

type Service interface {
	ID() string
	Serve() error
	Shutdown(context.Context) error
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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