Skip to content

This repository shows a simple way to manage the lifecycle of multiple components. It provides methods to start and shutdown components in a controlled and ordered way.

Notifications You must be signed in to change notification settings

JosemyDuarte/ComponentManager

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Component Manager

This repository aims to be a showcase on an attempt to simplify the managing of the lifecycle of multiple background services. It provides an easy-to-use interface to start and stop components in a particular order and handle errors gracefully.

Usage

To use the Component Manager, you need to create an instance of the Manager struct and add your components to it. For example:

package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/JosemyDuarte/ComponentManager/internal"
	"github.com/JosemyDuarte/ComponentManager/pkg"
)

    func main() {
        manager := pkg.NewManager()
    
        service := internal.NewService()
        server := internal.NewServer(service, "127.0.0.1:") // Server implements the Component interface
    
        manager.Register(server)
    
        manager.Start()

		// Wait for a while to let the components run.
		time.Sleep(10 * time.Second)
    
        if err := manager.Shutdown(context.Background(), time.Minute); err != nil {
            panic(fmt.Errorf("failed to shutdown the manager: %w", err))
        }
    }

In the example above, we created a Server components and added it to the manager. Then we called Start on the manager to start the components. After waiting for 10 seconds, we called Shutdown to stop the components in reverse order.

The components will be started in the order we register them and stopped in the reverse order.

Example

manager.Register(server)
manager.Register(database)
manager.Register(anotherComponent)

// The order of starting the components will be:
// 1. Server
// 2. Database
// 3. AnotherComponent

// The order of stopping the components will be:
// 1. AnotherComponent
// 2. Database
// 3. Server

Check out the tests or the main for more examples.

Component Interface

To add a component to the manager, your component needs to implement the Component interface:

type Component interface {
	// Name returns the identifier of the component (mainly for logging purposes)
	Name() string

	// Start is called in order to start the component.
	// The initReady channel should be closed when the component's initialisation is started
	// and the manager can move onto the next component.
	Start(initReady chan struct{}) error

	// Shutdown is called to stop and cleanup the component.
	// There is a limited time to do so which is controlled by the ctx.
	Shutdown(ctx context.Context) error

	// StartTimeout returns timeout within which the component is expected to be start
	StartTimeout() time.Duration
}

Contributing

Contributions are welcome! If you find any bugs or have suggestions for improvements, please submit a pull request.

About

This repository shows a simple way to manage the lifecycle of multiple components. It provides methods to start and shutdown components in a controlled and ordered way.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published