networking - How do I share data between worker processes in Elixir? -


i have 2 workers

worker(mmoserver.messagereceiver, []), worker(mmoserver.main, []) 

the messagereceiver wait until messages received on tcp , process them, main loop take information , act on it. how share info obtained worker1 worker2?

mmoserver.ex
main file starts workers

defmodule mmoserver   use application    def start(_type, _args)     import supervisor.spec, warn: false      io.puts "listening packets..."      children = [       # add our children here later        worker(mmoserver.messagereceiver, []),       worker(mmoserver.main, [])     ]      # start main supervisor, , restart failed children individually     opts = [strategy: :one_for_one, name: acmeudplogger.supervisor]     supervisor.start_link(children, opts)   end  end 

messagereceiver.ex
start tcp listener. should able message, figure out (by it's id) parse data , send specific function in main

defmodule mmoserver.messagereceiver   use genserver   require logger    def start_link(opts \\ [])     genserver.start_link(__module__, :ok, opts)   end    def init (:ok)     {:ok, _socket} = :gen_udp.open(21337)   end    # handle udp data   def handle_info({:udp, _socket, _ip, _port, data}, state)     parse_packet(data)     # logger.info "received secret message! " <> inspect(message)     {:noreply, state}   end    # ignore else   def handle_info({_, _socket}, state)     {:noreply, state}   end    def parse_packet(data)     # convert data string, split data     # warning - split may expensive     datastring = kernel.inspect(data)     vars = string.split(datastring, ",")      # variables     packetid = enum.at(vars, 0)     x = enum.at(vars, 1)      # stuff them     io.puts "packet id:"     io.puts packetid     io.puts x      # send data main     mmoserver.main.handle_data(vars)   end end 

main.ex
main loop. process recent data received tcp listener , act on it. update game state too.

defmodule mmoserver.main   use genserver    @tickdelay 33    def start_link(opts \\ [])     genserver.start_link(__module__, [], name: main)   end    def init (state)      io.puts "main server loop started..."      # start main loop, parameter initial tick value     mainloop(0)      # return, why 1??     {:ok, 1}   end    def handle_data(data)     genserver.cast(:main, {:handle_data, data})   end    def handle_info({:handle_data, data}, state)     # my_function(data)     io.puts "got here2"     io.puts inspect(data)     {:noreply, state}   end    # calls respective game functions   def mainloop(-1)     io.inspect "server loop has ended!" # base case, end of loop   end    def mainloop(times)     # shit     # io.inspect(times) # operation, or body of loop      # sleep     :timer.sleep(@tickdelay);      # continue loop recursively     mainloop(times + 1)   end  end 

because mmoserver.messagereceiver going send messages mmoserver.main, main has started in first place, plus, needs have name associated:

worker(mmoserver.main, []), worker(mmoserver.messagereceiver, []) 

the easiest way be, in mmoserver.main, assuming genserver:

defmodule mmoserver.main   use genserver    def start_link     genserver.start_link(__module__, [], name: :main)   end    # ... end 

you can add convenience function, plus implementation 1 like:

defmodule mmoserver.main   # ...    def handle_data(data)     genserver.cast(:main, {:handle_data, data})   end    def handle_info({:handle_data, data}, state)     my_function(data)     {:noreply, state}   end end 

so, messagereceiver, can send message like:

defmodule mmoserver.messagereceiver   def when_data_received(data)     mmoserver.main.handle_data(data)   end end 

this assumes mmoserver.messagereceiver doesn't expect mmoserver.main respond. i've decided way didn't specify way want handle data , seems easies example of how this.


Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -