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

Function clusterSendPing

src/cluster.cpp:2594–2720  ·  view source on GitHub ↗

Send a PING or PONG packet to the specified node, making sure to add enough * gossip information. */

Source from the content-addressed store, hash-verified

2592/* Send a PING or PONG packet to the specified node, making sure to add enough
2593 * gossip information. */
2594void clusterSendPing(clusterLink *link, int type) {
2595 unsigned char *buf;
2596 clusterMsg *hdr;
2597 int gossipcount = 0; /* Number of gossip sections added so far. */
2598 int wanted; /* Number of gossip sections we want to append if possible. */
2599 int totlen; /* Total packet length. */
2600 /* freshnodes is the max number of nodes we can hope to append at all:
2601 * nodes available minus two (ourself and the node we are sending the
2602 * message to). However practically there may be less valid nodes since
2603 * nodes in handshake state, disconnected, are not considered. */
2604 int freshnodes = dictSize(g_pserver->cluster->nodes)-2;
2605
2606 /* How many gossip sections we want to add? 1/10 of the number of nodes
2607 * and anyway at least 3. Why 1/10?
2608 *
2609 * If we have N masters, with N/10 entries, and we consider that in
2610 * node_timeout we exchange with each other node at least 4 packets
2611 * (we ping in the worst case in node_timeout/2 time, and we also
2612 * receive two pings from the host), we have a total of 8 packets
2613 * in the node_timeout*2 failure reports validity time. So we have
2614 * that, for a single PFAIL node, we can expect to receive the following
2615 * number of failure reports (in the specified window of time):
2616 *
2617 * PROB * GOSSIP_ENTRIES_PER_PACKET * TOTAL_PACKETS:
2618 *
2619 * PROB = probability of being featured in a single gossip entry,
2620 * which is 1 / NUM_OF_NODES.
2621 * ENTRIES = 10.
2622 * TOTAL_PACKETS = 2 * 4 * NUM_OF_MASTERS.
2623 *
2624 * If we assume we have just masters (so num of nodes and num of masters
2625 * is the same), with 1/10 we always get over the majority, and specifically
2626 * 80% of the number of nodes, to account for many masters failing at the
2627 * same time.
2628 *
2629 * Since we have non-voting slaves that lower the probability of an entry
2630 * to feature our node, we set the number of entries per packet as
2631 * 10% of the total nodes we have. */
2632 wanted = floor(dictSize(g_pserver->cluster->nodes)/10);
2633 if (wanted < 3) wanted = 3;
2634 if (wanted > freshnodes) wanted = freshnodes;
2635
2636 /* Include all the nodes in PFAIL state, so that failure reports are
2637 * faster to propagate to go from PFAIL to FAIL state. */
2638 int pfail_wanted = g_pserver->cluster->stats_pfail_nodes;
2639
2640 /* Compute the maximum totlen to allocate our buffer. We'll fix the totlen
2641 * later according to the number of gossip sections we really were able
2642 * to put inside the packet. */
2643 totlen = sizeof(clusterMsg)-sizeof(union clusterMsgData);
2644 totlen += (sizeof(clusterMsgDataGossip)*(wanted+pfail_wanted));
2645 /* Note: clusterBuildMessageHdr() expects the buffer to be always at least
2646 * sizeof(clusterMsg) or more. */
2647 if (totlen < (int)sizeof(clusterMsg)) totlen = sizeof(clusterMsg);
2648 buf = (unsigned char*)zcalloc(totlen, MALLOC_LOCAL);
2649 hdr = (clusterMsg*) buf;
2650
2651 /* Populate the header. */

Callers 4

clusterProcessPacketFunction · 0.85
clusterBroadcastPongFunction · 0.85
clusterCronFunction · 0.85

Calls 11

zcallocFunction · 0.85
clusterBuildMessageHdrFunction · 0.85
dictGetRandomKeyFunction · 0.85
clusterSetGossipEntryFunction · 0.85
dictGetSafeIteratorFunction · 0.85
clusterSendMessageFunction · 0.85
zfreeFunction · 0.85
mstimeFunction · 0.70
dictNextFunction · 0.70
dictReleaseIteratorFunction · 0.70

Tested by

no test coverage detected