11package submodule
22
33import (
4+ "context"
45 "reflect"
56 "sync"
67)
@@ -34,7 +35,8 @@ type Scope interface {
3435 InitError (g Retrievable , e error )
3536
3637 Dispose () error
37- AppendMiddleware (Middleware )
38+ DisposeWithContext (ctx context.Context ) error
39+ AppendMiddleware (... Middleware )
3840 Apply (Submodule [Middleware ])
3941}
4042
@@ -140,44 +142,94 @@ func (s *scope) Apply(submodule Submodule[Middleware]) {
140142 s .AppendMiddleware (m )
141143}
142144
143- // Dispose scope to free up all resolved values and trigger scope end middlewares
144- func (s * scope ) Dispose () error {
145+ // remove all values in the scope
146+ func (s * scope ) release () {
147+ s .mu .Lock ()
148+ defer s .mu .Unlock ()
149+
150+ for k := range s .values {
151+ delete (s .values , k )
152+ }
153+ }
154+
155+ type middlewareCaller func (Middleware ) error
156+
157+ func (s * scope ) dispose (cond middlewareCaller ) error {
145158 for _ , m := range s .middleware {
146159 if m .hasOnScopeEnd {
147- e := m .onScopeEnd ()
148- if e != nil {
149- return e
160+ if err := cond (m ); err != nil {
161+ return err
150162 }
151163 }
152164 }
165+ return nil
166+ }
153167
154- s .mu .Lock ()
155- defer s .mu .Unlock ()
168+ var disposeCond = func (m Middleware ) error {
169+ if m .onScopeEnd != nil {
170+ return m .onScopeEnd ()
171+ }
172+ return nil
173+ }
156174
157- for k := range s .values {
158- delete (s .values , k )
175+ var disposeWithContextCond = func (ctx context.Context ) func (m Middleware ) error {
176+ return func (m Middleware ) error {
177+ if m .onScopeEndWithContext != nil {
178+ return m .onScopeEndWithContext (ctx )
179+ }
180+ return nil
159181 }
182+ }
160183
184+ // DisposeWithContext dispose scope with context
185+ func (s * scope ) DisposeWithContext (ctx context.Context ) error {
186+ if err := s .dispose (disposeWithContextCond (ctx )); err != nil {
187+ return err
188+ }
189+ if err := s .dispose (disposeCond ); err != nil {
190+ return err
191+ }
192+ s .release ()
193+ return nil
194+ }
195+
196+ // Dispose scope to free up all resolved values and trigger scope end middlewares
197+ func (s * scope ) Dispose () error {
198+ if err := s .dispose (disposeWithContextCond (context .TODO ())); err != nil {
199+ return err
200+ }
201+ if err := s .dispose (disposeCond ); err != nil {
202+ return err
203+ }
204+ s .release ()
161205 return nil
162206}
163207
164208// Append middleware to the scope
165- func (s * scope ) AppendMiddleware (m Middleware ) {
166- s .middleware = append (s .middleware , m )
209+ func (s * scope ) AppendMiddleware (m ... Middleware ) {
210+ if len (m ) == 0 {
211+ return
212+ }
213+ s .middleware = append (s .middleware , m ... )
167214}
168215
169216// Append global middleware to the global scope
170217func AppendGlobalMiddleware (ms ... Middleware ) {
171- for _ , m := range ms {
172- globalScope . AppendMiddleware ( m )
218+ if len ( ms ) == 0 {
219+ return
173220 }
221+ globalScope .AppendMiddleware (ms ... )
174222}
175223
176224// Dispose global scope to free up all resolved values and trigger scope end middlewares
177225func DisposeGlobalScope () error {
178226 return globalScope .Dispose ()
179227}
180228
229+ func DisposeGlobalScopeWithContext (ctx context.Context ) error {
230+ return globalScope .DisposeWithContext (ctx )
231+ }
232+
181233// Apply middleware to the global scope
182234func Apply (s Middleware ) {
183235 globalScope .AppendMiddleware (s )
@@ -194,7 +246,8 @@ type Middleware struct {
194246 onScopeResolveType reflect.Type
195247 onScopeResolve reflect.Value
196248
197- onScopeEnd func () error
249+ onScopeEnd func () error
250+ onScopeEndWithContext func (context.Context ) error
198251}
199252
200253type MiddlewareFn func (Middleware ) Middleware
@@ -214,6 +267,13 @@ func WithScopeEnd(fn func() error) Middleware {
214267 }
215268}
216269
270+ func WithContextScopeEnd (fn func (context.Context ) error ) Middleware {
271+ return Middleware {
272+ hasOnScopeEnd : true ,
273+ onScopeEndWithContext : fn ,
274+ }
275+ }
276+
217277type ScopeOpts struct {
218278 inherit bool
219279 parent Scope
0 commit comments