Hello pals!
I’ve been playing about with the global
module, and I don’t understand what the rules are for when a process can set a lock.
Here’s what the documentation says:
If a lock already exists on
ResourceId
for another requester thanLockRequesterId
, andRetries
is not equal to0
, the process sleeps for a while and tries to execute the action later. WhenRetries
attempts have been made,false
is returned, otherwisetrue
. IfRetries
isinfinity
,true
is eventually returned (unless the lock is never released).
Here’s my test program:
#!/usr/bin/env escript
-module(lock_ness).
main(_) ->
% Spawn multiple processes, each try to get the same lock but with a
% different requester id.
spawn(fun get_lock/0),
spawn(fun get_lock/0),
spawn(fun get_lock/0),
% Let the program run.
timer:sleep(1000).
get_lock() ->
Nodes = [node()],
% Only try once so we can immediately see the result
Retries = 1,
% type global:id() :: {ResourceId :: term(), LockRequesterId :: term()}.
ResourceId = my_lock,
LockRequesterId = self(),
Id = {ResourceId, LockRequesterId},
% -spec set_lock(Id, Nodes, Retries) -> boolean()
DidGetLock = global:set_lock(Id, Nodes, Retries),
erlang:display({self(), DidGetLock}).
My expectation was that with with 3 different processes, 3 different LockRequesterIds, and 1 ResourceId the first would successfully set the lock, while the later 2 would not be able to. However, when I run the program it seems all 3 successfully set the lock:
$ escript lock_ness.escript
{<0.83.0>,true}
{<0.84.0>,true}
{<0.85.0>,true}
The documentation later says this:
The global name server keeps track of all processes sharing the same lock, that is, if two processes set the same lock, both processes must delete the lock.
I took this to mean that two processes using the same LockRequesterIds would be able to acquire the same lock, but with different LockRequesterIds they would not be able to.
What’s my misunderstanding here? Under what circumstances does global:set_lock/3
return false
?
Thanks,
Louis