Skip to content
This repository has been archived by the owner on Mar 15, 2024. It is now read-only.

Commit

Permalink
Move shutdown timeout into param instead of using viper
Browse files Browse the repository at this point in the history
- refactored tests
- fixed typos in README
- moved shutdown timeout into params
- moved usage of viper into a new function (prepare to removal of direct call to viper)
  • Loading branch information
im-kulikov committed Aug 2, 2021
1 parent 527c540 commit 2e543d1
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 40 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ type testWorker struct {

var _ = module.Module{
{Constructor: NewSingleOutService()},
{Constructor: NewSingleService, Options: dig.Group("services")},
{Constructor: NewSingleService, Options: []dig.ProvideOption{dig.Group("services,flatten")},
}

func (w *testWorker) Start(context.Context) error { return nil }
Expand All @@ -222,7 +222,7 @@ func NewSingleOutService() OutParams {
return OutParams{ Service: &testWorker{name: "worker1"} }
}

// module.New(NewSingleService, dig.Group("services")
// module.New(NewSingleService, dig.Group("services,flatten")
func NewSingleService() service.Service {
return &testWorker{name: "worker1"}
}
Expand Down Expand Up @@ -254,7 +254,7 @@ type testWorker struct {

var _ = module.Module{
{Constructor: NewMultipleOut},
{Constructor: NewMultiple, Options: dig.Group("services,flatten")},
{Constructor: NewMultiple, Options: []dig.ProvideOption{dig.Group("services,flatten")},
}

func (w *testWorker) Start(context.Context) error { return nil }
Expand Down
27 changes: 25 additions & 2 deletions service/module.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,34 @@
package service

import "github.com/im-kulikov/helium/module"
import (
"time"

"github.com/spf13/viper"
"go.uber.org/dig"

"github.com/im-kulikov/helium/module"
)

type outParams struct {
dig.Out

Shutdown time.Duration `name:"service_shutdown_timeout"`
}

// ShutdownTimeoutParam name for viper setting.
const ShutdownTimeoutParam = "shutdown_timeout"

var (
_ = Module // prevent unused

// Module for group of services
// nolint:gochecknoglobals
Module = module.New(newGroup)
Module = module.Module{
{Constructor: newParam},
{Constructor: newGroup},
}
)

func newParam(v *viper.Viper) outParams {
return outParams{Shutdown: v.GetDuration(ShutdownTimeoutParam)}
}
15 changes: 7 additions & 8 deletions service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package service

import (
"context"
"time"

"github.com/spf13/viper"
"go.uber.org/dig"
"go.uber.org/zap"

Expand Down Expand Up @@ -31,9 +31,9 @@ type (
Params struct {
dig.In

Logger *zap.Logger
Config *viper.Viper
Group []Service `group:"services"`
Logger *zap.Logger
Group []Service `group:"services"`
Shutdown time.Duration `name:"service_shutdown_timeout"`
}

multiple struct {
Expand All @@ -42,16 +42,15 @@ type (
}
)

// ShutdownTimeoutParam name for viper setting.
const ShutdownTimeoutParam = "shutdown_timeout"

// create group of services.
func newGroup(p Params) Group {
run := &multiple{
Logger: p.Logger,
Service: group.New(group.WithShutdownTimeout(p.Config.GetDuration(ShutdownTimeoutParam))),
Service: group.New(group.WithShutdownTimeout(p.Shutdown)),
}

p.Logger.Info("added workers", zap.Int("count", len(p.Group)))

for i := range p.Group {
if p.Group[i] == nil {
p.Logger.Warn("ignore nil service", zap.Int("position", i))
Expand Down
67 changes: 40 additions & 27 deletions service/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"go.uber.org/zap/zaptest"

"github.com/im-kulikov/helium/internal"
"github.com/im-kulikov/helium/module"
)

type (
Expand Down Expand Up @@ -92,49 +93,61 @@ func TestServices(t *testing.T) {
// should ignore empty service
services = append(services, nil)

grp := newGroup(Params{
Group: services,
Config: viper.New(),
Logger: zaptest.NewLogger(t),
})
di := dig.New()
require.NoError(t, module.Provide(di, Module.Append(module.Module{
{Constructor: func() *viper.Viper {
v := viper.New()
v.SetDefault(ShutdownTimeoutParam, time.Nanosecond)

ctx, cancel := context.WithCancel(context.Background())
return v
}},

group := new(sync.WaitGroup)
start := make(chan struct{})
{
Constructor: func() []Service { return services },
Options: []dig.ProvideOption{dig.Group("services,flatten")},
},

group.Add(1)
{Constructor: func() *zap.Logger { return zaptest.NewLogger(t) }},
})))

go func() {
defer group.Done()
require.NoError(t, di.Invoke(func(grp Group) {
ctx, cancel := context.WithCancel(context.Background())

<-start
require.NoError(t, grp.Run(ctx))
}()
group := new(sync.WaitGroup)
start := make(chan struct{})

close(start)
group.Add(1)

<-time.After(time.Millisecond * 5)
go func() {
defer group.Done()

for i := 0; i < count; i++ {
if wrk, ok := services[i].(*testWorker); ok && !services[i].(*testWorker).started.Load() {
t.Fatalf("worker(%d) should be started", wrk.number)
<-start
require.NoError(t, grp.Run(ctx))
}()

close(start)

<-time.After(time.Millisecond * 5)

for i := 0; i < count; i++ {
if wrk, ok := services[i].(*testWorker); ok && !services[i].(*testWorker).started.Load() {
t.Fatalf("worker(%d) should be started", wrk.number)
}
}
}

cancel()
group.Wait()
for i := 0; i < count; i++ {
require.False(t, services[i].(*testWorker).started.Load())
}
cancel()
group.Wait()
for i := 0; i < count; i++ {
require.False(t, services[i].(*testWorker).started.Load())
}
}))
})

t.Run("should panics on stop", func(t *testing.T) {
t.Run("should error on stop", func(t *testing.T) {
wrk := newWorker()
wrk.errored = true

grp := newGroup(Params{
Config: viper.New(),
Group: []Service{wrk},
Logger: zaptest.NewLogger(t),
})
Expand Down

0 comments on commit 2e543d1

Please sign in to comment.