mirror of
https://github.com/safing/portbase
synced 2025-09-04 03:29:59 +00:00
Add module template, update run method
This commit is contained in:
parent
b4f014574b
commit
3f17d0e7a9
4 changed files with 170 additions and 36 deletions
|
@ -7,5 +7,11 @@ linters:
|
||||||
- funlen
|
- funlen
|
||||||
- whitespace
|
- whitespace
|
||||||
- wsl
|
- 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
|
||||||
|
|
40
portbase.go
40
portbase.go
|
@ -1,49 +1,19 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/safing/portbase/info"
|
"github.com/safing/portbase/info"
|
||||||
"github.com/safing/portbase/log"
|
"github.com/safing/portbase/run"
|
||||||
"github.com/safing/portbase/modules"
|
|
||||||
// include packages here
|
// include packages here
|
||||||
|
_ "github.com/safing/portbase/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
// Set Info
|
// Set Info
|
||||||
info.Set("Portbase", "0.0.1", "GPLv3", false)
|
info.Set("Portbase", "0.0.1", "GPLv3", false)
|
||||||
|
|
||||||
// Start
|
// Run
|
||||||
err := modules.Start()
|
os.Exit(run.Run())
|
||||||
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(" <INTERRUPT>")
|
|
||||||
log.Warning("main: program was interrupted, shutting down.")
|
|
||||||
_ = modules.Shutdown()
|
|
||||||
case <-modules.ShuttingDown():
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
116
template/module.go
Normal file
116
template/module.go
Normal file
|
@ -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
|
||||||
|
}
|
42
template/module_test.go
Normal file
42
template/module_test.go
Normal file
|
@ -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)
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue