Are erlang ref unique between VM nodes / restarts?

The documentation says that

make_ref() -> ref() 

Returns an almost unique link.

The returned link will reappear after approximately two 82 calls; therefore, it is unique enough for practical purposes.

But my eyes tell me that between VM reboots, 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 are Erlangs Refs? Are they suitable for use as a unique "tag" generator when tags are persistent in mq or db and can be generated by various VM sessions.

I know that for this you can use the UUID. It is also well known that pids () are repeatable, reusable, and in no way unique if they are serialized and then loaded from persistent storage.

The question is, is refs () more like UUID or more like pids ()? Are refs () unique between nodes? Between restarts? Is there any official information on this topic?

+7
source share
2 answers

The links associated with the node name do not imply randomness, just uniqueness. As you already noticed, they are created cyclically. In addition, you correctly pointed out that the links are unique only for the lifetime of the node. As soon as you restart the virtual machine, the links can be repeated.

As with PID, #Ref<WXYZ> printed links 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, W for link 0 in the local node, 6793 on the remote.

+7
source

In any distributed system, in order to be able to generate a unique identifier, you need to either rely on a central atomic identifier generator with permanent storage, or ensure that the cluster is properly configured at any given time. We give an example of the second case.

In a distributed cluster, Erlang {node(), now()} can be considered unique. If you can make sure your clock is set correctly and you don’t start two nodes with the same name, you can try using {node(), now(), make_ref()} , which would make the collision insignificant.

+5
source

All Articles