From 58609926b9d35142ebdabef2292ff7411a5489b2 Mon Sep 17 00:00:00 2001 From: Darko Luketic <2694548+dalu@users.noreply.github.com> Date: Wed, 6 May 2020 01:49:46 +0200 Subject: [PATCH] graceful shutdown, CoreInterface changes, MongoDB official driver is the only DB backend --- core/base/base.go | 153 ----------------------------------- core/core.go | 198 ++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 9 +++ interfaces.go | 30 +++---- main.go | 25 +++++- registry.go | 37 +++++++++ 6 files changed, 277 insertions(+), 175 deletions(-) delete mode 100644 core/base/base.go create mode 100644 core/core.go create mode 100644 go.mod diff --git a/core/base/base.go b/core/base/base.go deleted file mode 100644 index 748777f..0000000 --- a/core/base/base.go +++ /dev/null @@ -1,153 +0,0 @@ -package base - -import ( - "fmt" - - "github.com/globalsign/mgo" - "github.com/jinzhu/gorm" -) - -type Base struct{} - -func (b *Base) Register() (string, error) { - if e := b.BeforeLoadPlugins(); e != nil { - return "", e - } - if e := b.LoadPlugins(); e != nil { - return "", e - } - if e := b.AfterLoadPlugins(); e != nil { - return "", e - } - if e := b.BeforeLoadConfiguration(); e != nil { - return "", e - } - if e := b.LoadConfiguration(); e != nil { - return "", e - } - if e := b.AfterLoadConfiguration(); e != nil { - return "", e - } - if e := b.BeforeConnectToDatabases(); e != nil { - return "", e - } - if e := b.ConnectToDatabases(); e != nil { - return "", e - } - if e := b.AfterConnectToDatabases(); e != nil { - return "", e - } - if e := b.BeforeSetupLogger(); e != nil { - return "", e - } - if e := b.SetupLogger(); e != nil { - return "", e - } - if e := b.AfterSetupLogger(); e != nil { - return "", e - } - if e := b.BeforeSetupRoutes(); e != nil { - return "", e - } - if e := b.SetupRoutes(); e != nil { - return "", e - } - if e := b.AfterSetupRoutes(); e != nil { - return "", e - } - if e := b.BeforeRun(); e != nil { - return "", e - } - if e := b.Run(); e != nil { - return "", e - } - if e := b.AfterRun(); e != nil { - return "", e - } - return "base", nil -} - -func (b *Base) UnRegister() error { - return nil -} - -func (b *Base) BeforeLoadPlugins() error { - fmt.Println("Hello World. BeforeLoadPlugins") - return nil -} - -func (b *Base) LoadPlugins() error { - return nil -} - -func (b *Base) AfterLoadPlugins() error { - return nil -} - -func (b *Base) BeforeLoadConfiguration() error { - return nil -} - -func (b *Base) LoadConfiguration() error { - return nil -} - -func (b *Base) AfterLoadConfiguration() error { - return nil -} - -func (b *Base) ConnectMongoDB(string) (*mgo.Session, error) { - return nil, nil -} - -func (b *Base) ConnectGORM(string) (*gorm.DB, error) { - return nil, nil -} - -func (b *Base) BeforeConnectToDatabases() error { - return nil -} - -func (b *Base) ConnectToDatabases() error { - return nil -} - -func (b *Base) AfterConnectToDatabases() error { - return nil -} - -func (b *Base) BeforeSetupLogger() error { - return nil -} - -func (b *Base) SetupLogger() error { - return nil -} - -func (b *Base) AfterSetupLogger() error { - return nil -} - -func (b *Base) BeforeSetupRoutes() error { - return nil -} - -func (b *Base) SetupRoutes() error { - return nil -} - -func (b *Base) AfterSetupRoutes() error { - return nil -} - -func (b *Base) BeforeRun() error { - return nil -} - -func (b *Base) Run() error { - return nil -} - -func (b *Base) AfterRun() error { - return nil -} diff --git a/core/core.go b/core/core.go new file mode 100644 index 0000000..9114128 --- /dev/null +++ b/core/core.go @@ -0,0 +1,198 @@ +package core + +import ( + "context" + "fmt" + "net/http" + "time" + + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +type Core struct { + client *mongo.Client + clientContext context.Context + clientTimeout time.Duration + clientURI string +} + +func (c *Core) Register() (string, error) { + if e := c.BeforeLoadPlugins(); e != nil { + return "", e + } + if e := c.LoadPlugins(); e != nil { + return "", e + } + if e := c.AfterLoadPlugins(); e != nil { + return "", e + } + if e := c.BeforeLoadConfiguration(); e != nil { + return "", e + } + if e := c.LoadConfiguration(); e != nil { + return "", e + } + if e := c.AfterLoadConfiguration(); e != nil { + return "", e + } + if e := c.BeforeDatabaseInit(); e != nil { + return "", e + } + if e := c.DatabaseInit(); e != nil { + return "", e + } + if e := c.AfterDatabaseInit(); e != nil { + return "", e + } + if e := c.BeforeSetupLogger(); e != nil { + return "", e + } + if e := c.SetupLogger(); e != nil { + return "", e + } + if e := c.AfterSetupLogger(); e != nil { + return "", e + } + if e := c.BeforeSetupRoutes(); e != nil { + return "", e + } + if e := c.SetupRoutes(); e != nil { + return "", e + } + if e := c.AfterSetupRoutes(); e != nil { + return "", e + } + return "core", nil +} + +func (c *Core) UnRegister() error { + fmt.Println("Core: UnRegister") + if e := c.BeforeShutdown(); e != nil { + return e + } + if e := c.Shutdown(); e != nil { + return e + } + return nil +} + +func (c *Core) BeforeLoadPlugins() error { + fmt.Println("Core: BeforeLoadPlugins") + return nil +} + +func (c *Core) LoadPlugins() error { + fmt.Println("Core: LoadPlugins") + return nil +} + +func (c *Core) AfterLoadPlugins() error { + fmt.Println("Core: AfterLoadPlugins") + return nil +} + +func (c *Core) BeforeLoadConfiguration() error { + fmt.Println("Core: BeforeLoadConfiguration") + return nil +} + +func (c *Core) LoadConfiguration() error { + fmt.Println("Core: LoadConfiguration") + c.clientURI = "mongodb://localhost:27017/" + return nil +} + +func (c *Core) AfterLoadConfiguration() error { + fmt.Println("Core: AfterLoadConfiguration") + return nil +} + +func (c *Core) BeforeDatabaseInit() error { + fmt.Println("Core: BeforeDatabaseInit") + return nil +} + +func (c *Core) DatabaseInit() error { + fmt.Println("Core: DatabaseInit") + c.clientTimeout = 10 * time.Second + c.clientContext = context.Background() + var e error + c.client, e = mongo.NewClient(options.Client().ApplyURI(c.clientURI)) + if e != nil { + return e + } + ctx, cancel := context.WithTimeout(c.clientContext, c.clientTimeout) + defer cancel() + return c.client.Connect(ctx) +} + +func (c *Core) AfterDatabaseInit() error { + fmt.Println("Core: AfterDatabaseInit") + return nil +} + +func (c *Core) BeforeSetupLogger() error { + fmt.Println("Core: BeforeSetupLogger") + return nil +} + +func (c *Core) SetupLogger() error { + fmt.Println("Core: SetupLogger") + return nil +} + +func (c *Core) AfterSetupLogger() error { + fmt.Println("Core: AfterSetupLogger") + return nil +} + +func (c *Core) BeforeSetupRoutes() error { + fmt.Println("Core: BeforeSetupRoutes") + return nil +} + +func (c *Core) SetupRoutes() error { + fmt.Println("Core: SetupRoutes") + return nil +} + +func (c *Core) AfterSetupRoutes() error { + fmt.Println("Core: AfterSetupRoutes") + return nil +} + +func (c *Core) BeforeRun() error { + fmt.Println("Core: BeforeRun") + return nil +} + +func (c *Core) Run() error { + fmt.Println("Core: Run") + return http.ListenAndServe(":8080", nil) +} + +func (c *Core) AfterRun() error { + fmt.Println("Core: AfterRun") + return nil +} + +func (c *Core) BeforeShutdown() error { + fmt.Println("Core: BeforeShutdown") + return nil +} + +func (c *Core) Shutdown() error { + fmt.Println("Core: Shutdown") + return c.Close() +} + +func (c *Core) Client() *mongo.Client { + fmt.Println("Core: Client") + return c.client +} + +func (c *Core) Close() error { + fmt.Println("Core: Close") + return c.client.Disconnect(c.clientContext) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..745126f --- /dev/null +++ b/go.mod @@ -0,0 +1,9 @@ +module git.icod.de/dalu/contentplatform + +go 1.14 + +require ( + github.com/davecgh/go-spew v1.1.1 + go.mongodb.org/mongo-driver v1.3.3 + golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd // indirect +) diff --git a/interfaces.go b/interfaces.go index 8b5d7ea..cbda76c 100644 --- a/interfaces.go +++ b/interfaces.go @@ -1,9 +1,6 @@ package main -import ( - "github.com/globalsign/mgo" - "github.com/jinzhu/gorm" -) +import "go.mongodb.org/mongo-driver/mongo" type CoreInterface interface { Register() (string, error) @@ -17,20 +14,9 @@ type CoreInterface interface { LoadConfiguration() error AfterLoadConfiguration() error - // connection string parameter e.g. "localhost" - ConnectMongoDB(string) (*mgo.Session, error) - - // connection string parameter - ConnectGORM(string) (*gorm.DB, error) - - // ConnectNeo4j - // ConnectArangoDB - // ConnectCassandra - // ConnectDGraph - - BeforeConnectToDatabases() error - ConnectToDatabases() error - AfterConnectToDatabases() error + BeforeDatabaseInit() error + DatabaseInit() error + AfterDatabaseInit() error BeforeSetupLogger() error SetupLogger() error @@ -43,6 +29,14 @@ type CoreInterface interface { BeforeRun() error Run() error AfterRun() error + + BeforeShutdown() error + Shutdown() error +} + +type DatabaseInterface interface { + Client() *mongo.Client + Close() error } type HandlerInterface interface { diff --git a/main.go b/main.go index bc7e716..6eb9530 100644 --- a/main.go +++ b/main.go @@ -2,16 +2,33 @@ package main import ( "log" + "os" + "os/signal" + "syscall" - "git.icod.de/dalu/contentplatform/core/base" + "git.icod.de/dalu/contentplatform/core" ) var registry = NewPluginRegistry() func main() { - - if e := registry.RegisterCorePlugin(new(base.Base)); e != nil { + catchSignal() + corePlugin := new(core.Core) + if e := registry.RegisterCorePlugin(corePlugin); e != nil { + log.Fatal(e.Error()) + } + if e := registry.Run(); e != nil { log.Fatal(e.Error()) } - +} + +func catchSignal() { + sigc := make(chan os.Signal, 1) + signal.Notify(sigc, os.Interrupt, os.Kill, syscall.SIGTERM) + go func(c chan os.Signal) { + sig := <-c + log.Printf("Caught signal %s: shutting down.", sig) + registry.Shutdown() + os.Exit(0) + }(sigc) } diff --git a/registry.go b/registry.go index d58946a..745bfb9 100644 --- a/registry.go +++ b/registry.go @@ -1,5 +1,10 @@ package main +import ( + "fmt" + "github.com/davecgh/go-spew/spew" +) + type PluginRegistry struct { CorePlugin map[string]CoreInterface HandlerPlugin map[string]HandlerInterface @@ -13,6 +18,7 @@ func NewPluginRegistry() *PluginRegistry { } func (r *PluginRegistry) RegisterCorePlugin(plugin CoreInterface) error { + spew.Dump(plugin) name, e := plugin.Register() if e != nil { return e @@ -45,3 +51,34 @@ func (r *PluginRegistry) RemoveCorePlugin(name string) { func (r *PluginRegistry) RemoveHandlerPlugin(name string) { delete(r.HandlerPlugin, name) } + +func (r *PluginRegistry) Run() error { + for _, v := range r.CorePlugin { + if e := v.BeforeRun(); e != nil { + return e + } + } + for _, v := range r.CorePlugin { + if e := v.Run(); e != nil { + return e + } + } + for _, v := range r.CorePlugin { + if e := v.AfterRun(); e != nil { + return e + } + } + return nil +} + +func (r *PluginRegistry) Shutdown() { + fmt.Println("Registry: Shutdown") + spew.Dump(r.CorePlugin) + for k, v := range r.CorePlugin { + fmt.Println(k, v) + if e := v.UnRegister(); e != nil { + panic(e) + } + } + fmt.Println("Registry: Shutdown Done") +}