Skip to content

Commit df48fd9

Browse files
committed
relax drift? to match the paper and unburden the client
1 parent 5859ff4 commit df48fd9

3 files changed

Lines changed: 30 additions & 24 deletions

File tree

lib/hlclock/server.ex

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,10 @@ defmodule HLClock.Server do
3434
end
3535

3636
def handle_call(:send_timestamp, _from, data) do
37-
case Timestamp.send(data.timestamp, physical_time(), data.max_drift) do
38-
{:ok, timestamp} ->
39-
{:reply, {:ok, timestamp}, %{data | timestamp: timestamp}}
37+
{:ok, timestamp} =
38+
Timestamp.send(data.timestamp, physical_time(), data.max_drift)
4039

41-
{:error, error} ->
42-
{:reply, {:error, error}, data}
43-
end
40+
{:reply, {:ok, timestamp}, %{data | timestamp: timestamp}}
4441
end
4542

4643
def handle_call(
@@ -60,13 +57,8 @@ defmodule HLClock.Server do
6057
def handle_info(:periodic_send, data) do
6158
Process.send_after(self(), :periodic_send, interval(data))
6259

63-
case Timestamp.send(data.timestamp, physical_time(), data.max_drift) do
64-
{:ok, ts} ->
65-
{:noreply, %{data | timestamp: ts}}
66-
67-
{:error, _} ->
68-
{:noreply, data}
69-
end
60+
{:ok, ts} = Timestamp.send(data.timestamp, physical_time(), data.max_drift)
61+
{:noreply, %{data | timestamp: ts}}
7062
end
7163

7264
defp physical_time, do: System.os_time(:millisecond)

lib/hlclock/timestamp.ex

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ defmodule HLClock.Timestamp do
1010
languages/representations.
1111
"""
1212

13+
import Kernel, except: [send: 2]
14+
1315
defstruct [:time, :counter, :node_id]
1416

1517
alias __MODULE__, as: T
@@ -41,13 +43,24 @@ defmodule HLClock.Timestamp do
4143
Generate a single HLC Timestamp for sending to other nodes or
4244
local causality tracking
4345
"""
44-
def send(%{time: old_time, counter: counter, node_id: node_id}, pt, max_drift) do
46+
def send(%{time: old_time, counter: counter, node_id: node_id}, pt) do
4547
new_time = max(old_time, pt)
4648
new_counter = advance_counter(old_time, counter, new_time)
4749

48-
with :ok <- handle_drift(old_time, new_time, max_drift) do
49-
{:ok, new(new_time, new_counter, node_id)}
50-
end
50+
# We were checking drift exception here, but functionally that
51+
# only catches errors caused by a system adminstrator setting the
52+
# system clock to jump or, more commonly, causing an error
53+
# whenever the computer running the vm sleeps.
54+
{:ok, new(new_time, new_counter, node_id)}
55+
end
56+
57+
# Compatibility for older users of Timestamp that may be providing the max_drift.
58+
def send(
59+
%{time: old_time, counter: counter, node_id: node_id},
60+
pt,
61+
_max_drift
62+
) do
63+
send(%{time: old_time, counter: counter, node_id: node_id}, pt)
5164
end
5265

5366
@doc """
@@ -185,8 +198,15 @@ defmodule HLClock.Timestamp do
185198
end
186199
end
187200

201+
# This was enforcing drift against abs(l - pt) which causes
202+
# timestamps in the past to raise a drift exception. The algorithm
203+
# only requires protecting ourselves against drift into the future
204+
# compared to our physical clock. Relaxing this constraint makes it
205+
# easier to always recv timestamps, simplifying client
206+
# implementations. Clients need to recv every timestamp that could
207+
# be in the future to preserve the causal order.
188208
defp drift?(l, pt, max_drift) do
189-
abs(l - pt) > max_drift
209+
l - pt > max_drift
190210
end
191211

192212
defp advance_counter(old_time, counter, new_time) do

test/hlclock/timestamp_test.exs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,6 @@ defmodule HLClock.TimestampTest do
104104
assert t0.time == t1.time
105105
assert t1.counter == 1
106106
end
107-
108-
test "send can fail due to excessive drift" do
109-
t0 = Timestamp.new(0, 0, 0)
110-
{:error, err} = Timestamp.send(t0, 5 + 1, @max_drift)
111-
assert err == :clock_drift_violation
112-
end
113107
end
114108

115109
describe "recv_timestamp/2" do

0 commit comments

Comments
 (0)