@@ -34,10 +34,8 @@ type Client struct {
3434 readyForNextBlockChan chan bool
3535 onceStart sync.Once
3636 onceStop sync.Once
37+ started atomic.Bool
3738 syncPipelinedRequestNext int
38-
39- // waitingForCurrentTipChan will process all the requests for the current tip until the channel
40- // is empty.
4139 //
4240 // want* only processes one request per message reply received from the server. If the message
4341 // request fails, it is the responsibility of the caller to clear the channel.
@@ -126,12 +124,8 @@ func (c *Client) Start() {
126124 "protocol" , ProtocolName ,
127125 "connection_id" , c .callbackContext .ConnectionId .String (),
128126 )
127+ c .started .Store (true )
129128 c .Protocol .Start ()
130- // Start goroutine to cleanup resources on protocol shutdown
131- go func () {
132- <- c .DoneChan ()
133- close (c .readyForNextBlockChan )
134- }()
135129 })
136130}
137131
@@ -151,6 +145,16 @@ func (c *Client) Stop() error {
151145 if err = c .SendMessage (msg ); err != nil {
152146 return
153147 }
148+ // Defer closing channel until protocol fully shuts down (only if started)
149+ if c .started .Load () {
150+ go func () {
151+ <- c .DoneChan ()
152+ close (c .readyForNextBlockChan )
153+ }()
154+ } else {
155+ // If protocol was never started, close channel immediately
156+ close (c .readyForNextBlockChan )
157+ }
154158 })
155159 return err
156160}
@@ -334,7 +338,15 @@ func (c *Client) GetAvailableBlockRange(
334338 )
335339 }
336340 start = firstBlock .point
337- case <- c .readyForNextBlockChan :
341+ case ready , ok := <- c .readyForNextBlockChan :
342+ if ! ok {
343+ // Channel closed, protocol shutting down
344+ return start , end , protocol .ErrProtocolShuttingDown
345+ }
346+ // Only proceed if ready is true
347+ if ! ready {
348+ return start , end , ErrSyncCancelled
349+ }
338350 // Request the next block
339351 msg := NewMsgRequestNext ()
340352 if err := c .SendMessage (msg ); err != nil {
@@ -721,14 +733,22 @@ func (c *Client) handleRollForward(msgGeneric protocol.Message) error {
721733 if callbackErr != nil {
722734 if errors .Is (callbackErr , ErrStopSyncProcess ) {
723735 // Signal that we're cancelling the sync
724- c .readyForNextBlockChan <- false
736+ select {
737+ case <- c .DoneChan ():
738+ return protocol .ErrProtocolShuttingDown
739+ case c .readyForNextBlockChan <- false :
740+ }
725741 return nil
726742 } else {
727743 return callbackErr
728744 }
729745 }
730746 // Signal that we're ready for the next block
731- c .readyForNextBlockChan <- true
747+ select {
748+ case <- c .DoneChan ():
749+ return protocol .ErrProtocolShuttingDown
750+ case c .readyForNextBlockChan <- true :
751+ }
732752 return nil
733753}
734754
@@ -752,15 +772,23 @@ func (c *Client) handleRollBackward(msgGeneric protocol.Message) error {
752772 if callbackErr := c .config .RollBackwardFunc (c .callbackContext , msgRollBackward .Point , msgRollBackward .Tip ); callbackErr != nil {
753773 if errors .Is (callbackErr , ErrStopSyncProcess ) {
754774 // Signal that we're cancelling the sync
755- c .readyForNextBlockChan <- false
775+ select {
776+ case <- c .DoneChan ():
777+ return protocol .ErrProtocolShuttingDown
778+ case c .readyForNextBlockChan <- false :
779+ }
756780 return nil
757781 } else {
758782 return callbackErr
759783 }
760784 }
761785 }
762786 // Signal that we're ready for the next block
763- c .readyForNextBlockChan <- true
787+ select {
788+ case <- c .DoneChan ():
789+ return protocol .ErrProtocolShuttingDown
790+ case c .readyForNextBlockChan <- true :
791+ }
764792 return nil
765793}
766794
0 commit comments