Skip to content

clock

django_spire.contrib.sync.core.clock

message = '_COUNTER_BITS must be in [1, 62], got {_COUNTER_BITS}' module-attribute

HybridLogicalClock

Source code in django_spire/contrib/sync/core/clock.py
def __init__(self) -> None:
    self._last = 0
    self._lock = threading.Lock()

now

Source code in django_spire/contrib/sync/core/clock.py
def now(self) -> int:
    for _ in range(_SPINS_MAX):
        with self._lock:
            physical_time = self._physical()
            wall_old = self._last >> _COUNTER_BITS
            counter_old = self._last & _COUNTER_MASK

            if physical_time > wall_old:
                wall, counter = physical_time, 0
            else:
                wall, counter = wall_old, counter_old + 1

            if counter <= _COUNTER_MASK:
                previous = self._last

                self._last = (wall << _COUNTER_BITS) | counter

                if self._last <= previous:
                    message = (
                        f'HLC monotonicity violated: '
                        f'{self._last} <= {previous}'
                    )

                    raise ClockOverflowError(message)

                return self._last

        time.sleep(0.001)

    message = (
        f'HLC counter overflow: unable to advance '
        f'after {_SPINS_MAX} attempts'
    )

    raise ClockOverflowError(message)

receive

Source code in django_spire/contrib/sync/core/clock.py
def receive(self, remote: int) -> int:
    if remote < 0:
        message = (
            f'The remote timestamp must be non-negative, '
            f'got {remote}'
        )

        raise InvalidParameterError(message)

    for _ in range(_SPINS_MAX):
        with self._lock:
            physical_time = self._physical()
            wall_old = self._last >> _COUNTER_BITS
            counter_old = self._last & _COUNTER_MASK
            wall_remote = remote >> _COUNTER_BITS
            counter_remote = remote & _COUNTER_MASK

            wall = max(physical_time, wall_old, wall_remote)

            if wall == wall_old == wall_remote:
                counter = max(counter_old, counter_remote) + 1
            elif wall == wall_old:
                counter = counter_old + 1
            elif wall == wall_remote:
                counter = counter_remote + 1
            else:
                counter = 0

            if counter <= _COUNTER_MASK:
                previous = self._last
                self._last = (wall << _COUNTER_BITS) | counter

                if self._last <= previous:
                    message = (
                        f'HLC monotonicity violated: '
                        f'{self._last} <= {previous}'
                    )

                    raise ClockOverflowError(message)

                return self._last

        time.sleep(0.001)

    message = (
        f'HLC counter overflow: unable to advance '
        f'after {_SPINS_MAX} attempts'
    )
    raise ClockOverflowError(message)

update

Source code in django_spire/contrib/sync/core/clock.py
def update(self, remote: int) -> None:
    self.receive(remote)