Locks

This section covers using Flower sets for locking. To learn more about sets, see "Sets and inter-process communication in Flower".

When you need to synchronize access to some resource, you utilize one of the mechanism that your platform provides - mutexes, critical sections, monitors etc. However, none of them can be shared across hosts and survive system crash. Flower guarantees portability of the processes and durability of their state, so the locks must also be persistent and distributed. For that, Flower allows to use sets as synchronized resources.

To define a synchronized resource, you need to create a set with message type System.Int32.

createOrUpdateSet({
    at: '/Sets/Shared/MyResource',
    messageType: 'System.Int32'
});


Then, in workflows you can demarcate critical sections by using Lock, Unlock and BeginLock statements. When multiple processes call Lock or BeginLock only one of them continue execution, the rest of them wait until the lock is released.

...
.Lock
(
    _ => new [] { "/Sets/Shared/MyResource" }, // Paths to the resources to
                                               // lock. You can lock multiple
                                               // resources in a single call.
    ctx => ctx.Pid,                            // The owner of the lock.
                                               // This may be any value by
                                               // which the lock owners
                                               // can be distinguished.
    _ => new string[] { ... },                 // The list of owners which can
                                               // share the resource with
                                               // the current owner.
    _ => true,                                 // Whether to wait if the
                                               // resource is locked.
    (_, lockFailures) => { ... }               // This action is executed
                                               // before the activity
                                               // is finished. 
                                               // The lockFailures is the list
                                               // of resources whose locking
                                               // has failed.
)
...

The Lock statement can work in blocking and non-blocking modes. In blocking mode it waits until the lock can be acquired, so the lockFailures list is always empty; in non-blocking mode it executes the result action passing lockFailures for the resources that has not been acquired.

The BeginLock statement has the same signature as Lock, but unlike Lock it opens a scope within which the resources are locked. If the statement is called in non-blocking mode and any of the resources has not been acquired, the control flow jumps over the block. At the end of the scope Unlock is called implicitly.

The Unlock statement releases the lock.

...
.Unlock
(
    _ => new [] { "/Sets/Shared/MyResource" },
    ctx => ctx.Pid
)
...

Last edited Apr 12, 2013 at 6:22 AM by dbratus, version 1

Comments

No comments yet.