Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang ETS insert/2 error

I am trying to create a simple Erlang process with the access to ETS module.

My source code includes:

  1. Process creation:

    start_message_channel() ->
        Table = ets:new(messages, [ordered_set, named_table]),
        Channel = spawn(?MODULE, channel, []),
        {Channel, {table, Table}}.
    
  2. Process logic:

    channel() ->
        receive
            {Sender, {send_message, {Message, Table}}} ->
                ets:insert(Table, {message, Message}),
                Sender ! {self(), {status, success}};
            {Sender, {receive_message, Table}} ->
                {message, Message} = ets:first(Table),
                Sender ! {self(), {status, {success, Message}}};
            _ ->
                throw(incorrect_protocol_exception)
    end.
    
  3. Communication with process

    send_message_to_message_channel({Channel, {table, Table}}, Message) ->
        Channel ! {self(), {send_message, {Message, Table}}},
        receive
            {Channel, {status, success}} ->
                io:format("Message sent!~n");
            {Channel, {status, failure}} ->
                io:format("Message failed to send!~n");
            _ ->
                throw(incorrect_protocol_exception)
    end.
    
    receive_message_from_message_channel({Channel, {table, Table}}) ->
        Channel ! {self(), {receive_message, Table}},
        receive
            {Channel, {status, {success, Message}}} ->
                io:format(Message);
            {Channel, {status, failure}} ->
                io:format("Message failed to receive!~n");
            _ ->
                throw(incorrect_protocol_exception)
    end.
    

While executing function calls in Erlang terminal, I am getting error:

    1> cd("C:/Users/dauma").                    
    C:/Users/dauma
    ok
    2> c(message_channel).
    {ok,message_channel}
    3> Object = message_channel:start_message_channel().
    {<0.59.0>,{table,messages}}
    4> message_channel:send_message_to_message_channel(Object, "Hello World!").

    =ERROR REPORT==== 19-May-2016::11:09:27 ===
    Error in process <0.59.0> with exit value:
    {badarg,[{ets,insert,[messages,"Hello World!"],[]},
        {message_channel,channel,0,
            [{file,"message_channel.erl"},{line,35}]}]}

Could anyone tell me, where might be the problem?

like image 824
Daumantas Versockas Avatar asked Dec 19 '22 16:12

Daumantas Versockas


1 Answers

ETS tables are owned by an Erlang process, and have access controls. By default the table is protected and can only be written to by the process that owns it, though it can be read from other processes.

If you want to read and write from a different process, use public.

Table = ets:new(messages, [ordered_set, named_table, public])

You can also use private, which means that only the owning process can read and write.

Per the documentation:

  • public Any process may read or write to the table.
  • protected The owner process can read and write to the table. Other processes can only read the table. This is the default setting for the access rights.
  • private Only the owner process can read or write to the table.

In your example, you create the table in one process (the one calling start_message_channel), and then you attempt to call ets:insert from a different process: spawn(?MODULE, channel, []) creates a new process, with channel as its entry point.

Because your table is not marked as public, the call to ets:insert from the other process fails with badarg.

Per the documentation, again:

In general, the functions below will exit with reason badarg if any argument is of the wrong format, if the table identifier is invalid or if the operation is denied due to table access rights (protected or private).


Side note: if you use named_table, the value returned from ets:new is the table name, so you can do this:

-define(TABLE, messages).

% later...
?TABLE = ets:new(?TABLE, [named_table, ordered_set, protected])

...and you don't need to store the returned value in state.

like image 191
Roger Lipscombe Avatar answered Jan 01 '23 17:01

Roger Lipscombe