(e endStreamEvent)
| 581 | } |
| 582 | |
| 583 | func (dc *DCPClient) onStreamEnd(e endStreamEvent) { |
| 584 | if e.err == nil { |
| 585 | DebugfCtx(dc.ctx, KeyDCP, "Stream (vb:%d) closed, all items streamed", e.vbID) |
| 586 | dc.deactivateVbucket(e.vbID) |
| 587 | return |
| 588 | } |
| 589 | |
| 590 | if errors.Is(e.err, gocbcore.ErrDCPStreamClosed) { |
| 591 | DebugfCtx(dc.ctx, KeyDCP, "Stream (vb:%d) closed by DCPClient", e.vbID) |
| 592 | dc.fatalError(fmt.Errorf("Stream (vb:%d) closed by DCPClient", e.vbID)) |
| 593 | return |
| 594 | } |
| 595 | |
| 596 | if errors.Is(e.err, gocbcore.ErrDCPStreamStateChanged) || errors.Is(e.err, gocbcore.ErrDCPStreamTooSlow) || errors.Is(e.err, gocbcore.ErrDCPStreamDisconnected) { |
| 597 | DebugfCtx(dc.ctx, KeyDCP, "Stream (vb:%d) ended with a known error, will reconnect. Reason: %s", e.vbID, e.err) |
| 598 | } else { |
| 599 | InfofCtx(dc.ctx, KeyDCP, "Stream (vb:%d) ended with an unknown error, will reconnect. Reason: %s", e.vbID, e.err) |
| 600 | } |
| 601 | retries := infiniteOpenStreamRetries |
| 602 | if dc.oneShot { |
| 603 | retries = openRetryCount |
| 604 | } |
| 605 | |
| 606 | // Re-opening the stream needs to be asynchronous, due to the way the DCPAgent performs locking while |
| 607 | // reconfiguring memdclients - the old client can't be closed while it has pending StreamObserver.End calls, |
| 608 | // and our openStream request won't succeed until the old client is closed. |
| 609 | // Since we've got a relatively small event buffer for processing observer events (10 x 8 workers), a |
| 610 | // synchronous openStream request will create a deadlock whenever more than 80 vbuckets need to be closed. |
| 611 | go func(vb uint16, maxRetries uint32) { |
| 612 | err := dc.openStream(vb, maxRetries) |
| 613 | if err != nil { |
| 614 | dc.fatalError(fmt.Errorf("Stream (vb:%d) failed to reopen: %w", vb, err)) |
| 615 | } |
| 616 | }(e.vbID, retries) |
| 617 | } |
| 618 | |
| 619 | func (dc *DCPClient) fatalError(err error) { |
| 620 | dc.setCloseError(err) |
nothing calls this directly
no test coverage detected