Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are erlang refs unique between nodes/VM restarts?

Tags:

uuid

ref

erlang

Documentation says that

make_ref() -> ref()  

Returns an almost unique reference.

The returned reference will re-occur after approximately 282 calls; therefore it is unique enough for practical purposes.

But my eyes tell me that between VM restarts I could easily get the same ref:

[~] erl
Erlang R14B04 (erts-5.8.5)
1> make_ref().
#Ref<0.0.0.33>
2> make_ref().
#Ref<0.0.0.37>
^C

[~] erl
Erlang R14B04 (erts-5.8.5)
1> make_ref().
#Ref<0.0.0.33>

So, how unique Erlang’s Refs are? Are they suitable to be used as an unique “tag” generator when tags are persistent in mq or db and may be generated by different VM sessions.

I know UUIDs could be used for this. It’s also well known that pids() are repeatable, reusable and by no means unique if serialized and then loaded from persistent storage.

Question is, what are refs() — more like UUIDs or more like pids()? Are refs() unique between nodes? Between restarts? Is there any official info on this topic?

like image 718
Niki Tonsky Avatar asked Apr 05 '12 13:04

Niki Tonsky


1 Answers

References, which are related to the name of a node, do not imply randomness, just uniqueness. As you've already noticed, they're created in a cyclic way. Also, you're correct on the fact references are unique only for the life span of a node. Once, you restart the VM, references can be repeated.

As in the case of PIDs, printed references #Ref<W.X.Y.Z> contain - as their first element (W) - information about the node number:

erl -sname right
Erlang R15B (erts-5.9) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9  (abort with ^G)
(right@mars)1> register(right, self()).
true
(right@mars)2> receive M -> M end.
#Ref<6793.0.0.41>
(right@mars)3> 

erl -sname left
Erlang R15B (erts-5.9) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9  (abort with ^G)
(left@mars)1> {right, 'right@mars'} ! make_ref().
#Ref<0.0.0.41>
(left@mars)2> 

Notice how in this case the W for the reference is 0 in the local node, 6793 in the remote one.

like image 172
Roberto Aloi Avatar answered Sep 20 '22 22:09

Roberto Aloi