@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at recaptime-dev/main 92 lines 2.5 kB view raw
1<?php 2 3/** 4 * Tick at a given frequency with a specifiable offset. 5 * 6 * One use case for this is to flatten out load spikes caused by periodic 7 * service calls. Give each host a metronome that ticks at the same frequency, 8 * but with different offsets. Then, have hosts make service calls only after 9 * their metronome ticks. This spreads service calls out evenly more quickly 10 * and more predictably than adding random jitter. 11 */ 12final class PhabricatorMetronome 13 extends Phobject { 14 15 private $offset = 0; 16 private $frequency; 17 18 public function setOffset($offset) { 19 if (!is_int($offset)) { 20 throw new Exception(pht('Metronome offset must be an integer.')); 21 } 22 23 if ($offset < 0) { 24 throw new Exception(pht('Metronome offset must be 0 or more.')); 25 } 26 27 // We're not requiring that the offset be smaller than the frequency. If 28 // the offset is larger, we'll just clamp it to the frequency before we 29 // use it. This allows the offset to be configured before the frequency 30 // is configured, which is useful for using a hostname as an offset seed. 31 32 $this->offset = $offset; 33 34 return $this; 35 } 36 37 public function setFrequency($frequency) { 38 if (!is_int($frequency)) { 39 throw new Exception(pht('Metronome frequency must be an integer.')); 40 } 41 42 if ($frequency < 1) { 43 throw new Exception(pht('Metronome frequency must be 1 or more.')); 44 } 45 46 $this->frequency = $frequency; 47 48 return $this; 49 } 50 51 public function setOffsetFromSeed($seed) { 52 $offset = PhabricatorHash::digestToRange($seed, 0, 0x7FFFFFFF); 53 return $this->setOffset($offset); 54 } 55 56 public function getFrequency() { 57 if ($this->frequency === null) { 58 throw new PhutilInvalidStateException('setFrequency'); 59 } 60 return $this->frequency; 61 } 62 63 public function getOffset() { 64 $frequency = $this->getFrequency(); 65 return ($this->offset % $frequency); 66 } 67 68 public function getNextTickAfter($epoch) { 69 $frequency = $this->getFrequency(); 70 $offset = $this->getOffset(); 71 72 $remainder = ($epoch % $frequency); 73 74 if ($remainder < $offset) { 75 return ($epoch - $remainder) + $offset; 76 } else { 77 return ($epoch - $remainder) + $frequency + $offset; 78 } 79 } 80 81 public function didTickBetween($min, $max) { 82 if ($max < $min) { 83 throw new Exception( 84 pht( 85 'Maximum tick window must not be smaller than minimum tick window.')); 86 } 87 88 $next = $this->getNextTickAfter($min); 89 return ($next <= $max); 90 } 91 92}