status-go/services/nimbus/service.go

85 lines
2.7 KiB
Go

// +build nimbus
package nimbus
import (
"errors"
"fmt"
"reflect"
gethrpc "github.com/ethereum/go-ethereum/rpc"
"github.com/status-im/status-go/params"
)
// errors
var (
ErrNodeStopped = errors.New("node not started")
ErrServiceUnknown = errors.New("service unknown")
)
// DuplicateServiceError is returned during Node startup if a registered service
// constructor returns a service of the same type that was already started.
type DuplicateServiceError struct {
Kind reflect.Type
}
// Error generates a textual representation of the duplicate service error.
func (e *DuplicateServiceError) Error() string {
return fmt.Sprintf("duplicate service: %v", e.Kind)
}
// ServiceContext is a collection of service independent options inherited from
// the protocol stack, that is passed to all constructors to be optionally used;
// as well as utility methods to operate on the service environment.
type ServiceContext struct {
config *params.NodeConfig
services map[reflect.Type]Service // Index of the already constructed services
// EventMux *event.TypeMux // Event multiplexer used for decoupled notifications
// AccountManager *accounts.Manager // Account manager created by the node.
}
func NewServiceContext(config *params.NodeConfig, services map[reflect.Type]Service) *ServiceContext {
return &ServiceContext{
config: config,
services: services,
}
}
// Service retrieves a currently running service registered of a specific type.
func (ctx *ServiceContext) Service(service interface{}) error {
element := reflect.ValueOf(service).Elem()
if running, ok := ctx.services[element.Type()]; ok {
element.Set(reflect.ValueOf(running))
return nil
}
return ErrServiceUnknown
}
// ServiceConstructor is the function signature of the constructors needed to be
// registered for service instantiation.
type ServiceConstructor func(ctx *ServiceContext) (Service, error)
// Service is an individual protocol that can be registered into a node.
//
// Notes:
//
// • Service life-cycle management is delegated to the node. The service is allowed to
// initialize itself upon creation, but no goroutines should be spun up outside of the
// Start method.
//
// • Restart logic is not required as the node will create a fresh instance
// every time a service is started.
type Service interface {
// APIs retrieves the list of RPC descriptors the service provides
APIs() []gethrpc.API
// StartService is called after all services have been constructed and the networking
// layer was also initialized to spawn any goroutines required by the service.
StartService() error
// Stop terminates all goroutines belonging to the service, blocking until they
// are all terminated.
Stop() error
}