{"result":{"depiction_url":null,"edges":{"hasreference":{"objects":[{"created":"2026-10-07T11:13:42Z","object_id":{"id":1429,"is_a":["text","documentation","cookbook"],"name":"doc_cookbook_justenough_otp1","title":{"_type":"trans","tr":{"en":"Create an Erlang application with Rebar3"}},"uri":"https:\/\/zotonic.com\/id\/1429"},"seq":1},{"created":"2026-10-07T11:13:42Z","object_id":{"id":2963,"is_a":["text","documentation","developerguide"],"name":"developer_background_work","title":{"_type":"trans","tr":{"en":"Run work outside a request"}},"uri":"https:\/\/zotonic.com\/id\/2963"},"seq":2}],"predicate":{"id":2774,"is_a":["meta","predicate"],"name":"hasreference","title":{"_type":"trans","tr":{"en":"Documentation reference"}},"uri":"https:\/\/zotonic.com\/id\/hasreference"}},"references":{"objects":[{"created":"2020-05-30T05:47:21Z","object_id":{"id":1429,"is_a":["text","documentation","cookbook"],"name":"doc_cookbook_justenough_otp1","title":{"_type":"trans","tr":{"en":"Create an Erlang application with Rebar3"}},"uri":"https:\/\/zotonic.com\/id\/1429"},"seq":1000000}],"predicate":{"id":332,"is_a":["meta","predicate"],"name":"references","title":{"_type":"trans","tr":{"en":"References"}},"uri":"https:\/\/zotonic.com\/id\/references"}},"subject":{"objects":[{"created":"2026-10-07T11:13:42Z","object_id":{"id":2553,"is_a":["categorization","keyword","keyword_information_type"],"name":"zotonic_topic_tutorial","title":"Tutorial","uri":"https:\/\/zotonic.com\/id\/2553"},"seq":1},{"created":"2026-10-07T11:13:42Z","object_id":{"id":2564,"is_a":["categorization","keyword","keyword_audience"],"name":"zotonic_topic_backend_developer","title":"Backend developer","uri":"https:\/\/zotonic.com\/id\/2564"},"seq":2},{"created":"2026-10-07T11:13:42Z","object_id":{"id":2670,"is_a":["categorization","keyword","keyword_technology"],"name":"zotonic_topic_erlang_otp","title":"Erlang\/OTP","uri":"https:\/\/zotonic.com\/id\/2670"},"seq":3},{"created":"2026-10-07T11:13:42Z","object_id":{"id":2613,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_development_and_debugging","title":"Development and debugging","uri":"https:\/\/zotonic.com\/id\/2613"},"seq":4}],"predicate":{"id":308,"is_a":["meta","predicate"],"name":"subject","title":{"_type":"trans","tr":{"en":"Keyword"}},"uri":"http:\/\/purl.org\/dc\/elements\/1.1\/subject"}}},"id":1428,"is_a":["text","documentation","cookbook"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1428"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_cookbook_justenough_otp2","page_url":{"en":"https:\/\/zotonic.com\/cookbook\/1428\/add-a-supervised-erlang-worker","x-default":"https:\/\/zotonic.com\/cookbook\/1428\/add-a-supervised-erlang-worker"},"preview_url":null,"resource":{"body":{"_type":"trans","tr":{"en":"<p>Start with the <code>garden_counter<\/code> application from the preceding Rebar3 recipe. Use OTP 28. Create <code>src\/garden_counter_server.erl<\/code>:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-erlang\">-module(garden_counter_server).\n-behaviour(gen_server).\n-export([start_link\/0, next\/0]).\n-export([init\/1, handle_call\/3, handle_cast\/2]).\n\nstart_link() -&gt; gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).\nnext() -&gt; gen_server:call(?MODULE, next).\ninit([]) -&gt; {ok, 0}.\nhandle_call(next, _From, Count) -&gt;\n    {reply, Count + 1, Count + 1};\nhandle_call(_Request, _From, Count) -&gt;\n    {reply, {error, unknown_request}, Count}.\nhandle_cast(_Message, Count) -&gt; {noreply, Count}.\n<\/code><\/pre>\n<p>Replace the generated supervisor&#39;s <code>init\/1<\/code> definition with:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-erlang\">init([]) -&gt;\n    Flags = #{strategy =&gt; one_for_one, intensity =&gt; 3, period =&gt; 10},\n    Worker = #{id =&gt; garden_counter_server,\n               start =&gt; {garden_counter_server, start_link, []},\n               restart =&gt; permanent,\n               shutdown =&gt; 5000,\n               type =&gt; worker,\n               modules =&gt; [garden_counter_server]},\n    {ok, {Flags, [Worker]}}.\n<\/code><\/pre>\n<p>Keep its existing <code>-module<\/code>, behaviour, exports and <code>start_link\/0<\/code>. Then run <code>rebar3 compile<\/code> and <code>rebar3 shell<\/code> again. In that practice shell:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-erlang\">application:ensure_all_started(garden_counter).\ngarden_counter_server:next().\ngarden_counter_server:next().\nsupervisor:which_children(garden_counter_sup).\n<\/code><\/pre>\n<p>Expect 1, then 2, and a running worker PID. To test recovery <strong>in this practice application<\/strong>, stop the worker:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-erlang\">gen_server:stop(garden_counter_server).\n<\/code><\/pre>\n<p>Call <code>supervisor:which_children\/1<\/code> again after it restarts. The PID should change. The next counter value is 1: supervision restarts a process, but does not persist its state. Rapid repeated failures can exceed the restart limit and stop the supervisor.<\/p>\n<p>For graphical inspection, <code>observer:start().<\/code> requires Erlang&#39;s optional wx support and a display. <code>supervisor:which_children\/1<\/code> works without a GUI; the old <code>pman<\/code> tool is not part of this workflow. Leave the standalone practice shell with <code>q().<\/code>. Leave a remote Zotonic shell with <strong>Ctrl-C twice<\/strong>.<\/p>"}},"category_id":{"id":318,"is_a":["meta","category"],"name":"cookbook","title":{"_type":"trans","tr":{"en":"Cookbook"}},"uri":"https:\/\/test.zotonic.com\/id\/318"},"content_group_id":{"id":339,"is_a":["meta","content_group"],"name":"default_content_group","title":{"_type":"trans","tr":{"en":"Default Content Group"}},"uri":"https:\/\/zotonic.com\/id\/default_content_group"},"created":"2020-05-30T05:47:21Z","creator_id":{"id":336,"is_a":["person","robot"],"name":"gitbot","title":"Git","uri":"https:\/\/zotonic.com\/id\/336"},"doc_editorial_bundle":true,"doc_editorial_edges":{"hasreference":[1429,2963],"subject":[2553,2564,2613,2670]},"github_url":"https:\/\/github.com\/zotonic\/zotonic\/tree\/master\/doc\/cookbook\/justenough-otp2.rst","is_authoritative":true,"is_dependent":false,"is_featured":false,"is_protected":false,"is_published":true,"is_unfindable":false,"language":["en"],"modified":"2026-10-07T11:13:52Z","modifier_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"name":"doc_cookbook_justenough_otp2","pivot_geocode":null,"pivot_location_lat":null,"pivot_location_lng":null,"privacy":0,"publication_end":"9999-06-01T00:00:00Z","publication_start":"2022-02-15T10:01:26Z","slug":"add-a-supervised-erlang-worker","summary":{"_type":"trans","tr":{"en":"Add a gen_server and verify that its supervisor restarts it."}},"title":{"_type":"trans","tr":{"en":"Add a supervised Erlang worker"}},"title_slug":{"_type":"trans","tr":{"en":"add-a-supervised-erlang-worker"}},"tz":"UTC","uri":null,"version":32,"visible_for":0},"uri":"https:\/\/zotonic.com\/id\/1428","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1428"}},"status":"ok"}