@@ -48,21 +48,32 @@ func (m *Meta) unsubscribeFromBlocks() {
48
48
m .l .Debug ("successfully unsubscribed from blocks" )
49
49
}
50
50
51
- func (m * Meta ) subscribeForMeta () error {
52
- cnrDeleteEv := cnrDeleteName
53
- _ , err := m .ws .ReceiveExecutionNotifications (& neorpc.NotificationFilter {Contract : & m .cnrH , Name : & cnrDeleteEv }, m .cnrDelEv )
54
- if err != nil {
55
- return fmt .Errorf ("subscribe for container removal notifications: %w" , err )
56
- }
51
+ // subscribeForNewContainers requires [Meta.cliM] to be taken.
52
+ func (m * Meta ) subscribeForNewContainers (ch chan <- * state.ContainedNotificationEvent ) (string , error ) {
53
+ m .l .Debug ("subscribing for containers" )
57
54
58
55
cnrPutEv := cnrPutName
59
- _ , err = m .ws .ReceiveExecutionNotifications (& neorpc.NotificationFilter {Contract : & m .cnrH , Name : & cnrPutEv }, m .cnrPutEv )
56
+ return m .ws .ReceiveExecutionNotifications (& neorpc.NotificationFilter {Contract : & m .cnrH , Name : & cnrPutEv }, ch )
57
+ }
58
+
59
+ // unsubscribeFromNewContainers requires [Meta.cliM] to be taken.
60
+ func (m * Meta ) unsubscribeFromNewContainers () {
61
+ m .l .Debug ("unsubscribing from containers" )
62
+
63
+ err := m .ws .Unsubscribe (m .cnrSubID )
60
64
if err != nil {
61
- return fmt .Errorf ("subscribe for container addition notifications: %w" , err )
65
+ m .l .Error ("could not unsubscribe from containers" , zap .Error (err ))
66
+ return
62
67
}
63
68
69
+ m .cnrSubID = ""
70
+
71
+ m .l .Debug ("successfully unsubscribed from containers" )
72
+ }
73
+
74
+ func (m * Meta ) subscribeEvents () error {
64
75
epochEv := newEpochName
65
- _ , err = m .ws .ReceiveExecutionNotifications (& neorpc.NotificationFilter {Contract : & m .netmapH , Name : & epochEv }, m .epochEv )
76
+ _ , err : = m .ws .ReceiveExecutionNotifications (& neorpc.NotificationFilter {Contract : & m .netmapH , Name : & epochEv }, m .epochEv )
66
77
if err != nil {
67
78
return fmt .Errorf ("subscribe for epoch notifications: %w" , err )
68
79
}
@@ -84,7 +95,7 @@ func (m *Meta) listenNotifications(ctx context.Context) error {
84
95
}
85
96
86
97
m .blockBuff <- h
87
- case aer , ok := <- m .cnrDelEv :
98
+ case aer , ok := <- m .cnrPutEv :
88
99
if ! ok {
89
100
err := m .reconnect (ctx )
90
101
if err != nil {
@@ -94,44 +105,17 @@ func (m *Meta) listenNotifications(ctx context.Context) error {
94
105
continue
95
106
}
96
107
97
- l := m .l .With (zap .Stringer ("notification container" , aer .Container ))
98
-
99
- ev , err := parseCnrNotification (aer )
100
- if err != nil {
101
- l .Error ("invalid container notification received" , zap .Error (err ))
102
- continue
103
- }
104
-
105
- m .stM .RLock ()
106
- _ , ok = m .storages [ev .cID ]
107
- m .stM .RUnlock ()
108
- if ! ok {
109
- l .Debug ("skipping container notification" , zap .Stringer ("inactual container" , ev .cID ))
110
- continue
111
- }
112
-
113
- go func () {
114
- err = m .dropContainer (ev .cID )
115
- if err != nil {
116
- l .Error ("deleting container failed" , zap .Error (err ))
117
- return
118
- }
119
-
120
- l .Debug ("deleted container" , zap .Stringer ("cID" , ev .cID ))
121
- }()
122
- case aer , ok := <- m .cnrPutEv :
123
- if ! ok {
124
- err := m .reconnect (ctx )
125
- if err != nil {
126
- return err
127
- }
128
-
108
+ m .cliM .RLock ()
109
+ alreadyListenToContainers := m .blockSubID != ""
110
+ m .cliM .RUnlock ()
111
+ if alreadyListenToContainers {
112
+ // container will be handled
129
113
continue
130
114
}
131
115
132
116
l := m .l .With (zap .Stringer ("notification container" , aer .Container ))
133
117
134
- ev , err := parseCnrNotification (aer )
118
+ ev , err := parseCnrNotification (* aer )
135
119
if err != nil {
136
120
l .Error ("invalid container notification received" , zap .Error (err ))
137
121
continue
@@ -204,14 +188,19 @@ func (m *Meta) reconnect(ctx context.Context) error {
204
188
m .stM .RUnlock ()
205
189
return fmt .Errorf ("subscription for blocks: %w" , err )
206
190
}
191
+ } else {
192
+ m .cnrPutEv = make (chan * state.ContainedNotificationEvent , notificationBuffSize )
193
+ m .cnrSubID , err = m .subscribeForNewContainers (m .cnrPutEv )
194
+ if err != nil {
195
+ m .stM .RUnlock ()
196
+ return fmt .Errorf ("subscription for containers: %w" , err )
197
+ }
207
198
}
208
199
m .stM .RUnlock ()
209
200
210
- m .cnrDelEv = make (chan * state.ContainedNotificationEvent , notificationBuffSize )
211
- m .cnrPutEv = make (chan * state.ContainedNotificationEvent , notificationBuffSize )
212
201
m .epochEv = make (chan * state.ContainedNotificationEvent , notificationBuffSize )
213
202
214
- err = m .subscribeForMeta ()
203
+ err = m .subscribeEvents ()
215
204
if err != nil {
216
205
return fmt .Errorf ("subscribe for meta notifications: %w" , err )
217
206
}
@@ -430,7 +419,7 @@ type cnrEvent struct {
430
419
cID cid.ID
431
420
}
432
421
433
- func parseCnrNotification (ev * state.ContainedNotificationEvent ) (cnrEvent , error ) {
422
+ func parseCnrNotification (ev state.ContainedNotificationEvent ) (cnrEvent , error ) {
434
423
var res cnrEvent
435
424
436
425
arr , ok := ev .Item .Value ().([]stackitem.Item )
@@ -481,7 +470,11 @@ func (m *Meta) dropContainer(cID cid.ID) error {
481
470
if len (m .storages ) == 0 {
482
471
m .cliM .Lock ()
483
472
m .unsubscribeFromBlocks ()
473
+ m .cnrSubID , err = m .subscribeForNewContainers (m .cnrPutEv )
484
474
m .cliM .Unlock ()
475
+ if err != nil {
476
+ return fmt .Errorf ("subscribing for new containers: %w" , err )
477
+ }
485
478
}
486
479
487
480
return nil
@@ -500,6 +493,7 @@ func (m *Meta) addContainer(cID cid.ID) error {
500
493
m .cliM .Unlock ()
501
494
return fmt .Errorf ("blocks subscription: %w" , err )
502
495
}
496
+ m .unsubscribeFromNewContainers ()
503
497
504
498
m .cliM .Unlock ()
505
499
}
@@ -573,14 +567,29 @@ func (m *Meta) handleEpochNotification(e uint64) error {
573
567
m .stM .Unlock ()
574
568
575
569
m .cliM .Lock ()
576
- if len (m .storages ) > 0 && m .blockSubID == "" {
577
- m .blockSubID , err = m .subscribeForBlocks (m .bCh )
578
- if err != nil {
579
- m .cliM .Unlock ()
580
- return fmt .Errorf ("blocks subscription: %w" , err )
570
+ if len (m .storages ) > 0 {
571
+ if m .blockSubID == "" {
572
+ m .blockSubID , err = m .subscribeForBlocks (m .bCh )
573
+ if err != nil {
574
+ m .cliM .Unlock ()
575
+ return fmt .Errorf ("blocks subscription: %w" , err )
576
+ }
577
+ }
578
+ if m .cnrSubID != "" {
579
+ m .unsubscribeFromBlocks ()
580
+ }
581
+ } else {
582
+ if m .blockSubID != "" {
583
+ m .unsubscribeFromBlocks ()
584
+ }
585
+
586
+ if m .cnrSubID == "" {
587
+ m .cnrSubID , err = m .subscribeForNewContainers (m .cnrPutEv )
588
+ if err != nil {
589
+ m .cliM .Unlock ()
590
+ return fmt .Errorf ("containers subscription: %w" , err )
591
+ }
581
592
}
582
- } else if len (m .storages ) == 0 && m .blockSubID != "" {
583
- m .unsubscribeFromBlocks ()
584
593
}
585
594
m .cliM .Unlock ()
586
595
0 commit comments