Skip to content

Commit eabc1c5

Browse files
Fix DSL-configured shutdown_after and hibernate_after being ignored (#11)
The values were stored for introspection but never read during process startup. Server.init/1 and Server.start_link/1 now fall back to the module's DSL-configured values when options are not explicitly passed.
1 parent 65123fe commit eabc1c5

3 files changed

Lines changed: 60 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Fixed
11+
12+
- DSL-configured `shutdown_after` and `hibernate_after` options were ignored at runtime — processes never shut down even when `shutdown_after` was set in the `options` block. The values were stored for introspection but never read during process startup. `Server.init/1` and `Server.start_link/1` now fall back to the module's DSL-configured values when options are not explicitly passed.
13+
1014
### Added
1115

1216
- Built-in `state.id` field on every object's `State` struct, automatically set to the object's ID at init time

lib/durable_object/server.ex

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@ defmodule DurableObject.Server do
3636
def start_link(opts) do
3737
module = Keyword.fetch!(opts, :module)
3838
object_id = Keyword.fetch!(opts, :object_id)
39-
hibernate_after = Keyword.get(opts, :hibernate_after, @default_hibernate_after)
39+
40+
hibernate_after =
41+
Keyword.get_lazy(opts, :hibernate_after, fn ->
42+
if function_exported?(module, :__durable_object__, 1),
43+
do: module.__durable_object__(:hibernate_after),
44+
else: @default_hibernate_after
45+
end)
4046

4147
GenServer.start_link(__MODULE__, opts,
4248
name: via_tuple(module, object_id),
@@ -122,7 +128,13 @@ defmodule DurableObject.Server do
122128
def init(opts) do
123129
module = Keyword.fetch!(opts, :module)
124130
object_id = Keyword.fetch!(opts, :object_id)
125-
shutdown_after = Keyword.get(opts, :shutdown_after)
131+
132+
shutdown_after =
133+
Keyword.get_lazy(opts, :shutdown_after, fn ->
134+
if function_exported?(module, :__durable_object__, 1),
135+
do: module.__durable_object__(:shutdown_after)
136+
end)
137+
126138
repo = Keyword.get(opts, :repo)
127139
prefix = Keyword.get(opts, :prefix)
128140
default_state = module.__durable_object__(:default_state)

test/durable_object/server_test.exs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,49 @@ defmodule DurableObject.ServerTest do
237237
end
238238
end
239239

240+
defmodule ShutdownHandler do
241+
use DurableObject
242+
243+
state do
244+
field(:data, :string, default: nil)
245+
end
246+
247+
handlers do
248+
handler(:get)
249+
end
250+
251+
options do
252+
shutdown_after(50)
253+
end
254+
255+
def handle_get(state) do
256+
{:reply, state, state}
257+
end
258+
end
259+
240260
describe "shutdown_after" do
261+
test "DSL-configured shutdown_after is respected" do
262+
id = unique_id("dsl-shutdown")
263+
264+
{:ok, pid} = Server.start_link(module: ShutdownHandler, object_id: id)
265+
266+
assert Process.alive?(pid)
267+
Process.sleep(100)
268+
refute Process.alive?(pid)
269+
end
270+
271+
test "explicit shutdown_after overrides DSL config" do
272+
id = unique_id("dsl-shutdown-override")
273+
274+
{:ok, pid} =
275+
Server.start_link(module: ShutdownHandler, object_id: id, shutdown_after: 200)
276+
277+
Process.sleep(100)
278+
assert Process.alive?(pid)
279+
Process.sleep(150)
280+
refute Process.alive?(pid)
281+
end
282+
241283
test "process shuts down after timeout" do
242284
{:ok, pid} =
243285
Server.start_link(

0 commit comments

Comments
 (0)