defmoduleEveSrvdodefmoduleState,do:defstructevents:%{},clients:%{}defmoduleEvent,do:defstructname:"",description:"",pid:nil,time_out:~N[1970-01-0100:00:00]definitdo# Loading events from a static file could be done here.# You would need to pass an argument to init telling where the# resource to find the events is. Then load it from here.# Another option is to just pass the events straight to the server# through this function.loop(%State{})enddefloop(state=%State{})doreceivedo{pid,msg_ref,{:subscribe,client}}->ref=Process.monitor(client)new_clients=Map.put_new(state.clients,ref,client)send(pid,{msg_ref,:ok})loop(%{state|clients:new_clients}){pid,msg_ref,{:add,name,description,time_out}}->event_pid=Event.start_link(name,time_out)new_events=Map.put_new(state.events,name,%EveSrv.Event{name:name,description:description,pid:event_pid,time_out:time_out})send(pid,{msg_ref,:ok})loop(%{state|events:new_events}){pid,msg_ref,{:cancel,name}}->events=caseMap.fetch(state.events,name)do{:ok,e}->Event.cancel(e.pid)Map.delete(state.events,name):error->state.eventsendsend(pid,{msg_ref,:ok})loop(%{state|events:events}){:done,name}->caseMap.fetch(state.events,name)do{:ok,e}->send_to_clients(state.clients,{:done,e.name,e.description})new_events=Map.delete(state.events,name)loop(%{state|events:new_events}):error-># This may happen if we cancel an event and# it fires at the same time.loop(state)end:shutdown->exit(:shutdown){:DOWN,ref,:process,_pid,_reason}->loop(%{state|clients:Map.delete(state.clients,ref)}):code_change->:do_something:unknown->IO.puts("Unknown message: #{inspectunknown}")loop(state)endenddefsend_to_clients(clients,msg)doMap.values(clients)|>Enum.each(&(send(&1,msg)))endend