Erlang: не удается создать gen_server:call()

#erlang #erlang-otp

#erlang #erlang-otp

Вопрос:

Учитывая следующий код:

 -module(appender_server).
-behaviour(gen_server).

-export([start_link/1, stop/0]).
-export([append_synched/2]).
-export([init/1, handle_call/3, handle_cast/2]).

start_link(FilePath) ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, FilePath, []).

init(FilePath) ->
    {ok, TheFile} = file:open(FilePath, [append]), % File is created if it does not exist.
    io_lib:print(TheFile).

append_synched(FilePath, Text) ->
    gen_server:call(?MODULE, {append_synched, FilePath, Text}).

handle_call({append_synched, FilePath, Text}, _From, LoopData) ->
    io:fwrite("Hello!~n", []),
    io:fwrite("LoopData:~p~n", LoopData),
    io:fwrite("~p~n", FilePath),
    io:fwrite("~p~n", Text).
    
handle_cast(append_asynched, Str) ->
    {ok, theFile} = file:write_file(theFile, Str).

stop() ->
 gen_server:cast(?MODULE, stop).
 

Затем я использую оболочку erlang для вызова следующего и получения ошибок:

 1> cd("c:/Users/TalTe/WebAppsProjects/fileappender/src/").
c:/Users/TalTe/WebAppsProjects/fileappender/src
ok
2> c(appender_server).
{ok,appender_server}
3> appender_server:start_link("c:/temp/file.txt").
{error,{bad_return_value,"<0.88.0>"}}
4> =CRASH REPORT==== 2-Dec-2020::23:30:19.687000 ===
  crasher:
    initial call: appender_server:init/1
    pid: <0.87.0>
    registered_name: appender_server
    exception exit: {bad_return_value,"<0.88.0>"}
      in function  gen_server:init_it/6 (gen_server.erl, line 409)
    ancestors: [<0.79.0>]
    message_queue_len: 0
    messages: []
    links: [<0.79.0>]
    dictionary: []
    trap_exit: false
    status: running
    heap_size: 376
    stack_size: 28
    reductions: 257
  neighbours:
    neighbour:
      pid: <0.79.0>
      registered_name: []
      initial_call: {erlang,apply,2}
      current_function: {io,execute_request,2}
      ancestors: []
      message_queue_len: 0
      links: [<0.78.0>,<0.87.0>]
      trap_exit: false
      status: waiting
      heap_size: 1598
      stack_size: 26
      reductions: 5365
      current_stacktrace: [{io,execute_request,2,[{file,"io.erl"},{line,571}]},
                  {shell,exprs,7,[{file,"shell.erl"},{line,693}]},
                  {shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
                  {shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]
** exception error: {bad_return_value,"<0.88.0>"}
4> appender_server:append_synched("c:/temp:/file.txt", "Hello").
** exception exit: {noproc,{gen_server,call,
                                       [appender_server,
                                        {append_synched,"c:/temp:/file.txt","Hello"}]}}
     in function  gen_server:call/2 (gen_server.erl, line 238)
5> 
 

Пожалуйста, помогите мне понять, что я здесь делаю не так?
Кстати, файл был создан, несмотря на ошибку на шаге 3.

Ответ №1:

Обратный init вызов должен вернуться {ok, SomeState} . В вашем случае возвращаемое значение init является возвращаемым значением io_lib:print()

Комментарии:

1. ДА. Вы, конечно, правы. Спасибо. Тем не менее, последняя команда завершается сбоем. Правильно ли я его вызываю: appender_server:append_synched(«c:/temp/file.txt «, «Привет»). ? Reson для проверки: {badarg,[{io,format,[<0.65.0>,»LoopData:~p ~ n»,<0.92.0>],[]} . ошибка исключения: неверный аргумент

2. Так и должно быть io:fwrite("LoopData:~p~n", [LoopData]) . Вам нужно изменить другие вызовы на io:fwrite also . Кроме того, возвращаемое значение from handle_call неверно. Так и должно быть {reply, SomeReply, SomeState} . Возвращаемое значение из handle_cast также неверно. Так и должно {noreply, SomeState} быть.