@@ -24,7 +24,7 @@ const httpShutdownTimeout = 10 * time.Second //nolint: mnd
2424
2525// Service is the main advancer service that processes inputs through Cartesi machines
2626type Service struct {
27- service.Service
27+ service.TickService
2828 inputBatchSize uint64
2929 snapshotsDir string
3030 repository AdvancerRepository
@@ -54,10 +54,11 @@ func Create(ctx context.Context, c *CreateInfo) (service.IService, error) {
5454 }
5555
5656 s := & Service {}
57+ s .TickImpl = s
5758 c .Impl = s
5859 c .EnableReschedule = true
5960
60- err = service .Create ( ctx , & c .CreateInfo , & s .Service )
61+ err = service .NewTickService ( & c .CreateInfo , & s .TickService )
6162 if err != nil {
6263 return nil , err
6364 }
@@ -96,15 +97,12 @@ func Create(ctx context.Context, c *CreateInfo) (service.IService, error) {
9697
9798 s .LogConfig (c .Config )
9899
99- return & s . Service , nil
100+ return s , nil
100101}
101102
102103// Service interface implementation
103- func (s * Service ) Alive () bool { return true }
104- func (s * Service ) Ready () bool { return true }
105- func (s * Service ) Reload () []error { return nil }
106- func (s * Service ) Tick () []error {
107- hadWork , err := s .Step (s .Context )
104+ func (s * Service ) Tick (ctx context.Context ) []error {
105+ hadWork , err := s .Step (ctx )
108106
109107 // Signal reschedule whenever work was done, even if some apps errored.
110108 // Failed apps are marked Failed and removed by the machine manager,
@@ -119,25 +117,14 @@ func (s *Service) Tick() []error {
119117 }
120118 // During shutdown, the machine manager is closed and GetMachine() may
121119 // return ErrNoApp. Suppress this to avoid spurious ERR log entries.
122- if errors .Is (err , ErrNoApp ) && s . IsStopping () {
120+ if errors .Is (err , ErrNoApp ) && ctx . Err () != nil {
123121 s .Logger .Warn ("Tick interrupted by shutdown" , "error" , err )
124122 return nil
125123 }
126124 return []error {err }
127125}
128126
129- func (s * Service ) Stop (b bool ) []error {
130- // CAS achieves once-semantics: the second caller returns immediately
131- // (fire-and-forget) rather than blocking like sync.Once. This is safe
132- // because the orchestrator calls Cancel() after Stop() and waits for
133- // the Serve goroutine to exit.
134- if ! s .cleanedUp .CompareAndSwap (false , true ) {
135- return nil // already stopped
136- }
137- // This method shadows service.Service.Stop(), so set the stopping flag
138- // explicitly. Without this, a concurrent Tick that observes closed
139- // resources would not see IsStopping() == true.
140- s .SetStopping ()
127+ func (s * Service ) fonStop (b bool ) []error {
141128 var errs []error
142129 if s .HTTPServer != nil {
143130 s .Logger .Info ("Shutting down inspect HTTP server" )
@@ -155,17 +142,15 @@ func (s *Service) Stop(b bool) []error {
155142 }
156143 return errs
157144}
158- func (s * Service ) Serve () error {
145+
146+ func (s * Service ) OnServe (ctx context.Context ) error {
159147 if s .inspector != nil && s .HTTPServerFunc != nil {
160148 go func () {
161149 if err := s .HTTPServerFunc (); err != nil && ! errors .Is (err , http .ErrServerClosed ) {
162150 s .Logger .Error ("Inspect HTTP server failed — shutting down" , "error" , err )
163- s .Cancel ( )
151+ s .Stop ( true )
164152 }
165153 }()
166154 }
167- return s .Service .Serve ()
168- }
169- func (s * Service ) String () string {
170- return s .Name
155+ return s .TickService .OnServe (ctx )
171156}
0 commit comments