Resolving warnings about `:restart` and `:shutdown` options being deprecated for `Task.Supervisor.start_link/1`

I’m testing upgrading my app to Elixir 1.10.x. I’m seeing three of these warnings when my app starts (in :dev):

warning: :restart and :shutdown options in Task.Supervisor.start_link/1 are deprecated. Please pass those options on start_child/3 instead
  (elixir 1.10.3) lib/task/supervisor.ex:86: Task.Supervisor.start_link/1
  (stdlib 3.13) supervisor.erl:385: :supervisor.do_start_child_i/3
  (stdlib 3.13) supervisor.erl:371: :supervisor.do_start_child/2
  (stdlib 3.13) supervisor.erl:355: anonymous fn/3 in :supervisor.start_children/2
  (stdlib 3.13) supervisor.erl:1171: :supervisor.children_map/4
  (stdlib 3.13) supervisor.erl:321: :supervisor.init_children/2
  (stdlib 3.13) gen_server.erl:417: :gen_server.init_it/2
  (stdlib 3.13) gen_server.erl:385: :gen_server.init_it/6
  (stdlib 3.13) proc_lib.erl:226: :proc_lib.init_p_do_apply/3

I’m guessing this is my app’s supervisor but that’s mainly because I can only correlate those warnings to different parts of the supervisor tree starting based on the console logs:

...

warning: :restart and :shutdown options in Task.Supervisor.start_link/1 are deprecated. Please pass those options on start_child/3 instead
  (elixir 1.10.3) lib/task/supervisor.ex:86: Task.Supervisor.start_link/1
  (stdlib 3.13) supervisor.erl:385: :supervisor.do_start_child_i/3
  (stdlib 3.13) supervisor.erl:371: :supervisor.do_start_child/2
  (stdlib 3.13) supervisor.erl:355: anonymous fn/3 in :supervisor.start_children/2
  (stdlib 3.13) supervisor.erl:1171: :supervisor.children_map/4
  (stdlib 3.13) supervisor.erl:321: :supervisor.init_children/2
  (stdlib 3.13) gen_server.erl:417: :gen_server.init_it/2
  (stdlib 3.13) gen_server.erl:385: :gen_server.init_it/6
  (stdlib 3.13) proc_lib.erl:226: :proc_lib.init_p_do_apply/3


18:17:04.096 domain=otp.sasl file=supervisor.erl function=report_progress/2 line=1433 mfa=:supervisor.report_progress/2 module=supervisor pid=<0.3957.0> [info]  Child :event_sup of Supervisor MyApp.Supervisor started
Pid: #PID<0.3999.0>
Start Call: Task.Supervisor.start_link([name: :event_sup, restart: :temporary, shutdown: 30000])
Restart: :permanent
Shutdown: :infinity
Type: :supervisor
 
18:17:04.096 application=partially domain=elixir file=lib/partially/task_killer.ex function=start_link/1 line=9 mfa=MyApp.TaskKiller.start_link/1 module=MyApp.TaskKiller pid=<0.3957.0> [debug] MyApp.TaskKiller start_link with sup :event_sup and [name: :event_killer]
 
18:17:04.096 domain=otp.sasl file=supervisor.erl function=report_progress/2 line=1433 mfa=:supervisor.report_progress/2 module=supervisor pid=<0.3957.0> [info]  Child :event_killer of Supervisor MyApp.Supervisor started
Pid: #PID<0.4000.0>
Start Call: MyApp.TaskKiller.start_link([:event_sup, [name: :event_killer]])
Restart: :permanent
Shutdown: 31000
Type: :worker
warning: :restart and :shutdown options in Task.Supervisor.start_link/1 are deprecated. Please pass those options on start_child/3 instead
  (elixir 1.10.3) lib/task/supervisor.ex:86: Task.Supervisor.start_link/1
  (stdlib 3.13) supervisor.erl:385: :supervisor.do_start_child_i/3
  (stdlib 3.13) supervisor.erl:371: :supervisor.do_start_child/2
  (stdlib 3.13) supervisor.erl:355: anonymous fn/3 in :supervisor.start_children/2
  (stdlib 3.13) supervisor.erl:1171: :supervisor.children_map/4
  (stdlib 3.13) supervisor.erl:321: :supervisor.init_children/2
  (stdlib 3.13) gen_server.erl:417: :gen_server.init_it/2
  (stdlib 3.13) gen_server.erl:385: :gen_server.init_it/6
  (stdlib 3.13) proc_lib.erl:226: :proc_lib.init_p_do_apply/3


18:17:04.097 domain=otp.sasl file=supervisor.erl function=report_progress/2 line=1433 mfa=:supervisor.report_progress/2 module=supervisor pid=<0.3957.0> [info]  Child :installment_sup of Supervisor MyApp.Supervisor started
Pid: #PID<0.4001.0>
Start Call: Task.Supervisor.start_link([name: :installment_sup, max_restarts: 3, restart: :transient, shutdown: 10000])
Restart: :permanent
Shutdown: :infinity
Type: :supervisor
warning: :restart and :shutdown options in Task.Supervisor.start_link/1 are deprecated. Please pass those options on start_child/3 instead
  (elixir 1.10.3) lib/task/supervisor.ex:86: Task.Supervisor.start_link/1
  (stdlib 3.13) supervisor.erl:385: :supervisor.do_start_child_i/3
  (stdlib 3.13) supervisor.erl:371: :supervisor.do_start_child/2
  (stdlib 3.13) supervisor.erl:355: anonymous fn/3 in :supervisor.start_children/2
  (stdlib 3.13) supervisor.erl:1171: :supervisor.children_map/4
  (stdlib 3.13) supervisor.erl:321: :supervisor.init_children/2
  (stdlib 3.13) gen_server.erl:417: :gen_server.init_it/2
  (stdlib 3.13) gen_server.erl:385: :gen_server.init_it/6
  (stdlib 3.13) proc_lib.erl:226: :proc_lib.init_p_do_apply/3


18:17:04.098 domain=otp.sasl file=supervisor.erl function=report_progress/2 line=1433 mfa=:supervisor.report_progress/2 module=supervisor pid=<0.3957.0> [info]  Child :scheduled_task_sup of Supervisor MyApp.Supervisor started
Pid: #PID<0.4002.0>
Start Call: Task.Supervisor.start_link([name: :scheduled_task_sup, restart: :transient, shutdown: 5000, max_restarts: 3])
Restart: :permanent
Shutdown: :infinity
Type: :supervisor

...

That also seems to match the options for the correlated supervisor children; from the code that start’s the app supervisor:

    children = [
      ...
      Supervisor.child_spec({Task.Supervisor,      [name: :event_sup, restart: :temporary, shutdown: 30_000]                          }, id: :event_sup),
      ...
      Supervisor.child_spec({Task.Supervisor,      [name: :installment_sup,    max_restarts: 3, restart: :transient, shutdown: 10_000]}, id: :installment_sup),
      Supervisor.child_spec({Task.Supervisor,      [name: :scheduled_task_sup, max_restarts: 3, restart: :transient, shutdown: 5000  ]}, id: :scheduled_task_sup),
      ...
    ]

    ...

    opts = [strategy: :one_for_one, name: MyApp.Supervisor]
    Supervisor.start_link(children, opts)

If I’m right that these child_spec calls are the problem, how do I fix it? Can I just move the :restart and :shutdown options to the end, i.e. after the :id option?

This was a perfect example of rubber duck debugging.

I was able – seemingly – to just move the :restart and :shutdown options to the end of the Supervisor.child_spec calls:

    children = [
      ...
      Supervisor.child_spec({Task.Supervisor, [name: :event_sup                          ]}, id: :event_sup,          restart: :temporary, shutdown: 30_000),
      ...
      Supervisor.child_spec({Task.Supervisor, [name: :installment_sup,    max_restarts: 3]}, id: :installment_sup,    restart: :transient, shutdown: 10_000),
      Supervisor.child_spec({Task.Supervisor, [name: :scheduled_task_sup, max_restarts: 3]}, id: :scheduled_task_sup, restart: :transient, shutdown: 5000  ),
      ...
    ]

The warnings are gone (but all of my tests still pass)!

1 Like