Skip to content

Commit

Permalink
Merge a6600ef into 1999728
Browse files Browse the repository at this point in the history
  • Loading branch information
henrod committed Aug 14, 2018
2 parents 1999728 + a6600ef commit 9e1ba82
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 30 deletions.
15 changes: 12 additions & 3 deletions app.go
Expand Up @@ -338,9 +338,18 @@ func Start() {
app.serviceDiscovery.AddListener(app.rpcClient.(*cluster.GRPCClient))
}

RegisterModule(app.serviceDiscovery, "serviceDiscovery")
RegisterModule(app.rpcServer, "rpcServer")
RegisterModule(app.rpcClient, "rpcClient")
err := RegisterModuleBefore(app.serviceDiscovery, "serviceDiscovery")
if err != nil {
logger.Log.Fatal("failed to register service discovery module: %s", err.Error())
}
err = RegisterModuleBefore(app.rpcServer, "rpcServer")
if err != nil {
logger.Log.Fatal("failed to register rpc server module: %s", err.Error())
}
err = RegisterModuleBefore(app.rpcClient, "rpcClient")
if err != nil {
logger.Log.Fatal("failed to register rpc client module: %s", err.Error())
}

app.router.SetServiceDiscovery(app.serviceDiscovery)

Expand Down
83 changes: 66 additions & 17 deletions module.go
Expand Up @@ -27,46 +27,95 @@ import (
"github.com/topfreegames/pitaya/logger"
)

var modules = make(map[string]interfaces.Module)
var (
modulesMap = make(map[string]interfaces.Module)
modulesArr = []moduleWrapper{}
)

type moduleWrapper struct {
module interfaces.Module
name string
}

// RegisterModule registers a module
// RegisterModule registers a module, by default it register after registered modules
func RegisterModule(module interfaces.Module, name string) error {
if _, ok := modules[name]; ok {
return fmt.Errorf("module with name %s already exists", name)
return RegisterModuleAfter(module, name)
}

// RegisterModuleAfter registers a module after all registered modules
func RegisterModuleAfter(module interfaces.Module, name string) error {
if err := alreadyRegistered(name); err != nil {
return err
}

modulesMap[name] = module
modulesArr = append(modulesArr, moduleWrapper{
module: module,
name: name,
})

return nil
}

// RegisterModuleBefore registers a module before all registered modules
func RegisterModuleBefore(module interfaces.Module, name string) error {
if err := alreadyRegistered(name); err != nil {
return err
}
modules[name] = module

modulesMap[name] = module
modulesArr = append([]moduleWrapper{
{
module: module,
name: name,
},
}, modulesArr...)

return nil
}

// GetModule gets a module with a name
func GetModule(name string) (interfaces.Module, error) {
if m, ok := modules[name]; ok {
if m, ok := modulesMap[name]; ok {
return m, nil
}
return nil, fmt.Errorf("module with name %s not found", name)
}

// StartModules starts all modules
func alreadyRegistered(name string) error {
if _, ok := modulesMap[name]; ok {
return fmt.Errorf("module with name %s already exists", name)
}

return nil
}

// startModules starts all modules in order
func startModules() {
logger.Log.Debug("initializing all modules")
for name, mod := range modules {
logger.Log.Debugf("initializing module: %s", name)
if err := mod.Init(); err != nil {
logger.Log.Fatalf("error starting module %s, error: %s", name, err.Error())
for _, modWrapper := range modulesArr {
logger.Log.Debugf("initializing module: %s", modWrapper.name)
if err := modWrapper.module.Init(); err != nil {
logger.Log.Fatalf("error starting module %s, error: %s", modWrapper.name, err.Error())
}
}

for name, mod := range modules {
mod.AfterInit()
logger.Log.Infof("module: %s successfully loaded", name)
for _, modWrapper := range modulesArr {
modWrapper.module.AfterInit()
logger.Log.Infof("module: %s successfully loaded", modWrapper.name)
}
}

// shutdownModules starts all modules in reverse order
func shutdownModules() {
for _, mod := range modules {
mod.BeforeShutdown()
for i := len(modulesArr) - 1; i >= 0; i-- {
modulesArr[i].module.BeforeShutdown()
}
for name, mod := range modules {

for i := len(modulesArr) - 1; i >= 0; i-- {
name := modulesArr[i].name
mod := modulesArr[i].module

logger.Log.Debugf("stopping module: %s", name)
if err := mod.Shutdown(); err != nil {
logger.Log.Warnf("error stopping module: %s", name)
Expand Down
55 changes: 45 additions & 10 deletions module_test.go
Expand Up @@ -32,29 +32,39 @@ import (
type MyMod struct {
component.Base
running bool
name string
}

var modulesOrder []string

func resetModules() {
modulesMap = make(map[string]interfaces.Module)
modulesArr = []moduleWrapper{}
modulesOrder = []string{}
}

func (m *MyMod) Init() error {
m.running = true
modulesOrder = append(modulesOrder, m.name)
return nil
}

func (m *MyMod) Shutdown() error {
m.running = false
modulesOrder = append(modulesOrder, m.name)
return nil
}

func resetModules() {
modules = make(map[string]interfaces.Module)
}

func TestRegisterModule(t *testing.T) {
resetModules()
b := &MyMod{}
err := RegisterModule(b, "mod")
assert.NoError(t, err)
assert.Equal(t, 1, len(modules))
assert.Equal(t, b, modules["mod"])
assert.Equal(t, 1, len(modulesMap))
assert.Equal(t, b, modulesMap["mod"])
assert.Equal(t, 1, len(modulesArr))
assert.Equal(t, "mod", modulesArr[0].name)
assert.Equal(t, b, modulesArr[0].module)
err = RegisterModule(b, "mod")
assert.Error(t, err)
}
Expand All @@ -76,19 +86,44 @@ func TestStartupModules(t *testing.T) {
resetModules()
Configure(true, "testtype", Standalone, map[string]string{}, viper.New())

RegisterModule(&MyMod{}, "bla")
err := RegisterModule(&MyMod{name: "mod1"}, "mod1")
assert.NoError(t, err)
err = RegisterModuleBefore(&MyMod{name: "mod2"}, "mod2")
assert.NoError(t, err)
err = RegisterModuleBefore(&MyMod{name: "mod3"}, "mod3")
assert.NoError(t, err)
err = RegisterModuleAfter(&MyMod{name: "mod4"}, "mod4")
assert.NoError(t, err)

startModules()
assert.Equal(t, true, modules["bla"].(*MyMod).running)
assert.Equal(t, true, modulesMap["mod1"].(*MyMod).running)
assert.Equal(t, true, modulesMap["mod2"].(*MyMod).running)
assert.Equal(t, true, modulesMap["mod3"].(*MyMod).running)
assert.Equal(t, true, modulesMap["mod4"].(*MyMod).running)
assert.Equal(t, []string{"mod3", "mod2", "mod1", "mod4"}, modulesOrder)
}

func TestShutdownModules(t *testing.T) {
resetModules()
initApp()
Configure(true, "testtype", Standalone, map[string]string{}, viper.New())

RegisterModule(&MyMod{}, "bla")
err := RegisterModule(&MyMod{name: "mod1"}, "mod1")
assert.NoError(t, err)
err = RegisterModuleBefore(&MyMod{name: "mod2"}, "mod2")
assert.NoError(t, err)
err = RegisterModuleBefore(&MyMod{name: "mod3"}, "mod3")
assert.NoError(t, err)
err = RegisterModuleAfter(&MyMod{name: "mod4"}, "mod4")
assert.NoError(t, err)

startModules()

modulesOrder = []string{}
shutdownModules()
assert.Equal(t, false, modules["bla"].(*MyMod).running)
assert.Equal(t, false, modulesMap["mod1"].(*MyMod).running)
assert.Equal(t, false, modulesMap["mod2"].(*MyMod).running)
assert.Equal(t, false, modulesMap["mod3"].(*MyMod).running)
assert.Equal(t, false, modulesMap["mod4"].(*MyMod).running)
assert.Equal(t, []string{"mod4", "mod1", "mod2", "mod3"}, modulesOrder)
}

0 comments on commit 9e1ba82

Please sign in to comment.