https://github.com/morebec/gorman
A Goroutine Management and Monitoring library
https://github.com/morebec/gorman
Last synced: 8 months ago
JSON representation
A Goroutine Management and Monitoring library
- Host: GitHub
- URL: https://github.com/morebec/gorman
- Owner: Morebec
- Created: 2023-03-29T22:06:41.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2023-04-01T08:30:09.000Z (about 3 years ago)
- Last Synced: 2025-10-28T10:03:17.209Z (8 months ago)
- Language: Go
- Size: 17.6 KB
- Stars: 0
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Gorman
Gorman is a lightweight Go package for managing and monitoring the execution
of goroutines.
It provides two core concepts:
- `Goroutine`: Struct wrapping a goroutine and allowing to control its execution using Start/Stop semantics.
- `Manager`: Allows controlling multiple `Goroutines` at once and managing their lifecycle as a group.
The `Manager` can be helpful to create Goroutine supervisors with a HTTP or CLI implementation
to start and stop specific Goroutines.
## Installation
To install Gorman, use go get:
```shell
go get -u github.com/morebec/gorman
```
## Usage
### Manager
To use Gorman, you first need to import it in your Go project:
```go
import "github.com/morebec/gorman"
```
Next, you can create a new instance of a Manager:
```go
man := gorman.NewManager(gorman.Options{
Logger: slog.New(tint.Options{
Level: slog.LevelDebug,
TimeFormat: time.TimeOnly,
}.NewHandler(os.Stdout)),
})
```
#### Registering a Goroutine
You can then register a new Goroutine with the manager:
```go
man.Add("MyGoroutine", func(ctx context.Context) error {
// Goroutine logic goes here
select {
case <-ctx.Done():
return nil
}
}, gorman.NeverRestart())
```
The last parameter allows specifying the restart policy of the Goroutine.
Out of the box the following Restart Policies are implemented:
- `NeverRestart()`: Never restarts the Goroutine once it has stopped.
- `AlwaysRestart()`: Always restarts the Goroutine.
- `RestartOnError()`: Restart the Goroutine when it stops with an error.
- `RestartPolicyFunc`: Allows specifying the restart logic using a function.
See the `RestartPolicy` interface for more information.
#### Running the Manager
The `Run` method, allows running the manager and starting all the goroutines that were added to it:
```go
man.Run(context.Background())
```
This method will run until the context is canceled, or the `Shutdown` method is called.
#### Stopping a Goroutine
To stop a running Goroutine, you can call `Stop`:
```go
err := manager.Stop("MyGoroutine")
if err != nil {
// handle error
}
```
> Note: For goroutines to be stoppable they should correctly listen to the ctx.Done() channel.
> Go routines will also stop whenever they return.
#### Starting a Goroutine
It is possible to start a goroutine that was previously stopped using the `Start` method:
```go
err := man.Start(context.Background(), "mygoroutine")
```
#### Getting the current state of goroutines
The manager exposes the Status method which returns a slice of `GoroutineState`
which represents the current state of Goroutines.
### Goroutine
Goroutines are the building blocks of Gorman and wrap the execution of a go routine
to allow start/stop semantics. They can be used independently of the manager to control
specific goroutines in isolation.
#### Creating a Goroutine
```go
g := gorman.NewGoroutine("name", func (ctx context.Context) error {
// Perform work here.
})
```
### Starting a Goroutine
```go
g.Start(context.Background())
```
### Stopping a Goroutine
The `Stop` method will cancel the goroutine's context and will wait for it
to be stopped.
```go
err := g.Stop()
```
Alternatively a goroutine can be stopped through its context.
```go
ctx, cancel := context.WithCancel(context.Background())
g.Start(ctx)
cancel()
```
### Listening to Goroutine events
Goroutines have an internal broadcasting system that allows subscribers to listen to Goroutine events
such as `GoroutineStartedEvent` and `GoroutineEndedEvent`.
Here's an example:
```go
g := gorman.NewGoroutine("mygoroutine", func(ctx context.Context) error {
// do something
return nil
})
eventChan := g.Listen()
g.Start(context.Background())
for event := range eventChan {
switch event.(type) {
case gorman.GoroutineStartedEvent:
fmt.Printf("Goroutine %s started\n", g.State.Name)
case gorman.GoroutineStoppedEvent:
e := event.(GoroutineStoppedEvent)
if e.Error != nil {
fmt.Printf("Goroutine %s stopped with error: %s\n", event.Name, event.Error.Error())
} else {
fmt.Printf("Goroutine %s stopped\n", event.Name)
}
}
}
g.Unlisten(eventChan)
```
This mechanism can be useful to react to a goroutine's execution. For instance
the `Manager` uses this mechanism to monitor the lifecycle of the Goroutines.
> Note: Every call to the Listen() method will return a new channel. When done with using the
> channel, it should be released using the `Unlisten` method.
## Examples
For more usage examples, check the `examples` directory.
## License
Gorman is released under the MIT License.