Deal with clock drifts and use DateTime UTC for server data (#2787)

This commit is contained in:
José Valim 2024-09-18 16:10:35 +02:00 committed by GitHub
parent 511644f563
commit 2e45f8aca0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 24 additions and 18 deletions

View file

@ -469,7 +469,7 @@ defmodule Livebook.Hubs.TeamClient do
deployment_group_id: app_deployment.deployment_group_id,
file: nil,
deployed_by: app_deployment.deployed_by,
deployed_at: NaiveDateTime.from_gregorian_seconds(app_deployment.deployed_at)
deployed_at: DateTime.from_gregorian_seconds(app_deployment.deployed_at)
}
end

View file

@ -16,7 +16,7 @@ defmodule Livebook.Teams.AppDeployment do
deployment_group_id: String.t() | nil,
file: binary() | nil,
deployed_by: String.t() | nil,
deployed_at: NaiveDateTime.t() | nil
deployed_at: DateTime.t() | nil
}
@access_types Livebook.Notebook.AppSettings.access_types()
@ -33,8 +33,7 @@ defmodule Livebook.Teams.AppDeployment do
field :deployment_group_id, :string
field :file, :string
field :deployed_by, :string
timestamps(updated_at: nil, inserted_at: :deployed_at)
field :deployed_at, :utc_datetime
end
@doc """

View file

@ -3,16 +3,18 @@ defmodule Livebook.Utils.Time do
@doc """
Formats the given point in time relatively to present.
## Examples
To deal with clock-drifts when receiving timestamps from the server, we accept future times:
iex> Livebook.Utils.Time.time_ago_in_words(~N[2100-06-20 18:15:00])
"less than 5 seconds"
"""
@spec time_ago_in_words(NaiveDateTime.t()) :: String.t()
def time_ago_in_words(naive_date_time) when is_struct(naive_date_time, NaiveDateTime) do
now = NaiveDateTime.utc_now()
if NaiveDateTime.compare(naive_date_time, now) == :gt do
raise ArgumentError, "expected a datetime in the past, got: #{inspect(naive_date_time)}"
end
distance_of_time_in_words(naive_date_time, now)
distance_of_time_in_words(naive_date_time, NaiveDateTime.utc_now())
end
@doc """
@ -75,6 +77,11 @@ defmodule Livebook.Utils.Time do
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2021-08-22 18:15:00])
"about 14 months"
To deal with clock-drifts when receiving timestamps from another machine, we accept future times:
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:06], ~N[2020-06-20 18:15:04])
"less than 5 seconds"
"""
@spec distance_of_time_in_words(NaiveDateTime.t(), NaiveDateTime.t()) :: String.t()
def distance_of_time_in_words(from_ndt, to_ndt)
@ -92,7 +99,7 @@ defmodule Livebook.Utils.Time do
defp maybe_convert_to_minutes(duration), do: duration
defp duration_in_words({:seconds, seconds}) when seconds in 0..4 do
defp duration_in_words({:seconds, seconds}) when seconds <= 4 do
"less than 5 seconds"
end

View file

@ -73,7 +73,7 @@ defmodule LivebookWeb.HTMLHelpers do
Formats the given UTC datetime relatively to present.
"""
@spec format_datetime_relatively(DateTime.t() | NaiveDateTime.t()) :: String.t()
def format_datetime_relatively(%DateTime{} = date) do
def format_datetime_relatively(%DateTime{time_zone: "Etc/UTC"} = date) do
date |> DateTime.to_naive() |> Livebook.Utils.Time.time_ago_in_words()
end

View file

@ -663,10 +663,10 @@ defmodule Livebook.Hubs.TeamClientTest do
version: Livebook.Utils.random_id(),
file: nil,
deployed_by: teams_app_deployment.app_revision.created_by.name,
deployed_at: teams_app_deployment.updated_at
deployed_at: DateTime.from_naive!(teams_app_deployment.updated_at, "Etc/UTC")
}
{seconds, 0} = NaiveDateTime.to_gregorian_seconds(app_deployment.deployed_at)
{seconds, 0} = DateTime.to_gregorian_seconds(app_deployment.deployed_at)
livebook_proto_app_deployment =
%LivebookProto.AppDeployment{

View file

@ -106,10 +106,10 @@ defmodule Livebook.Factory do
shasum = Base.encode16(md5_hash, case: :lower)
deployed_at =
NaiveDateTime.utc_now()
|> NaiveDateTime.truncate(:second)
DateTime.utc_now()
|> DateTime.truncate(:second)
{seconds, 0} = NaiveDateTime.to_gregorian_seconds(deployed_at)
{seconds, 0} = DateTime.to_gregorian_seconds(deployed_at)
%Livebook.Teams.AppDeployment{
id: "1",