{"_id":"58e6b38785ec873100be9393","user":"5612c290c0731b0d00625078","parentDoc":null,"category":{"_id":"58e6b68eb1eece19008b81fe","project":"5612c2a00fbdb60d00e4c7d1","version":"5612c2a00fbdb60d00e4c7d4","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2017-04-06T21:43:42.570Z","from_sync":false,"order":1,"slug":"api","title":"Lasp"},"project":"5612c2a00fbdb60d00e4c7d1","version":{"_id":"5612c2a00fbdb60d00e4c7d4","__v":7,"project":"5612c2a00fbdb60d00e4c7d1","createdAt":"2015-10-05T18:34:08.611Z","releaseDate":"2015-10-05T18:34:08.611Z","categories":["5612c2a10fbdb60d00e4c7d5","58e6b64bc397de1b00173c09","58e6b68eb1eece19008b81fe","58e6b6d185ec873100be9734","58f5e5c2616bbb1b00d54c15","58f5eaa74c413f19007a2858","58f767a79c723f19004e1ca9"],"is_deprecated":false,"is_hidden":false,"is_beta":true,"is_stable":true,"codename":"","version_clean":"0.0.1","version":"0.0.1"},"__v":1,"updates":["58f10fa36a9fad2f00f6fd78"],"next":{"pages":[],"description":""},"createdAt":"2017-04-06T21:30:47.384Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":5,"body":"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`.\n\nLet's play around with a counter to see how we can do this.\n\nFirst, we declare a new counter.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"> {ok, _} = lasp:declare({\\\"<<counter>>\\\", state_gcounter}, state_gcounter). \\n{ok,{{\\\"<<counter>>\\\",state_gcounter},\\n     state_gcounter,\\n     [{clock,[{<<170,227,142,126,63,64,19,227,195,66,39,125,58,\\n                 195,75,134,148,109,168,...>>,\\n               1}]}],\\n     {state_gcounter,[]}}}\",\n      \"language\": \"erlang\"\n    }\n  ]\n}\n[/block]\nThen, 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.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"> spawn(fun() -> \\n          lasp:read({\\\"<<counter>>\\\", state_gcounter}, {value, 50}), \\n          io:format(\\\"50 reached!\\\") \\n        end).\",\n      \"language\": \"erlang\"\n    }\n  ]\n}\n[/block]\nFinally, let's update the variable to reach `50`!\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"> lists:foreach(fun(_) -> \\n                  lasp:update({\\\"<<counter>>\\\", state_gcounter}, increment, self())\\n                end, lists:seq(1,100)).\\n50 reached!>\",\n      \"language\": \"erlang\"\n    }\n  ]\n}\n[/block]\nEach type of threshold is *data type specific*: the condition itself must be monotonic for it to operate in the synchronization-free distributed environment.  \n\nTo give you an idea of some of the types of thresholds that are possible, think about operations that once true, stay true.\n\n* Grow-only counters: is the value at some minimum?\n* Grow-only sets: has the value reached a particular size?  Does the set contain some element?\n* Session guarantees: provide the previous value that was read to ensure you only read values from the future.","excerpt":"How can I enforce that I read a particular value?","slug":"monotonic-read","type":"basic","title":"Monotonic Read"}

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. [block:code] { "codes": [ { "code": "> {ok, _} = lasp:declare({\"<<counter>>\", state_gcounter}, state_gcounter). \n{ok,{{\"<<counter>>\",state_gcounter},\n state_gcounter,\n [{clock,[{<<170,227,142,126,63,64,19,227,195,66,39,125,58,\n 195,75,134,148,109,168,...>>,\n 1}]}],\n {state_gcounter,[]}}}", "language": "erlang" } ] } [/block] 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. [block:code] { "codes": [ { "code": "> spawn(fun() -> \n lasp:read({\"<<counter>>\", state_gcounter}, {value, 50}), \n io:format(\"50 reached!\") \n end).", "language": "erlang" } ] } [/block] Finally, let's update the variable to reach `50`! [block:code] { "codes": [ { "code": "> lists:foreach(fun(_) -> \n lasp:update({\"<<counter>>\", state_gcounter}, increment, self())\n end, lists:seq(1,100)).\n50 reached!>", "language": "erlang" } ] } [/block] 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.