MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / flushReplBacklogToClients

Function flushReplBacklogToClients

src/replication.cpp:5611–5688  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

5609void _clientAsyncReplyBufferReserve(client *c, size_t len);
5610
5611void flushReplBacklogToClients()
5612{
5613 serverAssert(GlobalLocksAcquired());
5614 /* If we have the repl backlog lock, we will deadlock */
5615 serverAssert(!g_pserver->repl_backlog_lock.fOwnLock());
5616 if (g_pserver->repl_batch_offStart < 0)
5617 return;
5618
5619 if (g_pserver->repl_batch_offStart != g_pserver->master_repl_offset) {
5620 bool fAsyncWrite = false;
5621 long long min_offset = LLONG_MAX;
5622 // Ensure no overflow
5623 serverAssert(g_pserver->repl_batch_offStart < g_pserver->master_repl_offset);
5624 if (g_pserver->master_repl_offset - g_pserver->repl_batch_offStart > g_pserver->repl_backlog_size) {
5625 // We overflowed
5626 listIter li;
5627 listNode *ln;
5628 listRewind(g_pserver->slaves, &li);
5629 while ((ln = listNext(&li))) {
5630 client *c = (client*)listNodeValue(ln);
5631 sds sdsClient = catClientInfoString(sdsempty(),c);
5632 freeClientAsync(c);
5633 serverLog(LL_WARNING,"Client %s scheduled to be closed ASAP for overcoming of output buffer limits.", sdsClient);
5634 sdsfree(sdsClient);
5635 }
5636 goto LDone;
5637 }
5638
5639 // Ensure no overflow if we get here
5640 serverAssert(g_pserver->master_repl_offset - g_pserver->repl_batch_offStart <= g_pserver->repl_backlog_size);
5641 serverAssert(g_pserver->repl_batch_idxStart != g_pserver->repl_backlog_idx);
5642
5643 // Repl backlog writes must become visible to all threads at this point
5644 std::atomic_thread_fence(std::memory_order_release);
5645
5646 listIter li;
5647 listNode *ln;
5648 listRewind(g_pserver->slaves, &li);
5649 /* We don't actually write any data in this function since we send data
5650 * directly from the replication backlog to replicas in writeToClient.
5651 *
5652 * What we do however, is set the end offset of each replica here. This way,
5653 * future calls to writeToClient will know up to where in the replication
5654 * backlog is valid for writing. */
5655 while ((ln = listNext(&li))) {
5656 client *replica = (client*)listNodeValue(ln);
5657
5658 if (!canFeedReplicaReplBuffer(replica)) continue;
5659 if (replica->flags & CLIENT_CLOSE_ASAP) continue;
5660
5661 std::unique_lock<fastlock> ul(replica->lock);
5662 if (!FCorrectThread(replica))
5663 fAsyncWrite = true;
5664
5665 /* We should have set the repl_curr_off when synchronizing, so it shouldn't be -1 here */
5666 serverAssert(replica->repl_curr_off != -1);
5667
5668 min_offset = std::min(min_offset, replica->repl_curr_off);

Callers 6

callFunction · 0.85
processCommandFunction · 0.85
prepareForShutdownFunction · 0.85
executeWithoutGlobalLockFunction · 0.85
flushSlavesOutputBuffersFunction · 0.85

Calls 13

GlobalLocksAcquiredFunction · 0.85
listRewindFunction · 0.85
listNextFunction · 0.85
catClientInfoStringFunction · 0.85
sdsemptyFunction · 0.85
freeClientAsyncFunction · 0.85
serverLogFunction · 0.85
sdsfreeFunction · 0.85
canFeedReplicaReplBufferFunction · 0.85
FCorrectThreadFunction · 0.85
prepareClientToWriteFunction · 0.85

Tested by

no test coverage detected