Skip to content

Commit 89024a0

Browse files
derrickstoleegitster
authored andcommitted
maintenance: add get_random_minute()
When we initially created background maintenance -- with its hourly, daily, and weekly schedules -- we considered the effects of all clients launching fetches to the server every hour on the hour. The worry of DDoSing server hosts was noted, but left as something we would consider for a future update. As background maintenance has gained more adoption over the past three years, our worries about DDoSing the big Git hosts has been unfounded. Those systems, especially those serving public repositories, are already resilient to thundering herds of much smaller scale. However, sometimes organizations spin up specific custom server infrastructure either in addition to or on top of their Git host. Some of these technologies are built for a different range of scale, and can hit concurrency limits sooner. Organizations with such custom infrastructures are more likely to recommend tools like `scalar` which furthers their adoption of background maintenance. To help solve for this, create get_random_minute() as a method to help Git select a random minute when creating schedules in the future. The integrations with this method do not yet exist, but will follow in future changes. To avoid multiple sources of randomness in the Git codebase, create a new helper function, git_rand(), that returns a random uint32_t. This is similar to how rand() returns a random nonnegative value, except it is based on csprng_bytes() which is cryptographic and will return values larger than RAND_MAX. One thing that is important for testability is that we notice when we are under a test scenario and return a predictable result. The schedules themselves are not checked for this value, but at least one launchctl test checks that we do not unnecessarily reboot the schedule if it has not changed from a previous version. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a82fb66 commit 89024a0

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

builtin/gc.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,6 +1708,16 @@ static int get_schedule_cmd(const char **cmd, int *is_available)
17081708
return 1;
17091709
}
17101710

1711+
MAYBE_UNUSED
1712+
static int get_random_minute(void)
1713+
{
1714+
/* Use a static value when under tests. */
1715+
if (getenv("GIT_TEST_MAINT_SCHEDULER"))
1716+
return 13;
1717+
1718+
return git_rand() % 60;
1719+
}
1720+
17111721
static int is_launchctl_available(void)
17121722
{
17131723
const char *cmd = "launchctl";

wrapper.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,3 +819,13 @@ int csprng_bytes(void *buf, size_t len)
819819
return 0;
820820
#endif
821821
}
822+
823+
uint32_t git_rand(void)
824+
{
825+
uint32_t result;
826+
827+
if (csprng_bytes(&result, sizeof(result)) < 0)
828+
die(_("unable to get random bytes"));
829+
830+
return result;
831+
}

wrapper.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,10 @@ void sleep_millisec(int millisec);
139139
*/
140140
int csprng_bytes(void *buf, size_t len);
141141

142+
/*
143+
* Returns a random uint32_t, uniformly distributed across all possible
144+
* values.
145+
*/
146+
uint32_t git_rand(void);
147+
142148
#endif /* WRAPPER_H */

0 commit comments

Comments
 (0)