インターフェースを追加する

defmoduleEventdodefmoduleState,do:defstructserver:nil,name:"",to_go:0defstart(event_name,delay)dospawn(__MODULE__,:init,[self,event_name,delay])enddefstart_link(event_name,delay)dospawn_link(__MODULE__,:init,[self,event_name,delay])end# event's innerdsdefinit(server,event_name,delay)doloop(%State{server:server,name:event_name,to_go:normalize(delay)})enddefcancel(pid)do# Monitor in case the process is already dead.ref=Process.monitor(pid)send(pid,{self,ref,:cancel})receivedo{ref,:ok}->Process.demonitor(ref,[:flush]):ok{:DOWN,ref,:process,pid,_reason}->:okendend# Because Erlang is limited to about 49 days (49*24*60*60*1000) in# milliseconds, the following function is used.defnormalize(n)dolimit=49*24*60*60[rem(n,limit)|List.duplicate(limit,div(n,limit))]end# Loop uses a list for times in order to go around the ~49 days limit# on timeouts.defloop(state=%State{server:server,to_go:[t|next]})doreceivedo{server,ref,:cancel}->send(server,{ref,:ok})aftert*1000->casenextdo[]->send(server,{:done,state.name})[_x]->loop(%{state|to_go:next})endendendend