erlang позволяет прозрачно отправлять сообщения не только внутри процессов ноды но и с одной ноды на другую.
то есть либо Pid ! { message } либо {Pid, server@localhost } ! { message }.
сейчас пишу программу и что-то не ладится.
-module(bhsql_storageserver).
-import(file).
-import(io).
-export([ init/1, find_last_rowid/1, main_loop_start/0, work_select/4, work_insert/5, work_update/5, work_delete/4 ]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
init(Path) ->
register( storageserver, spawn( bhsql_storageserver, main_loop_start, [] ) ).
% register( storageserver, spawn( fun main_loop_start/0 ) ).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
main_loop_start() ->
put(last_rowid,find_last_rowid(1)),
main_loop().
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
main_loop() ->
receive
{ SrcProc, SrcNode, insert, N, Data } -> spawn( bhsql_storageserver,work_insert,[SrcProc,SrcNode,N,Data,gen_rowid()]), main_loop();
{ SrcProc, SrcNode, stop } -> io:fwrite("GOT STOP~n");
X -> io:fwrite("GOT rubbish - ~w~n",[X]), main_loop()
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
find_last_rowid(RowId) ->
case file:read_file_info(rowid_to_filename(RowId)) of
{ error, enoent } -> RowId-1;
{ ok, _ } -> find_last_rowid(RowId+1)
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
rowid_to_filename(RowId) ->
integer_to_list(RowId).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
gen_rowid() ->
RowId=get(last_rowid)+1,
put(last_rowid,RowId),
RowId.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
work_insert(SrcProc,SrcNode,N,Data,RowId) ->
io:fwrite("work_insert - Called with SrcProc=~w SrcNode=~w N=~w Data=~w RowId=~w~n",[SrcProc,SrcNode,N,Data,RowId]),
case file:write_file(rowid_to_filename(RowId),Data) of
ok ->
io:fwrite("work_insert - SENDING RET~n"),
{ SrcProc, SrcNode } ! { insert_result, ok, N, RowId },
io:fwrite("work_insert - SENT RET~n");
{ error, Reason } -> { SrcProc, SrcNode } ! { insert_result, error, N, Reason };
X -> io:fwrite("file:write_file, got rubbish - ~w~n",[X])
end.
-module(msgtest).
-import(io).
-export([ test/0, send_insert/1, send_stop/0 ]).
recv() ->
receive
X -> io:fwrite("GOT ~w~n",[X])
after 2000 ->
io:fwrite("Timeout~n")
end.
send_insert(Data) ->
{ storageserver, server@localhost } ! { self(), client@localhost, insert, 771, Data},
recv().
send_stop() ->
{ storageserver, server@localhost } ! { self(), client@localhost, stop},
recv().
(я немного сократил здесь текст программки, убрав select/update/delete, ибо они в тесте не участвуют)
консоль N1:
erl -sname server
c(bhsql_storageserver).
bhsql_storageserver:init("чтоугодно").
консоль N2:
erl -sname clent
c(msgtest).
msgtest:send_insert(<<"New line">>).
msgtest:send_stop().
итого:
send_insert отрабатывает наполовину нормально, файл создаётся и туда пишется «New line»,
НО! не срабатывает возврат данных с помощью восклицательного знака.
то есть work_insert печатает следущее:
(server@localhost)17> bhsql_storageserver:init("src").
true
work_insert - Called with SrcProc=<8957.39.0> SrcNode=client@localhost N=771 Data=<<78,101,119,32,108,105,110,101>> RowId=14
work_insert - SENDING RET
(server@localhost)18>
=ERROR REPORT==== 12-Jan-2010::19:14:16 ===
Error in process <0.109.0> on node 'server@localhost' with exit value: {badarg,[{bhsql_storageserver,work_insert,5}]}
обламываясь перед
io:fwrite("work_insert - SENT RET~n");