Skip to content

Instantly share code, notes, and snippets.

@dhaavi
Created October 30, 2019 13:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dhaavi/f95e1f1d07a9196e2ee6ce1f2e66e9ff to your computer and use it in GitHub Desktop.
Save dhaavi/f95e1f1d07a9196e2ee6ce1f2e66e9ff to your computer and use it in GitHub Desktop.
Demo files for Talk at Go Meetup in Vienna in Oct. 2019
package main
import (
"fmt"
"github.com/safing/portbase/config"
)
// Config
// - simple, fast and easy configuration
var (
serviceEnabled config.BoolOption // <- inspect!
)
func init() {
err := config.Register(&config.Option{
Name: "Enable Service",
Key: "core/serviceEnabled",
Description: "This option enables the service.",
OptType: config.OptTypeBool,
ExpertiseLevel: config.ExpertiseLevelUser,
ReleaseLevel: config.ReleaseLevelStable,
DefaultValue: false,
})
if err != nil {
panic(err)
}
// only to be used by 1 goroutine
serviceEnabled = config.GetAsBool("core/serviceEnabled", false) // <- inspect!
// may be used concurrently
serviceEnabled = config.Concurrent.GetAsBool("core/serviceEnabled", false)
}
func main() {
for {
if serviceEnabled() {
fmt.Println("yay!")
} else {
fmt.Println("nooo!")
}
}
}
package main
import (
"fmt"
"io/ioutil"
"os"
"sync"
"github.com/safing/portbase/database/record"
"github.com/safing/portbase/database"
)
// Database
// - K/V Meta-Layer
// - Multi-Backend
// - Hooks and Subscriptions
// - Websockets API
type TestRecord struct {
record.Base
sync.Mutex
Username string
Password string
}
func main() {
// get testing tmp dir
tmpDir, err := ioutil.TempDir(os.TempDir(), "pm-testing-")
if err != nil {
panic(err)
}
// Initialize
err = database.Initialize(tmpDir, nil)
if err != nil {
panic(err)
}
// register database
_, err = database.Register(&database.Database{
Name: "users",
Description: "Holds user data and settings",
StorageType: "bbolt", // or: badger, fstree, hashmap, sinkhole
})
if err != nil {
panic(err)
}
// get interface
db := database.NewInterface(&database.Options{
// AlwaysSetRelativateExpiry int64
// AlwaysSetAbsoluteExpiry int64
// CacheSize int
})
// set something
new := &TestRecord{
Username: "frank",
Password: "$6$...",
}
new.SetKey("users:all/frank")
err = db.Put(new)
if err != nil {
panic(err)
}
r, err := db.Get("users:all/frank")
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", r)
// db.Query()
// db.Subscribe()
// database.RegisterHook(...)
// database.InjectDatabase()
}
package main
import (
"context"
"errors"
"flag"
"io"
"net/http"
"os"
"time"
"github.com/safing/portbase/log"
"github.com/safing/portbase/modules"
"github.com/safing/portbase/run"
)
// Modules
// - Startup and Shutdown procedures
// - Dependencies
// - Resilient goroutines
// - Error reporting
var (
module *modules.Module
server = &http.Server{}
listenAddress string
)
// Init
func init() {
// virtual dependency one
modules.Register("dependencyOne", nil, nil, nil)
// register real module
module = modules.Register("service", prep, start, stop, "dependencyOne", "dependencyTwo")
// virtual dependency two
modules.Register("dependencyTwo", nil, nil, nil)
// register flag for listen address
flag.StringVar(&listenAddress, "listen", "", "set listen address")
}
// Module
func prep() error {
if listenAddress == "" {
return errors.New("you must set the listen address with the -listen option")
}
module.RegisterEvent("request handled")
return nil
}
func start() error {
// configure server
server.Addr = listenAddress
server.Handler = &requestHandler{}
// start serving
log.Infof("service: starting to listen on %s", server.Addr)
module.StartServiceWorker("service listener", 1*time.Second, func(ctx context.Context) error {
err := server.ListenAndServe()
if err == http.ErrServerClosed {
return nil
}
return err
})
module.RegisterEventHook("service", "request handled", "log request", func(ctx context.Context, data interface{}) error {
log.Infof("request: %s", data)
panic("test")
return nil
})
return nil
}
func stop() error {
return server.Shutdown(context.Background())
}
// HTTP Handler
type requestHandler struct{}
var handleRequestMicroTask = "service request handler"
func (rh *requestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
_ = module.RunMicroTask(&handleRequestMicroTask, func(ctx context.Context) error {
// test panic
if r.RequestURI == "/panic" {
panic("test")
}
_, _ = io.WriteString(w, "Hello World!\n")
log.Debugf("service: request from %s", r.RemoteAddr)
module.TriggerEvent("request handled", r)
return nil
})
}
// Main
func main() {
os.Exit(run.Run())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment