Files
pocket-id-pocket-id/backend/internal/utils/servicerunner.go

59 lines
1.4 KiB
Go

package utils
import (
"context"
"errors"
)
// Source:
// https://github.com/ItalyPaleAle/traefik-forward-auth/blob/v3.5.1/pkg/utils/servicerunner.go
// Copyright (c) 2018, Thom Seddon & Contributors Copyright (c) 2023, Alessandro Segala & Contributors
// License: MIT (https://github.com/ItalyPaleAle/traefik-forward-auth/blob/v3.5.1/LICENSE.md)
// Service is a background service
type Service func(ctx context.Context) error
// ServiceRunner oversees a number of services running in background
type ServiceRunner struct {
services []Service
}
// NewServiceRunner creates a new ServiceRunner
func NewServiceRunner(services ...Service) *ServiceRunner {
return &ServiceRunner{
services: services,
}
}
// Run all background services
func (r *ServiceRunner) Run(ctx context.Context) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
errCh := make(chan error)
for _, service := range r.services {
go func(service Service) {
// Run the service
rErr := service(ctx)
// Ignore context canceled errors here as they generally indicate that the service is stopping
if rErr != nil && !errors.Is(rErr, context.Canceled) {
errCh <- rErr
return
}
errCh <- nil
}(service)
}
// Wait for all services to return
errs := make([]error, 0)
for range len(r.services) {
err := <-errCh
if err != nil {
errs = append(errs, err)
}
}
return errors.Join(errs...)
}