From 3f17d0e7a912eff5277712472bf4ef72fee83cea Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 18 Feb 2020 15:41:24 +0100 Subject: [PATCH] Add module template, update run method --- .golangci.yml | 8 ++- portbase.go | 40 ++------------ template/module.go | 116 ++++++++++++++++++++++++++++++++++++++++ template/module_test.go | 42 +++++++++++++++ 4 files changed, 170 insertions(+), 36 deletions(-) create mode 100644 template/module.go create mode 100644 template/module_test.go diff --git a/.golangci.yml b/.golangci.yml index 3c2d6b3..de08de7 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -7,5 +7,11 @@ linters: - funlen - whitespace - wsl - - godox + - gomnd +linters-settings: + godox: + # report any comments starting with keywords, this is useful for TODO or FIXME comments that + # might be left in the code accidentally and should be resolved before merging + keywords: + - FIXME diff --git a/portbase.go b/portbase.go index 61c1662..8d9385e 100644 --- a/portbase.go +++ b/portbase.go @@ -1,49 +1,19 @@ package main import ( - "fmt" "os" - "os/signal" - "syscall" "github.com/safing/portbase/info" - "github.com/safing/portbase/log" - "github.com/safing/portbase/modules" + "github.com/safing/portbase/run" + // include packages here + _ "github.com/safing/portbase/api" ) func main() { - // Set Info info.Set("Portbase", "0.0.1", "GPLv3", false) - // Start - err := modules.Start() - if err != nil { - if err == modules.ErrCleanExit { - os.Exit(0) - } else { - os.Exit(1) - } - } - - // Shutdown - // catch interrupt for clean shutdown - signalCh := make(chan os.Signal, 3) - signal.Notify( - signalCh, - os.Interrupt, - syscall.SIGHUP, - syscall.SIGINT, - syscall.SIGTERM, - syscall.SIGQUIT, - ) - select { - case <-signalCh: - fmt.Println(" ") - log.Warning("main: program was interrupted, shutting down.") - _ = modules.Shutdown() - case <-modules.ShuttingDown(): - } - + // Run + os.Exit(run.Run()) } diff --git a/template/module.go b/template/module.go new file mode 100644 index 0000000..8c90de2 --- /dev/null +++ b/template/module.go @@ -0,0 +1,116 @@ +package template + +import ( + "context" + "time" + + "github.com/safing/portbase/config" + "github.com/safing/portbase/modules" + "github.com/safing/portbase/modules/subsystems" +) + +const ( + eventStateUpdate = "state update" +) + +var ( + module *modules.Module +) + +func init() { + // register module + module = modules.Register("template", prep, start, stop) // add dependencies... + + // register events that other modules can subscribe to + module.RegisterEvent(eventStateUpdate) +} + +func prep() error { + // register module as subsystem + err := subsystems.Register( + "Template Subsystem", // name + "This subsystem is a template for quick setup", // description + module, + "config:template", // key space for configuration options registered + &config.Option{ + Name: "Enable Template Subsystem", + Key: "config:subsystems/template", + Description: "This option enables the Template Subsystem [TEMPLATE]", + OptType: config.OptTypeBool, + DefaultValue: false, + }, + ) + if err != nil { + return err + } + + // register options + err = config.Register(&config.Option{ + Name: "language", + Key: "config:template/language", + Description: "Sets the language for the template [TEMPLATE]", + OptType: config.OptTypeString, + ExpertiseLevel: config.ExpertiseLevelUser, // default + ReleaseLevel: config.ReleaseLevelStable, // default + RequiresRestart: false, // default + DefaultValue: "en", + ValidationRegex: "^[a-z]{2}$", + }) + if err != nil { + return err + } + + // register event hooks + // do this in prep() and not in start(), as we don't want to register again if module is turned off and on again + err = module.RegisterEventHook( + "template", // event source module name + "state update", // event source name + "react to state changes", // description of hook function + eventHandler, // hook function + ) + if err != nil { + return err + } + + // hint: event hooks and tasks will not be run if module isn't online + return nil +} + +func start() error { + // register tasks + module.NewTask("do something", taskFn).Queue() + + // start service worker + module.StartServiceWorker("do something", 0, serviceWorker) + + return nil +} + +func stop() error { + return nil +} + +func serviceWorker(ctx context.Context) error { + for { + select { + case <-time.After(1 * time.Second): + err := do() + if err != nil { + return err + } + case <-ctx.Done(): + } + } +} + +func taskFn(ctx context.Context, task *modules.Task) error { + return do() +} + +func eventHandler(ctx context.Context, data interface{}) error { + return do() +} + +func do() error { + return nil +} diff --git a/template/module_test.go b/template/module_test.go new file mode 100644 index 0000000..e34522a --- /dev/null +++ b/template/module_test.go @@ -0,0 +1,42 @@ +package template + +import ( + "fmt" + "io/ioutil" + "os" + "testing" + + "github.com/safing/portbase/dataroot" + "github.com/safing/portbase/modules" +) + +func TestMain(m *testing.M) { + // tmp dir for data root (db & config) + tmpDir, err := ioutil.TempDir("", "portbase-testing-") + // initialize data dir + if err == nil { + err = dataroot.Initialize(tmpDir, 0755) + } + // start modules + if err == nil { + err = modules.Start() + } + // handle setup error + if err != nil { + fmt.Fprintf(os.Stderr, "failed to setup test: %s", err) + os.Exit(1) + } + + // run tests + exitCode := m.Run() + + // shutdown + _ = modules.Shutdown() + if modules.GetExitStatusCode() != 0 { + exitCode = modules.GetExitStatusCode() + fmt.Fprintf(os.Stderr, "failed to cleanly shutdown test: %s", err) + } + // clean up and exit + os.RemoveAll(tmpDir) + os.Exit(exitCode) +}