[erlang-questions] Not looping after processing read_file request

Jesper Louis Andersen jesper.louis.andersen@REDACTED
Sun Sep 7 18:52:53 CEST 2014


On Sun, Sep 7, 2014 at 6:29 PM, Justin HANEKOM <justin.hanekom@REDACTED>
wrote:

> I'm trying to create a file server that loops, responding to 2 requests:
> list_dir; and read_file. For some reason the server loops sometimes, but
> for some unknown reason after successfully  responding to a read_file
> request does not receive/respond to any further requests.
>

Hi!

I just tried your code here and it seems to work like it should, in the
happy-path case.

Where your strategy seems to go a bit off is that you have no way of
knowing if your process is still alive, and if it dies, why it died. This
is where you want to use a supervisor to keep your process alive, and
handle errors. Alternatively, you want to have a monitoring process using
erlang:monitor(Process, Pid) in order to figure out if your server exits.
For quick debugging, you can easily check for its status:

Eshell V6.1.2  (abort with ^G)
1> afile_server:start(".").
<0.44.0>
2> exit(v(1), foo).
true
3>
3> is_process_alive(v(1)).
false

but note that for a serious server, you need to have someone watching over
your process and report if it goes wrong along the way. There is really no
other way. You may be lured into having the process itself catch errors,
but this leads to convoluted code quickly:

start(Dir) ->
   spawn(fun() -> try loop(Dir) catch Class:Error ->
error_logger:error_report([{class, Class}, {reason, Reason}]) end end).

(not tested, but you get the gist of it, surely).

Yet another way, is to trace any event on the server process:

Eshell V6.1.2  (abort with ^G)
1> Pid = afile_server:start().
** exception error: undefined function afile_server:start/0
2> Pid = afile_server:start(".").
<0.46.0>
3> dbg:tracer().
{ok,<0.48.0>}
4> dbg:p(Pid, all).
{ok,[{matched,nonode@REDACTED,1}]}
5> Pid ! {self(), list_dir}.
(<0.46.0>) << {<0.44.0>,list_dir} (Timestamp: {1410,108607,886896})
(<0.46.0>) in {afile_server,loop,1} (Timestamp: {1410,108607,886905})
(<0.46.0>) <0.19.0> !
{'$gen_call',{<0.46.0>,#Ref<0.0.0.76>},{list_dir,"."}} (Timestamp: {1410,

              108607,

              886912})
(<0.46.0>) out {gen,do_call,4} (Timestamp: {1410,108607,886915})
(<0.46.0>) << {#Ref<0.0.0.76>,
               {ok,["transit-erlang","afile_server.erl","afile_server.beam",
                    "zoo.txt"]}} (Timestamp: {1410,108607,887026})
(<0.46.0>) in {gen,do_call,4} (Timestamp: {1410,108607,887075})
(<0.46.0>) <0.44.0> ! {<0.46.0>,
                       {list_dir,{ok,["transit-erlang","afile_server.erl",
                                      "afile_server.beam","zoo.txt"]}}}
(Timestamp: {1410,

         108607,

         887078})
{<0.44.0>,list_dir}
(<0.46.0>) out {afile_server,loop,1} (Timestamp: {1410,108607,887081})
[...]
7> exit(Pid, foo).
true
(<0.46.0>) exit foo (Timestamp: {1410,108643,568435})

The idiomatic Erlang way is to have someone else clean up after a failed
process, but at least you have a couple of methods to debug your current
situation.

-- 
J.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20140907/0f1124dc/attachment.htm>


More information about the erlang-questions mailing list