Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang unique_integer returns the same integer after restart

Tags:

erlang

mnesia

I need to number my records so that I can always compare what came "later" from what came "before".

For this I used the unique_integer function:

Tag = erlang:unique_integer([monotonic]),

and then I would compare any two events:

Event1.tag < Event2.tag

would mean that Event1 came before Event2.

However, when I restart the erlang node, it starts numbering from the beginning again:

event1  -5555
event2  -5554
event3  -5553

-- restart the system

event4  -5555
event5  -5554
event6  -5553

Now my sorting is not working as intended.

Is there any way to generate long sequential number that picks up where it left off after restarts?

P.S.: If it is useful, I am using mnesia to store my events, and so I need an increasing row number for record.

like image 633
Andriy Drozdyuk Avatar asked Sep 08 '25 18:09

Andriy Drozdyuk


2 Answers

This is the feature I was looking for: mnesia:dirty_update_counter.

Thanks to this excellent post on the matter:

mnesia:dirty_update_counter(unique_ids, record_type, 1), 
io:format("Id => ~p~n", [Id]), 

Id1 = mnesia:dirty_update_counter(unique_ids,record_type, 1), 
io:format( "Id => ~p~n", [Id1]), 

Id2 = mnesia:dirty_update_counter(unique_ids, another_type, 1), 
io:format("Id => ~p~n", [Id2]),

The output you will get is

Id => 1 
Id => 2 
Id => 1

A single table can be used to generate the unique ids for other tables. In this example, unique ids are generated for record_type and another_type. Posted by Dude From Mangalore at 3:19 PM

like image 131
Andriy Drozdyuk Avatar answered Sep 11 '25 09:09

Andriy Drozdyuk


From the documentation:

erlang:unique_integer() -> integer()

Generates and returns an integer unique on current runtime system instance. The same as calling erlang:unique_integer([]).

So what you're seeing is consistent with the defined behavior.


I'm not clear what you need this for, and the correct solution depends on your exact needs. Assuming you have events coming in rapidly and you're planning to use ordered_set to store them in Mnesia by arrival time I can think of a few approaches:

  • Have a single process in charge of inserts. It can initialize with the max ID from the table and increment on each insert.
  • Generate a key with erlang:system_time(nano_seconds) that's unique-ish
  • Generate a key with {erlang:system_time(nano_seconds), make_ref()} to ensure uniqueness even when the timestamps are the same
like image 22
Nathaniel Waisbrot Avatar answered Sep 11 '25 10:09

Nathaniel Waisbrot