// Package service provides a toolkit for creating Hnakra services. package service import "os" import "log" import "time" import "hnakra/rotate" import "hnakra/routines" // Service is capable of managing multiple mounts. It also sets up logging // automatically. type Service struct { ServiceInfo Mounts []Mount } // NewService provides a shorthand for creating a new service, leaving most // values to their default. func NewService (name, description string, mounts ...Mount) *Service { return &Service { ServiceInfo: ServiceInfo { Name: name, Description: description, }, Mounts: mounts, } } // Run runs the mounts within the service, and only exits when all of them have // exited. It will automatically start logging to the directory specified by // $HNAKRA_LOG_DIR. If that variable is unset, it will just log to stdout. func (service *Service) Run () error { // set up logging logDir := os.Getenv("HNAKRA_LOG_DIR") if logDir != "" { logger, err := rotate.New(logDir) if err != nil { log.Fatal("cannot access log dir:", err) } log.SetOutput(logger) } log.Println("... starting service", service.Name) // set up routine manager manager := routines.Manager { RestartDeadline: time.Second * 8 } manager.Routines = make([]routines.Routine, len(service.Mounts)) for index, mount := range service.Mounts { manager.Routines[index] = func () error { return mount.Run(service.ServiceInfo) } } // send it err := manager.Run() if err != nil { log.Println("XXX", err) } return err } // Close abruptly closes all mounts in the service. This will cause Run() to // exit. func (service *Service) Close () (err error) { for _, mount := range service.Mounts { singleErr := mount.Close() if singleErr != nil { err = singleErr } } return } // Shutdown gracefully shuts down each mount in the service. This will cause // Run() to exit. func (service *Service) Shutdown () (err error) { for _, mount := range service.Mounts { singleErr := mount.Shutdown() if singleErr != nil { err = singleErr } } return }