Получение данных в модуле

218 views
Skip to first unread message

Анастасия Субботина

unread,
Nov 11, 2014, 7:37:03 AM11/11/14
to erlang-...@googlegroups.com
Добрый день.
Данные приходят из другого модуля функцией module:get_data(Data), в модуле получающем следующий код

start_link() -> gen_server:start_link(?MODULE, [], []).
get_data(Data) -> gen_server:cast(?MODULE, {get_data, Data}).
init([]) -> {ok, dict:new()].
handle_cast({get_data, Data}, State) ->
 NewState = dict:store(store, Data, State),
 io:format("Data: ~p ~n ~n", [Data]),
 Response = {ok, Data},
 [reply, Response, NewState}.
Если сделать просто

 get_data(Data) ->  io:format("Data: ~p ~n ~n", [Data]), то данные идут, в чем причина отсутствия данных, когда используется gen_server?

Valery Tikhonov

unread,
Nov 11, 2014, 7:38:48 AM11/11/14
to erlang-...@googlegroups.com

Call вместо cast использовать надобно, если ответ получить желаете.

11 Ноя 2014 г. 14:37 пользователь "Анастасия Субботина" <spasen...@gmail.com> написал:
--
Вы получили это сообщение, поскольку подписаны на группу "Erlang по-русски".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес erlang-russia...@googlegroups.com.
Чтобы отправлять сообщения в эту группу, отправьте письмо на электронный адрес erlang-...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

Анастасия Субботина

unread,
Nov 11, 2014, 8:15:46 AM11/11/14
to erlang-...@googlegroups.com
мне ответ не нужен

вторник, 11 ноября 2014 г., 16:37:03 UTC+4 пользователь Анастасия Субботина написал:

Valery Tikhonov

unread,
Nov 11, 2014, 8:21:22 AM11/11/14
to erlang-...@googlegroups.com
Если не нужен ответ - в cast ставьте {noreply, NewState}
конструкции вида reply возможны лишь в handle_call.

Я так понимаю, причина в том, что handle_cast не вызывается?
Попробуйте зарегистрировать модуль локально, раз вы к нему обращаетесь gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

11 ноября 2014 г., 13:15 пользователь Анастасия Субботина <spasen...@gmail.com> написал:

--

Анастасия Субботина

unread,
Nov 11, 2014, 8:47:28 AM11/11/14
to erlang-...@googlegroups.com
спасибо, что то сдвинулось



вторник, 11 ноября 2014 г., 16:37:03 UTC+4 пользователь Анастасия Субботина написал:
Добрый день.

Анастасия Субботина

unread,
Nov 17, 2014, 5:51:27 AM11/17/14
to erlang-...@googlegroups.com
Каким образом применить ets, чтобы работало

init([]) ->
%    State = ets:new(store, [named_table, set, public]),
    {ok, #state{store = State}}.

handle_cast({get_data, Number}, #state{}) ->
    NewState = #state{store = ets:insert(store, {price, Number})},
    io:format("Number: ~p ~n ~n", [Number]),
    {reply,NewState}.

Eshell V6.2  (abort with ^G)
1> application:start(fast).
ok
2> fast_in:start_link().
{ok,<0.41.0>}
3> fast_server:start_link().
{ok,<0.43.0>}
1.001e5
 
Number: 1.001e5
 
100110.0
 
4>
=ERROR REPORT==== 17-Nov-2014::13:45:27 ===
** Generic server fast_in terminating
** Last message in was {'$gen_cast',{get_data,1.001e5}}
** When Server state == {state,store}
** Reason for termination ==
** {bad_return_value,{reply,{state,true}}}
** exception error: {bad_return_value,{reply,{state,true}}}


вторник, 11 ноября 2014 г., 15:37:03 UTC+3 пользователь Анастасия Субботина написал:

Boris Timokhin

unread,
Nov 17, 2014, 6:03:34 AM11/17/14
to erlang-...@googlegroups.com
Я так понимаю, что дело не в ets, а в том что handle_cast {reply, State} возвращает.

17 ноября 2014 г., 13:51 пользователь Анастасия Субботина <spasen...@gmail.com> написал:

--

Andy

unread,
Nov 17, 2014, 6:50:28 AM11/17/14
to erlang-...@googlegroups.com
Ну и в дополнение: нет резона хранить именованную таблицу в состоянии.

понедельник, 17 ноября 2014 г., 13:03:34 UTC+2 пользователь Boris Timokhin написал:

Анастасия Субботина

unread,
Nov 17, 2014, 7:04:40 AM11/17/14
to erlang-...@googlegroups.com
Логика была следующая - получаем число, на основе его рассчитываем параметры a, b, c, d, при чем b зависит от a и b предыдущего, c зависит от a и b и cпредыдущего, d зависти от a, b, c и d предыдущего. Результат a, b, c, d планировалось внести в ets и передать в качестве состояния для рассчетов при новом числе. Что тогда передавать в State?


вторник, 11 ноября 2014 г., 16:37:03 UTC+4 пользователь Анастасия Субботина написал:
Добрый день.

Boris Timokhin

unread,
Nov 17, 2014, 7:10:13 AM11/17/14
to erlang-...@googlegroups.com
Так может храните в стейте эти ваши переходящие a,b,c,d, они же всё равно имеют смысл только в рамках данного процесса. Так?

17 ноября 2014 г., 15:04 пользователь Анастасия Субботина <spasen...@gmail.com> написал:

--

Анастасия Субботина

unread,
Nov 17, 2014, 7:18:42 AM11/17/14
to erlang-...@googlegroups.com
Но без ets ими не удобно оперировать, к тому же это нужно делать быстро.


вторник, 11 ноября 2014 г., 16:37:03 UTC+4 пользователь Анастасия Субботина написал:
Добрый день.

Andy

unread,
Nov 17, 2014, 9:15:13 AM11/17/14
to erlang-...@googlegroups.com
И ets и State в gen_server используются для хранения данных процессов (а также словарь процесса; да и различия между ними есть, но здесь это несущественно). Поэтому использование обоих - это дублирование. По скорости - конечно, State быстрее будет, особенно если Вам не надо иметь общее хранилище на несколько процессов.

понедельник, 17 ноября 2014 г., 14:04:40 UTC+2 пользователь Анастасия Субботина написал:

Анастасия Субботина

unread,
Nov 18, 2014, 8:14:54 AM11/18/14
to erlang-...@googlegroups.com
Сделала изменения в коде:
 init([]) ->

    ets:new(store, [named_table, set, public]),
    {ok, #state{}}.

handle_cast({get_data, Number}, State) ->
   
    Prev = case ets:lookup(store,weight) of
                       [{_, P}] -> P;
                       _ -> 1.0
               end,
        ets:insert(store,{volume,Prev}),
        if Prev < Number -> ets:insert(store,{more, Number});
               true -> ok
        end,
        ets:insert(store,{weight, Number}),

%    ets:insert(store, {price, Number}),
    NewState = State#state{store = Prev},
   
    io:format("Prev: ~p ~n ~n", [Prev]),
    {reply,NewState}.

Но результат все равно отрицательный:


1> application:start(fast).
ok
2> fast_in:start_link().
{ok,<0.41.0>}
3> fast_server:start_link().
{ok,<0.43.0>}
102270.0
 
Prev: 1.0
 
4>
=ERROR REPORT==== 18-Nov-2014::16:09:48 ===

** Generic server fast_in terminating
** Last message in was {'$gen_cast',{get_data,102270.0}}
** When Server state == {state,undefined}

** Reason for termination ==
** {bad_return_value,{reply,{state,1.0}}}
** exception error: {bad_return_value,{reply,{state,1.0}}}

Что изменить?

Yuri Zhloba

unread,
Nov 18, 2014, 8:24:40 AM11/18/14
to erlang-...@googlegroups.com
{reply,NewState}
нет такого варианта возврата из handle_call
есть
{noreply, NewState}
есть
{reply, Reply, NewState}

Мне кажется, вы не очень хорошо понимаете, как работает gen_server, и handle_call в частности. Рекомендую разобраться в этой теме.

18 ноября 2014 г., 16:14 пользователь Анастасия Субботина <spasen...@gmail.com> написал:

--
Вы получили это сообщение, поскольку подписаны на группу "Erlang по-русски".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес erlang-russia...@googlegroups.com.
Чтобы отправлять сообщения в эту группу, отправьте письмо на электронный адрес erlang-...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.



--
Yuri Zhloba

skype: yzh44yzh
phone: +375 44 793 33 73

Анастасия Субботина

unread,
Nov 18, 2014, 8:36:07 AM11/18/14
to erlang-...@googlegroups.com
 У меня handle_cast.

Yuri Zhloba

unread,
Nov 18, 2014, 8:38:47 AM11/18/14
to erlang-...@googlegroups.com
из handle_cast нет возврата {reply, только {noreply, :)

18 ноября 2014 г., 16:36 пользователь Анастасия Субботина <spasen...@gmail.com> написал:
 У меня handle_cast.

--
Вы получили это сообщение, поскольку подписаны на группу "Erlang по-русски".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес erlang-russia...@googlegroups.com.
Чтобы отправлять сообщения в эту группу, отправьте письмо на электронный адрес erlang-...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

Grigory Fateyev

unread,
Nov 18, 2014, 8:39:52 AM11/18/14
to erlang-...@googlegroups.com
Hello Анастасия Субботина!
Я бы создал файл модуля из шаблона (есть в IDEA и emacs) и смотря на
спеки писал код.

--
Best regards!
gfborn [at] gmail [dot] com

Анастасия Субботина

unread,
Nov 18, 2014, 9:04:46 AM11/18/14
to erlang-...@googlegroups.com
"из handle_cast нет возврата {reply, только {noreply, :)"

Спасибо


вторник, 11 ноября 2014 г., 16:37:03 UTC+4 пользователь Анастасия Субботина написал:
Добрый день.

Вадим Кравченко

unread,
Nov 19, 2014, 8:34:52 AM11/19/14
to erlang-...@googlegroups.com
Что-то я сам начал уже забывать erlang, но разве вы не опечатались в init? вот тут: {ok, #state{}}. Мне кажется там должно быть store вместо state, об этом вроде говорит стектрейс: When Server state == {state,undefined}.

вторник, 18 ноября 2014 г., 17:14:54 UTC+4 пользователь Анастасия Субботина написал:

Анастасия Субботина

unread,
Nov 19, 2014, 8:50:21 AM11/19/14
to erlang-...@googlegroups.com
В том виде как было написано нехватало {noreply, NewState}, с ним все работает.

вторник, 11 ноября 2014 г., 16:37:03 UTC+4 пользователь Анастасия Субботина написал:

Grigory Fateyev

unread,
Nov 19, 2014, 8:59:31 AM11/19/14
to erlang-...@googlegroups.com
Hello Вадим Кравченко!
On Wed, 19 Nov 2014 05:34:52 -0800 (PST) you wrote:

> Что-то я сам начал уже забывать erlang, но разве вы не опечатались в
> init? вот тут: {ok, #state{}}. Мне кажется там должно быть store
> вместо state, об этом вроде говорит стектрейс: When Server state ==
> {state,undefined}.

Если таблица именнованная (параметр named_table), то доступ к таблице
осуществляется по имени и нет смысла сохранять Tid в стейте.

Вадим Кравченко

unread,
Nov 20, 2014, 4:32:06 AM11/20/14
to erlang-...@googlegroups.com
Спасибо за восстановленые знания =) Меня просто смутил синтаксис #state{}. Если я правильно помню, то это синтаксис для рекорда, и в строке NewState = State#state{store = Prev} тоже идет ображение к рекорду state. Ну и я ошибочно принял строку "When Server state == {state,undefined} " как указание того что state undefined, а не того что это рекорд с именем state у которого единственное поле undefined. Поправьте, если ошибаюсь, пожалуйста =)

среда, 19 ноября 2014 г., 17:59:31 UTC+4 пользователь Grigory Fateyev написал:
Reply all
Reply to author
Forward
0 new messages