[erlang-questions] Exchanging messages during functions called by Erlang Server Interface mod_esi?

Ingo Jaeckel ingo.jaeckel@REDACTED
Fri Jan 13 21:44:09 CET 2012


Hello,

the problem was not related to the Erlang Service Interface. The
working version of the module is listed below.

Regards,
Ingo

-module(main).
-include_lib("eunit/include/eunit.hrl").
-export([start/0, create/3, read/3, loop/0]).

%% API Functions
start() ->
	register(storage, spawn(?MODULE, loop, [])),

	inets:start(),
	inets:start(httpd, [
		{port, 8080},
		{server_name, "wuza"},
		{server_root, "log"},
		{document_root, "www"},
		{modules,[mod_esi,mod_get]},					
		{erl_script_alias, {"/erl", [main]}}
	]).

create(SessionID, _Env, _Input) ->
	{Key, Value} = lists:last(_Env),

	case Key of
		query_string ->
			reply(SessionID, "{created: true}"),
			storage ! {create, string_to_tuple(Value)};
		_ ->
			reply(SessionID, "{error: \"Missing query string.\"}")
	end.

read(SessionID, _Env, _Input) ->
	storage ! {read, self()},
	receive
		[] ->	reply(SessionID, lists:concat(["{\"count\": 0, \"results\": []}"]));
		Data ->	reply(SessionID, lists:concat(["{\"count\": ", length(Data),
", \"results\": ", json:encode(Data), "}"]))
	end.

loop() -> loop([]).

loop(Data) ->
	receive
		{create, What} ->
			loop(Data ++ [What]);
		{read, ClientPid} ->	
			ClientPid ! Data
	end,
	loop(Data).

%% Local Functions
reply(SessionID, Reply) ->
	mod_esi:deliver(SessionID, [
		"Content-Type: application/json\r\n\r\n",
		Reply
	]).

string_to_tuple(String) ->
	lists:map(fun(Pair) ->
		[Key, Value|_] = string:tokens(Pair, "="),
		{Key, Value} end, string:tokens(String, "&")).

On Thu, Jan 12, 2012 at 11:08 AM, Ingo Jaeckel
<ingo.jaeckel@REDACTED> wrote:
> Hello,
>
> I am currently developing a module that creates an instance of inets
> http server. After starting the server, I call two different messages
> of my module (create/3, read/3) from a browser. Both methods are shown
> below:
>
> create(SessionID, Env, _Input) ->
>        {Key, Value} = lists:last(Env),
>
>        case Key of
>                query_string ->
>                        reply(SessionID, "{created: true}"),
>                        storage ! {create, string_to_tuple(Value)};
>                _ ->
>                        reply(SessionID, "{error: \"Missing query string.\"}")
>        end.
>
> read(SessionID, _Env, _Input) ->
>        storage ! {read, self()},
>        receive
>               [] ->   reply(SessionID, lists:concat(["{\"results\": []}"]));
>               Data ->
>                       reply(SessionID, lists:concat(["{\"count\": ",
> length(Data), ", \"results\": ", json:encode(Data), "}"]))
>       end.
>
> reply(SessionID, Reply) ->
>        mod_esi:deliver(SessionID, [
>                "Content-Type: application/json\r\n\r\n",
>                Reply
>        ]).
>
> I can open the URL for the create/3 function without any problems. The
> browser immediately receives the proper reply. But when I try to call
> the URL for read/3, the server never receives a response. I have
> exactly the same behavior for create/3 when I send a message BEFORE
> replying back to the client.
>
> Now, one difference between read/3 and create/3 is that read/3 sends
> and receives a message to a registered process (running on the same
> node) before it replies back to the client. Is this maybe something
> you cannot do within functions called by mod_esi? Or could there be
> another reason preventing me from sending a proper reply back to the
> client?
>
> Thank you very much in advance!
>
> Regards,
> Ingo



More information about the erlang-questions mailing list