erlang - How to pass arguments to :simple_one_for_one GenServer to initialize state -


i trying set supervision tree scheduler application (note using elixir 1.5 syntax). application should work that:

  • application boots registry & scheduler supervisor
  • the schedulersupervisor boots, , allows children dynamically added via start_child callback. takes initialisation args used build schedule state.
  • the scheduler, on initialisation, registers name registry, , initialises struct holds state (scheduler has functions manipulating schedules, isn't relevant issue i'm having).

if don't pass arguments, can working - schedules created not registered, , have modify state after creation. try add arguments, system errors out - know it's syntax misunderstanding on part, cannot life of me figure out i'm doing wrong. haven't found docs terribly helpful here, , i've tried copying , modifying examples gh, gh gists , articles online, cannot work.

current setup - ideally want pass id, period , targets arguments start_child, can't working single argument, sticking 1 until can running:

the application:

defmodule assay.application   use application    def start(_type, _args)     children = [       {assay.schedulersupervisor, []},       {registry, keys: :unique, name: assay.scheduler.registry}     ]      opts = [strategy: :one_for_all, name: assay.supervisor]     supervisor.start_link(children, opts)   end end 

the supervisor:

defmodule assay.schedulersupervisor     use supervisor      @name assay.schedulersupervisor      def start_link(_args)         supervisor.start_link(__module__, :ok, name: @name)     end      def start_schedule(id)         supervisor.start_child(@name, [id])     end      def init(_)         supervisor.init([assay.scheduler], [strategy: :simple_one_for_one, name: @name])     end end 

the genserver (only relevant initialisation functions shown)

defmodule assay.scheduler     use genserver     alias assay.scheduler     require logger      defstruct targets: [], period: 60_000, id: nil, active: false      def start_link(id)         genserver.start_link(__module__, [id], [name: via_tuple(id)])     end      def init([id])         logger.info "starting new #{__module__} id #{id}"         {:ok, %scheduler{id: id}}     end end 

edit: actual error might - can see args wrong, can't figure out why:

{:error,  {:exit,   {:undef,    [{assay.scheduler, :start_link, [[], 1], []},     {:supervisor, :do_start_child_i, 3, [file: 'supervisor.erl', line: 381]},     {:supervisor, :handle_call, 3, [file: 'supervisor.erl', line: 406]},     {:gen_server, :try_handle_call, 4, [file: 'gen_server.erl', line: 636]},     {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 665]},     {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 247]}]}}} 

for :simple_one_for_one supervisors, supervisor.start_child calls start function arguments given arguments specified in child specification. when using supervisor.init, child specification taken module's child_spec/1 function in elixir 1.5. since you're using genserver , not specifying custom start function , [] passed child_spec/1, defaults to [[]] means function ends being called 2 arguments, [] , 1 if id 1 , undefined function error.

you can fix explicitly saying don't want genserver provide arguments start function in child_spec changing

use genserver 

to

use genserver, start: {__module__, :start_link, []} 

now function called correctly, 1 argument, id.

io.inspect assay.schedulersupervisor.start_link [] io.inspect assay.schedulersupervisor.start_schedule 12 

will print:

{:ok, #pid<0.82.0>} [info]  starting new elixir.assay.scheduler id 12 {:ok, #pid<0.83.0>} 

Comments

Popular posts from this blog

resizing Telegram inline keyboard -

command line - How can a Python program background itself? -

php - "cURL error 28: Resolving timed out" on Wordpress on Azure App Service on Linux -