@@ -3,6 +3,7 @@ package signal
33import (
44 "context"
55 "sync"
6+ "sync/atomic"
67
78 "github.com/tech-engine/goscrapy/pkg/core"
89)
@@ -24,30 +25,30 @@ type ItemBus[OUT any] interface {
2425
2526// typed signal bus
2627type Bus [OUT any ] struct {
27- mu sync.RWMutex
28+ mu sync.Mutex
2829
2930 // spider signals
30- spiderOpened [ ]func (context.Context )
31- spiderClosed [ ]func (context.Context )
32- spiderError [ ]func (context.Context , error )
33- spiderIdle [ ]func (context.Context )
31+ spiderOpened atomic. Pointer [[ ]func (context.Context )]
32+ spiderClosed atomic. Pointer [[ ]func (context.Context )]
33+ spiderError atomic. Pointer [[ ]func (context.Context , error )]
34+ spiderIdle atomic. Pointer [[ ]func (context.Context )]
3435
3536 // item signals
36- itemScraped [ ]func (context.Context , OUT )
37- itemDropped [ ]func (context.Context , OUT , error )
38- itemError [ ]func (context.Context , OUT , error )
37+ itemScraped atomic. Pointer [[ ]func (context.Context , OUT )]
38+ itemDropped atomic. Pointer [[ ]func (context.Context , OUT , error )]
39+ itemError atomic. Pointer [[ ]func (context.Context , OUT , error )]
3940
4041 // request signals
41- requestScheduled [ ]func (context.Context , * core.Request )
42- requestDropped [ ]func (context.Context , * core.Request , error )
43- requestError [ ]func (context.Context , * core.Request , error )
42+ requestScheduled atomic. Pointer [[ ]func (context.Context , * core.Request )]
43+ requestDropped atomic. Pointer [[ ]func (context.Context , * core.Request , error )]
44+ requestError atomic. Pointer [[ ]func (context.Context , * core.Request , error )]
4445
4546 // response signals
46- responseReceived [ ]func (context.Context , core.IResponseReader )
47+ responseReceived atomic. Pointer [[ ]func (context.Context , core.IResponseReader )]
4748
4849 // engine signals
49- engineStarted [ ]func (context.Context )
50- engineStopped [ ]func (context.Context )
50+ engineStarted atomic. Pointer [[ ]func (context.Context )]
51+ engineStopped atomic. Pointer [[ ]func (context.Context )]
5152}
5253
5354// create new signal bus
@@ -58,194 +59,259 @@ func New[OUT any]() *Bus[OUT] {
5859func (b * Bus [OUT ]) OnSpiderOpened (h func (context.Context )) {
5960 b .mu .Lock ()
6061 defer b .mu .Unlock ()
61- b .spiderOpened = append (b .spiderOpened , h )
62+ old := b .spiderOpened .Load ()
63+ var newHandlers []func (context.Context )
64+ if old != nil {
65+ newHandlers = append ([]func (context.Context ){}, * old ... )
66+ }
67+ newHandlers = append (newHandlers , h )
68+ b .spiderOpened .Store (& newHandlers )
6269}
6370
6471func (b * Bus [OUT ]) OnSpiderClosed (h func (context.Context )) {
6572 b .mu .Lock ()
6673 defer b .mu .Unlock ()
67- b .spiderClosed = append (b .spiderClosed , h )
74+ old := b .spiderClosed .Load ()
75+ var newHandlers []func (context.Context )
76+ if old != nil {
77+ newHandlers = append ([]func (context.Context ){}, * old ... )
78+ }
79+ newHandlers = append (newHandlers , h )
80+ b .spiderClosed .Store (& newHandlers )
6881}
6982
7083func (b * Bus [OUT ]) OnSpiderError (h func (context.Context , error )) {
7184 b .mu .Lock ()
7285 defer b .mu .Unlock ()
73- b .spiderError = append (b .spiderError , h )
86+ old := b .spiderError .Load ()
87+ var newHandlers []func (context.Context , error )
88+ if old != nil {
89+ newHandlers = append ([]func (context.Context , error ){}, * old ... )
90+ }
91+ newHandlers = append (newHandlers , h )
92+ b .spiderError .Store (& newHandlers )
7493}
7594
7695func (b * Bus [OUT ]) OnSpiderIdle (h func (context.Context )) {
7796 b .mu .Lock ()
7897 defer b .mu .Unlock ()
79- b .spiderIdle = append (b .spiderIdle , h )
98+ old := b .spiderIdle .Load ()
99+ var newHandlers []func (context.Context )
100+ if old != nil {
101+ newHandlers = append ([]func (context.Context ){}, * old ... )
102+ }
103+ newHandlers = append (newHandlers , h )
104+ b .spiderIdle .Store (& newHandlers )
80105}
81106
82107func (b * Bus [OUT ]) OnItemScraped (h func (context.Context , OUT )) {
83108 b .mu .Lock ()
84109 defer b .mu .Unlock ()
85- b .itemScraped = append (b .itemScraped , h )
110+ old := b .itemScraped .Load ()
111+ var newHandlers []func (context.Context , OUT )
112+ if old != nil {
113+ newHandlers = append ([]func (context.Context , OUT ){}, * old ... )
114+ }
115+ newHandlers = append (newHandlers , h )
116+ b .itemScraped .Store (& newHandlers )
86117}
87118
88119func (b * Bus [OUT ]) OnItemDropped (h func (context.Context , OUT , error )) {
89120 b .mu .Lock ()
90121 defer b .mu .Unlock ()
91- b .itemDropped = append (b .itemDropped , h )
122+ old := b .itemDropped .Load ()
123+ var newHandlers []func (context.Context , OUT , error )
124+ if old != nil {
125+ newHandlers = append ([]func (context.Context , OUT , error ){}, * old ... )
126+ }
127+ newHandlers = append (newHandlers , h )
128+ b .itemDropped .Store (& newHandlers )
92129}
93130
94131func (b * Bus [OUT ]) OnItemError (h func (context.Context , OUT , error )) {
95132 b .mu .Lock ()
96133 defer b .mu .Unlock ()
97- b .itemError = append (b .itemError , h )
134+ old := b .itemError .Load ()
135+ var newHandlers []func (context.Context , OUT , error )
136+ if old != nil {
137+ newHandlers = append ([]func (context.Context , OUT , error ){}, * old ... )
138+ }
139+ newHandlers = append (newHandlers , h )
140+ b .itemError .Store (& newHandlers )
98141}
99142
100143func (b * Bus [OUT ]) OnRequestScheduled (h func (context.Context , * core.Request )) {
101144 b .mu .Lock ()
102145 defer b .mu .Unlock ()
103- b .requestScheduled = append (b .requestScheduled , h )
146+ old := b .requestScheduled .Load ()
147+ var newHandlers []func (context.Context , * core.Request )
148+ if old != nil {
149+ newHandlers = append ([]func (context.Context , * core.Request ){}, * old ... )
150+ }
151+ newHandlers = append (newHandlers , h )
152+ b .requestScheduled .Store (& newHandlers )
104153}
105154
106155func (b * Bus [OUT ]) OnRequestDropped (h func (context.Context , * core.Request , error )) {
107156 b .mu .Lock ()
108157 defer b .mu .Unlock ()
109- b .requestDropped = append (b .requestDropped , h )
158+ old := b .requestDropped .Load ()
159+ var newHandlers []func (context.Context , * core.Request , error )
160+ if old != nil {
161+ newHandlers = append ([]func (context.Context , * core.Request , error ){}, * old ... )
162+ }
163+ newHandlers = append (newHandlers , h )
164+ b .requestDropped .Store (& newHandlers )
110165}
111166
112167func (b * Bus [OUT ]) OnRequestError (h func (context.Context , * core.Request , error )) {
113168 b .mu .Lock ()
114169 defer b .mu .Unlock ()
115- b .requestError = append (b .requestError , h )
170+ old := b .requestError .Load ()
171+ var newHandlers []func (context.Context , * core.Request , error )
172+ if old != nil {
173+ newHandlers = append ([]func (context.Context , * core.Request , error ){}, * old ... )
174+ }
175+ newHandlers = append (newHandlers , h )
176+ b .requestError .Store (& newHandlers )
116177}
117178
118179func (b * Bus [OUT ]) OnResponseReceived (h func (context.Context , core.IResponseReader )) {
119180 b .mu .Lock ()
120181 defer b .mu .Unlock ()
121- b .responseReceived = append (b .responseReceived , h )
182+ old := b .responseReceived .Load ()
183+ var newHandlers []func (context.Context , core.IResponseReader )
184+ if old != nil {
185+ newHandlers = append ([]func (context.Context , core.IResponseReader ){}, * old ... )
186+ }
187+ newHandlers = append (newHandlers , h )
188+ b .responseReceived .Store (& newHandlers )
122189}
123190
124191func (b * Bus [OUT ]) OnEngineStarted (h func (context.Context )) {
125192 b .mu .Lock ()
126193 defer b .mu .Unlock ()
127- b .engineStarted = append (b .engineStarted , h )
194+ old := b .engineStarted .Load ()
195+ var newHandlers []func (context.Context )
196+ if old != nil {
197+ newHandlers = append ([]func (context.Context ){}, * old ... )
198+ }
199+ newHandlers = append (newHandlers , h )
200+ b .engineStarted .Store (& newHandlers )
128201}
129202
130203func (b * Bus [OUT ]) OnEngineStopped (h func (context.Context )) {
131204 b .mu .Lock ()
132205 defer b .mu .Unlock ()
133- b .engineStopped = append (b .engineStopped , h )
206+ old := b .engineStopped .Load ()
207+ var newHandlers []func (context.Context )
208+ if old != nil {
209+ newHandlers = append ([]func (context.Context ){}, * old ... )
210+ }
211+ newHandlers = append (newHandlers , h )
212+ b .engineStopped .Store (& newHandlers )
134213}
135214
136215func (b * Bus [OUT ]) EmitSpiderOpened (ctx context.Context ) {
137- b .mu .RLock ()
138- handlers := b .spiderOpened
139- b .mu .RUnlock ()
140- for _ , h := range handlers {
141- h (ctx )
216+ if handlers := b .spiderOpened .Load (); handlers != nil {
217+ for _ , h := range * handlers {
218+ h (ctx )
219+ }
142220 }
143221}
144222
145223func (b * Bus [OUT ]) EmitSpiderClosed (ctx context.Context ) {
146- b .mu .RLock ()
147- handlers := b .spiderClosed
148- b .mu .RUnlock ()
149- for _ , h := range handlers {
150- h (ctx )
224+ if handlers := b .spiderClosed .Load (); handlers != nil {
225+ for _ , h := range * handlers {
226+ h (ctx )
227+ }
151228 }
152229}
153230
154231func (b * Bus [OUT ]) EmitSpiderError (ctx context.Context , err error ) {
155- b .mu .RLock ()
156- handlers := b .spiderError
157- b .mu .RUnlock ()
158- for _ , h := range handlers {
159- h (ctx , err )
232+ if handlers := b .spiderError .Load (); handlers != nil {
233+ for _ , h := range * handlers {
234+ h (ctx , err )
235+ }
160236 }
161237}
162238
163239func (b * Bus [OUT ]) EmitSpiderIdle (ctx context.Context ) {
164- b .mu .RLock ()
165- handlers := b .spiderIdle
166- b .mu .RUnlock ()
167- for _ , h := range handlers {
168- h (ctx )
240+ if handlers := b .spiderIdle .Load (); handlers != nil {
241+ for _ , h := range * handlers {
242+ h (ctx )
243+ }
169244 }
170245}
171246
172247func (b * Bus [OUT ]) EmitItemScraped (ctx context.Context , item OUT ) {
173- b .mu .RLock ()
174- handlers := b .itemScraped
175- b .mu .RUnlock ()
176- for _ , h := range handlers {
177- h (ctx , item )
248+ if handlers := b .itemScraped .Load (); handlers != nil {
249+ for _ , h := range * handlers {
250+ h (ctx , item )
251+ }
178252 }
179253}
180254
181255func (b * Bus [OUT ]) EmitItemDropped (ctx context.Context , item OUT , err error ) {
182- b .mu .RLock ()
183- handlers := b .itemDropped
184- b .mu .RUnlock ()
185- for _ , h := range handlers {
186- h (ctx , item , err )
256+ if handlers := b .itemDropped .Load (); handlers != nil {
257+ for _ , h := range * handlers {
258+ h (ctx , item , err )
259+ }
187260 }
188261}
189262
190263func (b * Bus [OUT ]) EmitItemError (ctx context.Context , item OUT , err error ) {
191- b .mu .RLock ()
192- handlers := b .itemError
193- b .mu .RUnlock ()
194- for _ , h := range handlers {
195- h (ctx , item , err )
264+ if handlers := b .itemError .Load (); handlers != nil {
265+ for _ , h := range * handlers {
266+ h (ctx , item , err )
267+ }
196268 }
197269}
198270
199271func (b * Bus [OUT ]) EmitRequestScheduled (ctx context.Context , req * core.Request ) {
200- b .mu .RLock ()
201- handlers := b .requestScheduled
202- b .mu .RUnlock ()
203- for _ , h := range handlers {
204- h (ctx , req )
272+ if handlers := b .requestScheduled .Load (); handlers != nil {
273+ for _ , h := range * handlers {
274+ h (ctx , req )
275+ }
205276 }
206277}
207278
208279func (b * Bus [OUT ]) EmitRequestDropped (ctx context.Context , req * core.Request , err error ) {
209- b .mu .RLock ()
210- handlers := b .requestDropped
211- b .mu .RUnlock ()
212- for _ , h := range handlers {
213- h (ctx , req , err )
280+ if handlers := b .requestDropped .Load (); handlers != nil {
281+ for _ , h := range * handlers {
282+ h (ctx , req , err )
283+ }
214284 }
215285}
216286
217287func (b * Bus [OUT ]) EmitRequestError (ctx context.Context , req * core.Request , err error ) {
218- b .mu .RLock ()
219- handlers := b .requestError
220- b .mu .RUnlock ()
221- for _ , h := range handlers {
222- h (ctx , req , err )
288+ if handlers := b .requestError .Load (); handlers != nil {
289+ for _ , h := range * handlers {
290+ h (ctx , req , err )
291+ }
223292 }
224293}
225294
226295func (b * Bus [OUT ]) EmitResponseReceived (ctx context.Context , resp core.IResponseReader ) {
227- b .mu .RLock ()
228- handlers := b .responseReceived
229- b .mu .RUnlock ()
230- for _ , h := range handlers {
231- h (ctx , resp )
296+ if handlers := b .responseReceived .Load (); handlers != nil {
297+ for _ , h := range * handlers {
298+ h (ctx , resp )
299+ }
232300 }
233301}
234302
235303func (b * Bus [OUT ]) EmitEngineStarted (ctx context.Context ) {
236- b .mu .RLock ()
237- handlers := b .engineStarted
238- b .mu .RUnlock ()
239- for _ , h := range handlers {
240- h (ctx )
304+ if handlers := b .engineStarted .Load (); handlers != nil {
305+ for _ , h := range * handlers {
306+ h (ctx )
307+ }
241308 }
242309}
243310
244311func (b * Bus [OUT ]) EmitEngineStopped (ctx context.Context ) {
245- b .mu .RLock ()
246- handlers := b .engineStopped
247- b .mu .RUnlock ()
248- for _ , h := range handlers {
249- h (ctx )
312+ if handlers := b .engineStopped .Load (); handlers != nil {
313+ for _ , h := range * handlers {
314+ h (ctx )
315+ }
250316 }
251317}
0 commit comments