@@ -62,6 +62,18 @@ type notifyMsg struct {
6262 latestCommitTs uint64
6363}
6464
65+ func collectWrapEventTypes (ch chan * wrapEvent ) []int {
66+ eventTypes := make ([]int , 0 )
67+ for {
68+ select {
69+ case e := <- ch :
70+ eventTypes = append (eventTypes , e .msgType )
71+ default :
72+ return eventTypes
73+ }
74+ }
75+ }
76+
6577func TestCheckNeedScan (t * testing.T ) {
6678 broker , _ , _ , _ := newEventBrokerForTest ()
6779 // Close the broker, so we can catch all message in the test.
@@ -119,6 +131,64 @@ func TestGetOrSetChangefeedStatusInitializesFilter(t *testing.T) {
119131 require .Same (t , status .filter , reused .filter )
120132}
121133
134+ func TestAddDispatcherSendsReadyImmediatelyAfterRegistration (t * testing.T ) {
135+ broker , _ , _ , _ := newEventBrokerForTest ()
136+ broker .close ()
137+
138+ info := newMockDispatcherInfoForTest (t )
139+ err := broker .addDispatcher (info )
140+ require .NoError (t , err )
141+
142+ dispPtr := broker .getDispatcher (info .GetID ())
143+ require .NotNil (t , dispPtr )
144+ disp := dispPtr .Load ()
145+ require .NotNil (t , disp )
146+
147+ eventTypes := collectWrapEventTypes (broker .messageCh [disp .messageWorkerIndex ])
148+ require .Equal (t , []int {event .TypeReadyEvent }, eventTypes )
149+ }
150+
151+ func TestResetDispatcherSendsHandshakeImmediatelyAfterEpochSwitch (t * testing.T ) {
152+ broker , _ , _ , _ := newEventBrokerForTest ()
153+ broker .close ()
154+
155+ info := newMockDispatcherInfoForTest (t )
156+ err := broker .addDispatcher (info )
157+ require .NoError (t , err )
158+
159+ disp := broker .getDispatcher (info .GetID ()).Load ()
160+ require .NotNil (t , disp )
161+ collectWrapEventTypes (broker .messageCh [disp .messageWorkerIndex ])
162+
163+ resetInfo := newMockDispatcherInfo (t , 500 , info .GetID (), info .GetTableSpan ().GetTableID (), eventpb .ActionType_ACTION_TYPE_RESET )
164+ resetInfo .epoch = 1
165+ err = broker .resetDispatcher (resetInfo )
166+ require .NoError (t , err )
167+
168+ newDisp := broker .getDispatcher (info .GetID ()).Load ()
169+ require .NotNil (t , newDisp )
170+ require .Equal (t , uint64 (1 ), newDisp .epoch )
171+
172+ eventTypes := collectWrapEventTypes (broker .messageCh [newDisp .messageWorkerIndex ])
173+ require .Equal (t , []int {event .TypeHandshakeEvent }, eventTypes )
174+ }
175+
176+ func TestAddTableTriggerDispatcherDoesNotSendReadyImmediately (t * testing.T ) {
177+ broker , _ , _ , _ := newEventBrokerForTest ()
178+ broker .close ()
179+
180+ info := newMockDispatcherInfo (t , 300 , common .NewDispatcherID (), 0 , eventpb .ActionType_ACTION_TYPE_REGISTER )
181+ info .span = common .KeyspaceDDLSpan (testTableTriggerKeyspaceID )
182+ err := broker .addDispatcher (info )
183+ require .NoError (t , err )
184+
185+ disp := broker .getDispatcher (info .GetID ()).Load ()
186+ require .NotNil (t , disp )
187+
188+ eventTypes := collectWrapEventTypes (broker .messageCh [disp .messageWorkerIndex ])
189+ require .Empty (t , eventTypes )
190+ }
191+
122192func TestOnNotify (t * testing.T ) {
123193 broker , _ , ss , _ := newEventBrokerForTest ()
124194 // Close the broker, so we can catch all message in the test.
@@ -704,19 +774,25 @@ func TestHandleDispatcherHeartbeat_InactiveDispatcherCleanup(t *testing.T) {
704774 ctx , cancel = context .WithTimeout (context .Background (), 5 * time .Second )
705775 defer cancel ()
706776 // Verify that a response was sent indicating the dispatcher is removed
707- select {
708- case msg := <- outputCh :
709- require .Equal (t , messaging .TypeDispatcherHeartbeatResponse , msg .Type )
710- // The response should contain a dispatcher state indicating removal
711- require .Len (t , msg .Message , 1 )
712- response := msg .Message [0 ].(* event.DispatcherHeartbeatResponse )
713- require .NotNil (t , response )
714- states := response .DispatcherStates
715- require .Len (t , states , 1 )
716- require .Equal (t , dispInfo .GetID (), states [0 ].DispatcherID )
717- require .Equal (t , event .DSStateRemoved , states [0 ].State )
718- case <- ctx .Done ():
719- require .Fail (t , "Expected to receive a dispatcher heartbeat response" )
777+ for {
778+ select {
779+ case msg := <- outputCh :
780+ if msg .Type != messaging .TypeDispatcherHeartbeatResponse {
781+ continue
782+ }
783+ // Ignore earlier ready/handshake traffic and verify the heartbeat response itself.
784+ require .Len (t , msg .Message , 1 )
785+ response := msg .Message [0 ].(* event.DispatcherHeartbeatResponse )
786+ require .NotNil (t , response )
787+ states := response .DispatcherStates
788+ require .Len (t , states , 1 )
789+ require .Equal (t , dispInfo .GetID (), states [0 ].DispatcherID )
790+ require .Equal (t , event .DSStateRemoved , states [0 ].State )
791+ return
792+ case <- ctx .Done ():
793+ require .Fail (t , "Expected to receive a dispatcher heartbeat response" )
794+ return
795+ }
720796 }
721797}
722798
@@ -939,7 +1015,7 @@ func TestSendHandshakeUsesStartTs(t *testing.T) {
9391015
9401016func TestAddDispatcherFailure (t * testing.T ) {
9411017 broker , _ , ss , _ := newEventBrokerForTest ()
942- defer broker .close ()
1018+ broker .close ()
9431019
9441020 // Simulate schema store failure
9451021 ss .registerTableError = errors .New ("mock error" )
@@ -950,4 +1026,8 @@ func TestAddDispatcherFailure(t *testing.T) {
9501026
9511027 _ , ok := broker .changefeedMap .Load (dispInfo .GetChangefeedID ())
9521028 require .False (t , ok , "changefeedStatus should be removed after failed registration" )
1029+ require .Nil (t , broker .getDispatcher (dispInfo .GetID ()))
1030+ for _ , ch := range broker .messageCh {
1031+ require .Empty (t , collectWrapEventTypes (ch ))
1032+ }
9531033}
0 commit comments