Re: ETS: update list value without race condition

Jesper Louis Andersen <[email protected]>
Newsgroups gmane.comp.lang.erlang.general
Message-ID <CAGrdgiUiUfYDpYjU3nEhz+4c_Dd7d5ViZhw9qTKqLL4U=214vA@mail.gmail.com>
In a bag you can have multiple tuples with the same key. So you would store

{123, jane}
{123, john}
{123, bob}
{456, joe}
{456, alice}

When you match on e.g., 123, you get back all tuples matching this, so you
can still get the behavior you want and obtain [jane, john, bob]. However,
now, if one process wants to add {123, adam} and another process wants to
delete {123, jane}, it's possible because the rows are different, even if
they have the same key. As your problem is formulated, this works in your
situation. However, I think your problem might be a bit more involved than
this cooked example in reality, so it might not work.

If you have a low number of updates to the table, I usually just make it
protected and then factor all updates through an owning process. Once
there's a single writer things are usually simpler, but beware that you can
still have interleaved reads so one must think about atomicity in this case.


On Thu, Apr 22, 2021 at 2:08 PM Frank Muller <[email protected]>
wrote:

> Can’t see how the bag type can help with concurrent update Jesper.
>
> I still need a read, update followed by a write.
> Am I wrong?
>
>
>> Another path is to figure out if the ETS type 'bag' is more suitable in
>> your situation.
>>
>> On Thu, Apr 22, 2021 at 1:46 PM Sverker Eriksson <
>> [email protected]> wrote:
>>
>>> It seems ets:select_replace could be your solution.
>>>
>>>
>>>
>>> The documentation contains this example usage to do a compare-and-swap
>>> for a single key:
>>>
>>>
>>>
>>> [Old] = ets:lookup(T, Key),
>>>
>>> New = update_object(Old),
>>>
>>> Success = (1 =:= ets:select_replace(T, [{Old, [], [{const, New}]}])),
>>>
>>>
>>>
>>> /Sverker
>>>
>>>
>>>
>>> *From:* erlang-questions <[email protected]> *On
>>> Behalf Of *Frank Muller
>>> *Sent:* den 22 april 2021 13:32
>>> *To:* Erlang-Questions Questions <[email protected]>
>>> *Subject:* ETS: update list value without race condition
>>>
>>>
>>>
>>> Hi guys
>>>
>>>
>>>
>>> I’ve a little issue I’m unable to solve with the current ETS API.
>>>
>>>
>>>
>>> My table is of type set. Keys are integers and values are list of names:
>>>
>>> 123 -> [ jane, john, bob ]
>>>
>>> 456 -> [ joe, alice ]
>>>
>>> …
>>>
>>>
>>>
>>> Process A with Key=123 wants to delete ‘Jane’ while process B with
>>> Key=123 wants to add ‘Adam’.
>>>
>>>
>>>
>>> First, they both needs to read the value associated with Key=123, update
>>> that list accordingly and set back the new value.
>>>
>>>
>>>
>>> But this lead to race condition (ex. process B could put back ‘jane’ -
>>> last write wins).
>>>
>>>
>>>
>>> Could this problem be solved atomically without involving explicit
>>> locking per Key?
>>>
>>>
>>>
>>> Is there any other better way to represent this data set which will not
>>> suffer from the race condition?
>>>
>>>
>>>
>>> Thanks
>>>
>>> /Frank
>>>
>>
>>
>> --
>> J.
>>
>

-- 
J.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.