MCPcopy Create free account
hub / github.com/F-Stack/f-stack / clientsCron

Function clientsCron

app/redis-6.2.6/src/server.c:1801–1854  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1799 */
1800#define CLIENTS_CRON_MIN_ITERATIONS 5
1801void clientsCron(void) {
1802 /* Try to process at least numclients/server.hz of clients
1803 * per call. Since normally (if there are no big latency events) this
1804 * function is called server.hz times per second, in the average case we
1805 * process all the clients in 1 second. */
1806 int numclients = listLength(server.clients);
1807 int iterations = numclients/server.hz;
1808 mstime_t now = mstime();
1809
1810 /* Process at least a few clients while we are at it, even if we need
1811 * to process less than CLIENTS_CRON_MIN_ITERATIONS to meet our contract
1812 * of processing each client once per second. */
1813 if (iterations < CLIENTS_CRON_MIN_ITERATIONS)
1814 iterations = (numclients < CLIENTS_CRON_MIN_ITERATIONS) ?
1815 numclients : CLIENTS_CRON_MIN_ITERATIONS;
1816
1817
1818 int curr_peak_mem_usage_slot = server.unixtime % CLIENTS_PEAK_MEM_USAGE_SLOTS;
1819 /* Always zero the next sample, so that when we switch to that second, we'll
1820 * only register samples that are greater in that second without considering
1821 * the history of such slot.
1822 *
1823 * Note: our index may jump to any random position if serverCron() is not
1824 * called for some reason with the normal frequency, for instance because
1825 * some slow command is called taking multiple seconds to execute. In that
1826 * case our array may end containing data which is potentially older
1827 * than CLIENTS_PEAK_MEM_USAGE_SLOTS seconds: however this is not a problem
1828 * since here we want just to track if "recently" there were very expansive
1829 * clients from the POV of memory usage. */
1830 int zeroidx = (curr_peak_mem_usage_slot+1) % CLIENTS_PEAK_MEM_USAGE_SLOTS;
1831 ClientsPeakMemInput[zeroidx] = 0;
1832 ClientsPeakMemOutput[zeroidx] = 0;
1833
1834
1835 while(listLength(server.clients) && iterations--) {
1836 client *c;
1837 listNode *head;
1838
1839 /* Rotate the list, take the current head, process.
1840 * This way if the client must be removed from the list it's the
1841 * first element and we don't incur into O(N) computation. */
1842 listRotateTailToHead(server.clients);
1843 head = listFirst(server.clients);
1844 c = listNodeValue(head);
1845 /* The following functions do different service checks on the client.
1846 * The protocol is that they return non-zero if the client was
1847 * terminated. */
1848 if (clientsCronHandleTimeout(c,now)) continue;
1849 if (clientsCronResizeQueryBuffer(c)) continue;
1850 if (clientsCronTrackExpansiveClients(c, curr_peak_mem_usage_slot)) continue;
1851 if (clientsCronTrackClientsMemUsage(c)) continue;
1852 if (closeClientOnOutputBufferLimitReached(c, 0)) continue;
1853 }
1854}
1855
1856/* This function handles 'background' operations we are required to do
1857 * incrementally in Redis databases, such as active key expiring, resizing,

Callers 1

serverCronFunction · 0.85

Calls 7

listRotateTailToHeadFunction · 0.85
clientsCronHandleTimeoutFunction · 0.85
mstimeFunction · 0.70

Tested by

no test coverage detected