diff --git a/EXPERIMENTAL/typicmd/application/application.go b/EXPERIMENTAL/typicmd/application/application.go index d54cdf39..18b69ae1 100644 --- a/EXPERIMENTAL/typicmd/application/application.go +++ b/EXPERIMENTAL/typicmd/application/application.go @@ -18,7 +18,7 @@ type application struct { func (a application) Run(ctx *cli.Context) (err error) { di := dig.New() - defer a.Destruct(di) + defer a.Close(di) gracefulStop := make(chan os.Signal) signal.Notify(gracefulStop, syscall.SIGTERM) signal.Notify(gracefulStop, syscall.SIGINT) @@ -36,7 +36,7 @@ func (a application) Run(ctx *cli.Context) (err error) { go func() { <-gracefulStop fmt.Println("\n\n\nGraceful Shutdown...") - a.Destruct(di) + a.Close(di) }() runner := a.Application.(typiobj.Runner) return runner.Run(di) @@ -50,3 +50,15 @@ func (a application) Provide() (constructors []interface{}) { } return } + +func (a application) Destroy() (destructors []interface{}) { + destructors = append(destructors, a.Modules.Destroy()...) + if destroyer, ok := a.Application.(typiobj.Destroyer); ok { + destructors = append(destructors, destroyer.Destroy()...) + } + return +} + +func (a application) Close(c *dig.Container) (err error) { + return typiobj.Destroy(c, a) +} diff --git a/EXPERIMENTAL/typictx/context.go b/EXPERIMENTAL/typictx/context.go index f106df0b..09f0f6db 100644 --- a/EXPERIMENTAL/typictx/context.go +++ b/EXPERIMENTAL/typictx/context.go @@ -3,7 +3,6 @@ package typictx import ( "github.com/typical-go/typical-rest-server/EXPERIMENTAL/slice" "github.com/typical-go/typical-rest-server/EXPERIMENTAL/typiobj" - "go.uber.org/dig" ) // Context of typical application @@ -51,14 +50,14 @@ func (c *Context) Configurations() (cfgs []typiobj.Configuration) { // } // Destruct dependencies -func (c *Context) Destruct(container *dig.Container) (err error) { - if destructor, ok := c.Application.(typiobj.Destructor); ok { - if err = destructor.Destruct(container); err != nil { - return - } - } - return c.Modules.Destruct(container) -} +// func (c *Context) Destruct(container *dig.Container) (err error) { +// if destructor, ok := c.Application.(typiobj.Destructor); ok { +// if err = destructor.Destruct(container); err != nil { +// return +// } +// } +// return c.Modules.Destruct(container) +// } // Preparing context // TODO: rename back to validate as conflicting with life cycle phase diff --git a/EXPERIMENTAL/typiobj/cli.go b/EXPERIMENTAL/typiobj/cli.go index 046cfa17..9a77a3ef 100644 --- a/EXPERIMENTAL/typiobj/cli.go +++ b/EXPERIMENTAL/typiobj/cli.go @@ -10,8 +10,10 @@ func CliAction(p interface{}, fn interface{}) func(ctx *cli.Context) error { return func(ctx *cli.Context) (err error) { c := dig.New() defer func() { - if destructor, ok := p.(Destructor); ok { - destructor.Destruct(c) + if destroyer, ok := p.(Destroyer); ok { + if err = Destroy(c, destroyer); err != nil { + return + } } }() if provider, ok := p.(Provider); ok { diff --git a/EXPERIMENTAL/typiobj/destroyer.go b/EXPERIMENTAL/typiobj/destroyer.go new file mode 100644 index 00000000..29ffce54 --- /dev/null +++ b/EXPERIMENTAL/typiobj/destroyer.go @@ -0,0 +1,24 @@ +package typiobj + +import "go.uber.org/dig" + +// Destroyer responsible to destruct dependency +type Destroyer interface { + Destroy() []interface{} +} + +// Destroy to execute destroyer +func Destroy(c *dig.Container, d Destroyer) (err error) { + for _, destructor := range d.Destroy() { + if err = c.Invoke(destructor); err != nil { + return + } + } + return +} + +// IsDestroyer return true if object implementation of destructor +func IsDestroyer(obj interface{}) (ok bool) { + _, ok = obj.(Destroyer) + return +} diff --git a/EXPERIMENTAL/typiobj/modules.go b/EXPERIMENTAL/typiobj/modules.go index 9009afa7..4176266b 100644 --- a/EXPERIMENTAL/typiobj/modules.go +++ b/EXPERIMENTAL/typiobj/modules.go @@ -3,7 +3,6 @@ package typiobj import ( "github.com/typical-go/typical-rest-server/EXPERIMENTAL/slice" "github.com/urfave/cli" - "go.uber.org/dig" ) // Modules is list of module @@ -39,13 +38,11 @@ func (m Modules) Provide() (constructors []interface{}) { return } -// Destruct dependency -func (m Modules) Destruct(c *dig.Container) (err error) { +// Destroy dependency +func (m Modules) Destroy() (destructors []interface{}) { for _, module := range m { - if destructor, ok := module.(Destructor); ok { - if err = destructor.Destruct(c); err != nil { - return - } + if destroyer, ok := module.(Destroyer); ok { + destructors = append(destructors, destroyer.Destroy()...) } } return diff --git a/EXPERIMENTAL/typiobj/object.go b/EXPERIMENTAL/typiobj/object.go index 373d14f8..bb164ee3 100644 --- a/EXPERIMENTAL/typiobj/object.go +++ b/EXPERIMENTAL/typiobj/object.go @@ -18,12 +18,6 @@ func IsProvider(obj interface{}) (ok bool) { return } -// IsDestructor return true if object implementation of destructor -func IsDestructor(obj interface{}) (ok bool) { - _, ok = obj.(Destructor) - return -} - // IsCommandLiner return true if object implementation of CommandLiner func IsCommandLiner(obj interface{}) (ok bool) { _, ok = obj.(CommandLiner) diff --git a/EXPERIMENTAL/typiobj/types.go b/EXPERIMENTAL/typiobj/types.go index f723fb89..1003015c 100644 --- a/EXPERIMENTAL/typiobj/types.go +++ b/EXPERIMENTAL/typiobj/types.go @@ -15,11 +15,6 @@ type Provider interface { Provide() []interface{} } -// Destructor responsible to destruct dependency -type Destructor interface { - Destruct(c *dig.Container) error -} - // CommandLiner responsible to give command type CommandLiner interface { CommandLine() cli.Command diff --git a/pkg/typpostgres/module.go b/pkg/typpostgres/module.go index ca2ef4e9..f735dbd7 100644 --- a/pkg/typpostgres/module.go +++ b/pkg/typpostgres/module.go @@ -17,7 +17,6 @@ import ( "github.com/typical-go/typical-rest-server/EXPERIMENTAL/typiobj" "github.com/typical-go/typical-rest-server/pkg/utility/envkit" "github.com/urfave/cli" - "go.uber.org/dig" ) const ( @@ -67,9 +66,11 @@ func (p postgresModule) Provide() []interface{} { } } -// Destruct dependencies -func (p postgresModule) Destruct(c *dig.Container) (err error) { - return c.Invoke(p.closeConnection) +// Destroy dependencies +func (p postgresModule) Destroy() []interface{} { + return []interface{}{ + p.closeConnection, + } } func (p postgresModule) loadConfig() (cfg *Config, err error) { diff --git a/pkg/typpostgres/module_test.go b/pkg/typpostgres/module_test.go index bc15a158..0960ec6e 100644 --- a/pkg/typpostgres/module_test.go +++ b/pkg/typpostgres/module_test.go @@ -11,7 +11,7 @@ import ( func TestModule(t *testing.T) { m := typpostgres.Module() require.True(t, typiobj.IsProvider(m)) - require.True(t, typiobj.IsDestructor(m)) + require.True(t, typiobj.IsDestroyer(m)) require.True(t, typiobj.IsCommandLiner(m)) require.True(t, typiobj.IsConfigurer(m)) } diff --git a/pkg/typredis/module.go b/pkg/typredis/module.go index 63e7b616..1928a7c2 100644 --- a/pkg/typredis/module.go +++ b/pkg/typredis/module.go @@ -10,7 +10,6 @@ import ( "github.com/typical-go/typical-rest-server/EXPERIMENTAL/typiobj" "github.com/typical-go/typical-rest-server/pkg/utility/envkit" "github.com/urfave/cli" - "go.uber.org/dig" ) // Module of redis @@ -37,9 +36,11 @@ func (r redisModule) Provide() []interface{} { } } -// Destruct dependencies -func (r redisModule) Destruct(c *dig.Container) (err error) { - return c.Invoke(c) +// Destroy dependencies +func (r redisModule) Destroy() []interface{} { + return []interface{}{ + r.disconnect, + } } // CommandLine return command diff --git a/pkg/typredis/module_test.go b/pkg/typredis/module_test.go index f18f05e2..48ec840e 100644 --- a/pkg/typredis/module_test.go +++ b/pkg/typredis/module_test.go @@ -11,7 +11,7 @@ import ( func TestModule(t *testing.T) { m := typredis.Module() require.True(t, typiobj.IsProvider(m)) - require.True(t, typiobj.IsDestructor(m)) + require.True(t, typiobj.IsDestroyer(m)) require.True(t, typiobj.IsCommandLiner(m)) require.True(t, typiobj.IsConfigurer(m)) } diff --git a/pkg/typserver/module.go b/pkg/typserver/module.go index 970ab240..a80cdc00 100644 --- a/pkg/typserver/module.go +++ b/pkg/typserver/module.go @@ -6,7 +6,6 @@ import ( "github.com/kelseyhightower/envconfig" "github.com/typical-go/typical-rest-server/EXPERIMENTAL/typiobj" - "go.uber.org/dig" logrusmiddleware "github.com/bakatz/echo-logrusmiddleware" "github.com/labstack/echo" @@ -36,8 +35,10 @@ func (s serverModule) Provide() []interface{} { } } -func (s serverModule) Destruct(c *dig.Container) (err error) { - return c.Invoke(s.Shutdown) +func (s serverModule) Destroy() []interface{} { + return []interface{}{ + s.Shutdown, + } } func (s serverModule) loadConfig() (cfg *Config, err error) { diff --git a/pkg/typserver/module_test.go b/pkg/typserver/module_test.go index c7a5808b..085ac7cf 100644 --- a/pkg/typserver/module_test.go +++ b/pkg/typserver/module_test.go @@ -11,6 +11,6 @@ import ( func TestModule(t *testing.T) { m := typserver.Module() require.True(t, typiobj.IsProvider(m)) - require.True(t, typiobj.IsDestructor(m)) + require.True(t, typiobj.IsDestroyer(m)) require.True(t, typiobj.IsConfigurer(m)) }