0

I have a problem matching a message received in a gen_statem in an Erlang module I've called e_counter. Here is a snap shot of the code. The gen_statem is linked to a Supervisor. When the e_counter process receives an event message from another process it increments a counter. The counter is implemented as a record which looks like so

-record(cntr,              {cnt       :: non_neg_integer(),
                            iv        :: non_neg_integer()}).

And defined like this

    CV = InitValues#initValues.di_CV,
    Cntr = #cntr{cnt = 0, iv = CV},

Where CV represents the value the counter is to count up to.

All messages in the code are constructed using a message record that looks like this

-record(message,     {type                      :: event | data,
                      name                      :: atom(),
                      value                     :: any() | undefined,
                      ref                       :: reference(),  % Currently not used
                      from                      :: pid()}).

Here is a snapshot of the gen_statem

incrCnt(cast, #message{type = event, name = ei_INCR, value = undefined, ref = _Ref, from = _From} =_Message, State) when State#state.cntr#cntr.cnt < State#state.cntr#cntr.iv ->
     io:format("Current State ~p~n", [State]),
     NewCount = State#state.cntr#cntr{cnt = State#state.cntr#cntr.cnt +1},
     io:format("Count so far ~p~n", [NewCount]),
     {next_state, incrCnt, NewCount};
incrCnt(cast, #message{type = event, name = ei_INCR, value = undefined, ref = _Ref, from = _From} = _Message, State) when State#state.cntr#cntr.cnt =:= State#state.cntr#cntr.iv ->
     NewCount = State#state.cntr#cntr{cnt =  0},
     gen_func:send_event(State#state.connections#connections.eventOut#eventOut.eo_EO),
     {next_state, incrCnt, NewCount}.

In the SASL error report shown below the first time the message is received by the incrCnt state it is properly matched and in the incrCnt state the counter is incremented. However any messages receives after that result in a error as depicted the ERROR REPORT section of the report.

Eshell V13.1.4  (abort with ^G)
1> application:start(sasl).
ok
2> application:start(checkCntrApp).
{normal, } 
Port #Port<0.5>
ok
3> *** Different: StateBitIndxVals: [1]  ProfinetBitIndxVals *** [0]
ok ),
,ok),
Current State {state,{connections,{eventOut,{connector,ei_2,kl_2404_A}},
                                  {dataOut}},
                     {cntr,0,4}}
Count so far {cntr,1,4}
*** Different: StateBitIndxVals: [0]  ProfinetBitIndxVals *** [1]
ok ),
,ok),




=ERROR REPORT==== 28-Aug-2023::15:32:55.544317 ===
** State machine e_counter terminating
** Last event = {cast,{message,event,ei_INCR,undefined,
                               #Ref<0.4143019743.798228481.4176>,<0.104.0>}}
** When server state  = {incrCnt,{cntr,1,4}}
** Reason for termination = error:function_clause
** Callback modules = [e_counter]
** Callback mode = state_functions
** Stacktrace =
**  [{e_counter,incrCnt,
                [cast,
                 {message,event,ei_INCR,undefined,
                          #Ref<0.4143019743.798228481.4176>,<0.104.0>},
                 {cntr,1,4}],
                [{file,"src/e_counter.erl"},{line,115}]},
     {gen_statem,loop_state_callback,11,[{file,"gen_statem.erl"},{line,1426}]},
     {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]

How is it that received message is matched the first time and never after that?

0 Answers0