From 05a0543e0021380e2e946c5179ef7c47643866a5 Mon Sep 17 00:00:00 2001 From: Andreas Linde Date: Wed, 16 Oct 2024 14:05:54 +0200 Subject: [PATCH 1/2] Refactor service start & stop Make it possible to shutdown an initialized service and start it again. Also add the option to get the current service run status --- api/api.go | 3 +++ mocks/ServiceInterface.go | 45 +++++++++++++++++++++++++++++++++++++++ service/service.go | 36 ++++++++++++++++++++++++++----- 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/api/api.go b/api/api.go index 688e2f2b..c9647f7b 100644 --- a/api/api.go +++ b/api/api.go @@ -24,6 +24,9 @@ type ServiceInterface interface { // shutdown the service Shutdown() + // return if the service is running + IsRunning() bool + // add a use case to the service AddUseCase(useCase UseCaseInterface) diff --git a/mocks/ServiceInterface.go b/mocks/ServiceInterface.go index c2a318b9..868ead26 100644 --- a/mocks/ServiceInterface.go +++ b/mocks/ServiceInterface.go @@ -218,6 +218,51 @@ func (_c *ServiceInterface_IsAutoAcceptEnabled_Call) RunAndReturn(run func() boo return _c } +// IsRunning provides a mock function with given fields: +func (_m *ServiceInterface) IsRunning() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for IsRunning") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// ServiceInterface_IsRunning_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsRunning' +type ServiceInterface_IsRunning_Call struct { + *mock.Call +} + +// IsRunning is a helper method to define mock.On call +func (_e *ServiceInterface_Expecter) IsRunning() *ServiceInterface_IsRunning_Call { + return &ServiceInterface_IsRunning_Call{Call: _e.mock.On("IsRunning")} +} + +func (_c *ServiceInterface_IsRunning_Call) Run(run func()) *ServiceInterface_IsRunning_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ServiceInterface_IsRunning_Call) Return(_a0 bool) *ServiceInterface_IsRunning_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ServiceInterface_IsRunning_Call) RunAndReturn(run func() bool) *ServiceInterface_IsRunning_Call { + _c.Call.Return(run) + return _c +} + // LocalDevice provides a mock function with given fields: func (_m *ServiceInterface) LocalDevice() spine_goapi.DeviceLocalInterface { ret := _m.Called() diff --git a/service/service.go b/service/service.go index a5a571f9..4aa972fb 100644 --- a/service/service.go +++ b/service/service.go @@ -42,9 +42,11 @@ type Service struct { // defines wether a user interaction to accept pairing is possible isPairingPossible bool - startOnce sync.Once + // return if the service is running + isRunning bool - mux sync.Mutex + mux sync.Mutex + muxRunning sync.Mutex } // creates a new EEBUS service @@ -153,15 +155,39 @@ func (s *Service) Setup() error { // Starts the service func (s *Service) Start() { - s.startOnce.Do(func() { - s.connectionsHub.Start() - }) + s.muxRunning.Lock() + defer s.muxRunning.Unlock() + + // make sure we do not start twice while the service is already running + if s.isRunning { + return + } + + s.connectionsHub.Start() } // Shutdown all services and stop the server. func (s *Service) Shutdown() { + s.muxRunning.Lock() + defer s.muxRunning.Unlock() + + // if the service is not running, we do not need to shut it down + if !s.isRunning { + return + } + // Shut down all running connections s.connectionsHub.Shutdown() + + s.isRunning = false +} + +// return if the service is running +func (s *Service) IsRunning() bool { + s.muxRunning.Lock() + defer s.muxRunning.Unlock() + + return s.isRunning } // add a use case to the service From d203cf713765c33e797847c79b0e48734d858363 Mon Sep 17 00:00:00 2001 From: Andreas Linde Date: Wed, 16 Oct 2024 14:56:22 +0200 Subject: [PATCH 2/2] Add missing set and extend tests --- service/service.go | 2 ++ service/service_test.go | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/service/service.go b/service/service.go index 4aa972fb..7542250a 100644 --- a/service/service.go +++ b/service/service.go @@ -164,6 +164,8 @@ func (s *Service) Start() { } s.connectionsHub.Start() + + s.isRunning = true } // Shutdown all services and stop the server. diff --git a/service/service_test.go b/service/service_test.go index d74d4ab8..fa64e8da 100644 --- a/service/service_test.go +++ b/service/service_test.go @@ -171,12 +171,21 @@ func (s *ServiceSuite) Test_Setup() { assert.Equal(s.T(), "d:_n:vendor_model-serial", string(*address)) s.sut.connectionsHub = s.conHub - s.conHub.EXPECT().Start() + s.conHub.EXPECT().Start().Once() s.sut.Start() time.Sleep(time.Millisecond * 200) - s.conHub.EXPECT().Shutdown() + isRunning := s.sut.IsRunning() + assert.True(s.T(), isRunning) + + // nothing should happen + s.sut.Start() + + s.conHub.EXPECT().Shutdown().Once() + s.sut.Shutdown() + + // nothing should happen s.sut.Shutdown() device := s.sut.LocalDevice()