Monotonic Read

How can I enforce that I read a particular value?

However, when reading variables, many times you don't want to read a value until it reaches a particular point. For instance, only return the value of a counter once the number is greater than 2.

Let's play around with a counter to see how we can do this.

First, we declare a new counter.

> {ok, _} = lasp:declare({"<<counter>>", state_gcounter}, state_gcounter). 
{ok,{{"<<counter>>",state_gcounter},
     state_gcounter,
     [{clock,[{<<170,227,142,126,63,64,19,227,195,66,39,125,58,
                 195,75,134,148,109,168,...>>,
               1}]}],
     {state_gcounter,[]}}}

Then, let's start a read procedure, giving it a threshold on the value. Since the read operation will block, we start it in its own process.

> spawn(fun() -> 
          lasp:read({"<<counter>>", state_gcounter}, {value, 50}), 
          io:format("50 reached!") 
        end).

Finally, let's update the variable to reach 50!

> lists:foreach(fun(_) -> 
                  lasp:update({"<<counter>>", state_gcounter}, increment, self())
                end, lists:seq(1,100)).
50 reached!>

Each type of threshold is data type specific: the condition itself must be monotonic for it to operate in the synchronization-free distributed environment.

To give you an idea of some of the types of thresholds that are possible, think about operations that once true, stay true.

  • Grow-only counters: is the value at some minimum?
  • Grow-only sets: has the value reached a particular size? Does the set contain some element?
  • Session guarantees: provide the previous value that was read to ensure you only read values from the future.