Skip to content

Commit b1fbeb8

Browse files
committed
fix: resolve Elixir 1.20 gradual-type warnings and harden cold-build tests
Reorder LogCapture.serialize_value/1 and CompensationRunner.serialize_output/1 so nil and booleans are not shadowed by the is_atom clause (they were serialized to the strings nil/true/false); they now keep native JSON values, matching StepRunner.serialize_output/1. Drop dead clauses the 1.20 type checker flagged (pattern_to_clause_name true/false, handle_wait_result call_workflow, HistoryTab.format_duration nil), simplify execute_workflow always-truthy context guard, and remove unused require Logger. test_helper: eagerly load durable and postgrex modules to avoid a cold-build on-demand-loader race (module not available) under the parallel suite. Bump credo 1.7.15 to 1.7.19; 1.7.15 crashes on Elixir 1.20 sigil tokens and breaks precommit.
1 parent 64ec008 commit b1fbeb8

8 files changed

Lines changed: 19 additions & 17 deletions

File tree

durable/lib/durable/dsl/step.ex

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,6 @@ defmodule Durable.DSL.Step do
398398

399399
defp pattern_to_clause_name({:_, _, _}), do: :default
400400
defp pattern_to_clause_name(atom) when is_atom(atom), do: atom
401-
defp pattern_to_clause_name(true), do: true
402-
defp pattern_to_clause_name(false), do: false
403401
defp pattern_to_clause_name(string) when is_binary(string), do: String.to_atom(string)
404402
defp pattern_to_clause_name(int) when is_integer(int), do: :"val_#{int}"
405403
defp pattern_to_clause_name(_), do: :match

durable/lib/durable/executor.ex

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ defmodule Durable.Executor do
122122
else
123123
# Pipeline model: start with workflow input or restored context
124124
initial_data =
125-
if execution.context && execution.context != %{} do
125+
if execution.context != %{} do
126126
atomize_keys(execution.context)
127127
else
128128
execution.input
@@ -430,9 +430,6 @@ defmodule Durable.Executor do
430430
defp handle_wait_result(config, exec, :wait_for_all, opts),
431431
do: {:waiting, handle_wait_for_all(config, exec, opts) |> elem(1)}
432432

433-
defp handle_wait_result(config, exec, :call_workflow, opts),
434-
do: handle_call_workflow(config, exec, opts)
435-
436433
# ============================================================================
437434
# Workflow Orchestration (call_workflow)
438435
# ============================================================================

durable/lib/durable/executor/compensation_runner.ex

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ defmodule Durable.Executor.CompensationRunner do
2020
alias Durable.Repo
2121
alias Durable.Storage.Schemas.StepExecution
2222

23-
require Logger
24-
2523
@type result :: {:ok, any()} | {:error, any()}
2624

2725
@doc """
@@ -176,12 +174,12 @@ defmodule Durable.Executor.CompensationRunner do
176174
|> Repo.update(config)
177175
end
178176

177+
defp serialize_output(nil), do: nil
179178
defp serialize_output(output) when is_map(output), do: output
180179
defp serialize_output(output) when is_list(output), do: %{value: output}
181180
defp serialize_output(output) when is_binary(output), do: %{value: output}
182181
defp serialize_output(output) when is_number(output), do: %{value: output}
183182
defp serialize_output(output) when is_atom(output), do: %{value: Atom.to_string(output)}
184183
defp serialize_output(output) when is_tuple(output), do: %{value: Tuple.to_list(output)}
185-
defp serialize_output(nil), do: nil
186184
defp serialize_output(output), do: %{value: inspect(output)}
187185
end

durable/lib/durable/executor/step_runner.ex

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ defmodule Durable.Executor.StepRunner do
1818

1919
import Ecto.Query, only: [from: 2]
2020

21-
require Logger
22-
2321
@type result ::
2422
{:ok, map()}
2523
| {:error, any()}

durable/lib/durable/log_capture.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,10 +272,10 @@ defmodule Durable.LogCapture do
272272
end
273273

274274
defp serialize_value(v) when is_binary(v), do: v
275+
defp serialize_value(nil), do: nil
276+
defp serialize_value(v) when is_boolean(v), do: v
275277
defp serialize_value(v) when is_atom(v), do: Atom.to_string(v)
276278
defp serialize_value(v) when is_number(v), do: v
277-
defp serialize_value(v) when is_boolean(v), do: v
278-
defp serialize_value(nil), do: nil
279279

280280
defp serialize_value(v) do
281281
# Bug M-6: surface (once per step) when log metadata has been silently

durable/mix.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
%{
22
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
3-
"credo": {:hex, :credo, "1.7.15", "283da72eeb2fd3ccf7248f4941a0527efb97afa224bcdef30b4b580bc8258e1c", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "291e8645ea3fea7481829f1e1eb0881b8395db212821338e577a90bf225c5607"},
3+
"credo": {:hex, :credo, "1.7.19", "cc52129665fc7c15143d47838fda0f9cd6dac9ceced7bf4da6f85fcbfe64b12a", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "2d8bc95d5a7bb99dd2613621d4f08c6a3575c3fd4b62e6a2b48a100352a557b8"},
44
"crontab": {:hex, :crontab, "1.2.0", "503611820257939d5d0fd272eb2b454f48a470435a809479ddc2c40bb515495c", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "ebd7ef4d831e1b20fa4700f0de0284a04cac4347e813337978e25b4cc5cc2207"},
55
"db_connection": {:hex, :db_connection, "2.8.1", "9abdc1e68c34c6163f6fb96a96532272d13ad7ca45262156ae8b7ec6d9dc4bec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a61a3d489b239d76f326e03b98794fb8e45168396c925ef25feb405ed09da8fd"},
6-
"decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"},
6+
"decimal": {:hex, :decimal, "2.4.1", "6c0fbede12fb122ba685e9ab41c6a40c129e322b3aa192f9e072e61f3a6ffaf2", [:mix], [], "hexpm", "7e618897933a8455f19a727d7c5e50a2c071a544b700e5e724298ecb4340187f"},
77
"dialyxir": {:hex, :dialyxir, "1.4.7", "dda948fcee52962e4b6c5b4b16b2d8fa7d50d8645bbae8b8685c3f9ecb7f5f4d", [:mix], [{:erlex, ">= 0.2.8", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b34527202e6eb8cee198efec110996c25c5898f43a4094df157f8d28f27d9efe"},
88
"earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"},
99
"ecto": {:hex, :ecto, "3.13.5", "9d4a69700183f33bf97208294768e561f5c7f1ecf417e0fa1006e4a91713a834", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "df9efebf70cf94142739ba357499661ef5dbb559ef902b68ea1f3c1fabce36de"},
@@ -15,7 +15,7 @@
1515
"glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"},
1616
"hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"},
1717
"igniter": {:hex, :igniter, "0.7.0", "6848714fa5afa14258c82924a57af9364745316241a409435cf39cbe11e3ae80", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "1e7254780dbf4b44c9eccd6d86d47aa961efc298d7f520c24acb0258c8e90ba9"},
18-
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
18+
"jason": {:hex, :jason, "1.4.5", "2e3a008590b0b8d7388c20293e9dcc9cf3e5d642fd2a114e4cbbb52e595d940a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b0c823996102bcd0239b3c2444eb00409b72f6a140c1950bc8b457d836b30684"},
1919
"makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"},
2020
"makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"},
2121
"makeup_erlang": {:hex, :makeup_erlang, "1.0.2", "03e1804074b3aa64d5fad7aa64601ed0fb395337b982d9bcf04029d68d51b6a7", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "af33ff7ef368d5893e4a267933e7744e46ce3cf1f61e2dccf53a111ed3aa3727"},

durable/test/test_helper.exs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,15 @@
99
ExUnit.start(exclude: [:integration])
1010

1111
Ecto.Adapters.SQL.Sandbox.mode(Durable.TestRepo, :manual)
12+
13+
# Cold builds + the highly parallel suite can race the BEAM's on-demand code
14+
# loader: the first dynamic reference to a freshly-compiled module can transiently
15+
# fail with "module ... is not available". We've seen it hit Durable mix tasks
16+
# (called directly as `<Task>.run/1`, e.g. `MigrationsTask.run/1`) and Postgrex's
17+
# lazily-loaded error-code table (`Postgrex.ErrorCode`, used when mapping a DB
18+
# error such as a unique violation). The build is settled here and we're still
19+
# single-threaded, so eagerly load those apps' modules before any test runs.
20+
for app <- [:durable, :postgrex],
21+
mod <- Application.spec(app, :modules) || [] do
22+
Code.ensure_loaded(mod)
23+
end

durable_dashboard/lib/durable_dashboard/components/workflow/history_tab.ex

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ defmodule DurableDashboard.Components.Workflow.HistoryTab do
153153

154154
defp pulsing?(s), do: to_string(s) in ["running", "waiting", "compensating"]
155155

156-
defp format_duration(nil), do: "—"
157156
defp format_duration(ms) when ms < 1000, do: "#{ms}ms"
158157
defp format_duration(ms) when ms < 60_000, do: "#{Float.round(ms / 1000, 1)}s"
159158
defp format_duration(ms), do: "#{div(ms, 60_000)}m"

0 commit comments

Comments
 (0)