{"id":140,"date":"2012-03-25T17:35:53","date_gmt":"2012-03-25T22:35:53","guid":{"rendered":"https:\/\/dalnefre.com\/wp\/?p=140"},"modified":"2016-03-29T15:01:36","modified_gmt":"2016-03-29T20:01:36","slug":"futures-and-capabilities","status":"publish","type":"post","link":"https:\/\/dalnefre.com\/wp\/2012\/03\/futures-and-capabilities\/","title":{"rendered":"Futures and Capabilities"},"content":{"rendered":"<p>In the Actor Model, concurrency is the default.  Sequencing must by arranged explicitly.  An important case of sequencing occurs when there is a data dependency between different parts of a system.  One part produces a value that another part needs to perform its function.<\/p>\n<p \/>\nOne mechanism for sequencing data-dependent operations is to create a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Futures_and_promises\">Future<\/a>.  This is sometimes known as a single-assignment data-flow variable (e.g.: in <a href=\"http:\/\/www.mozart-oz.org\/documentation\/tutorial\/node3.html\">Mozart\/Oz<\/a>) [1].  It is basically a storage cell that can be written to only once, but read from multiple times.  If a read occurs before the write, the read-reply is delayed until the write provides a value.  This effectively suspends readers until the write occurs.  Note, however, that there is no blocking in an actor system.  The asynchronous reply to a read request is simply deferred until a value is available.<\/p>\n<p><a name=\"future\"><\/a><\/p>\n<h2>Future<\/h2>\n<p>When an actor representing a Future is created, its value is unknown.  In this state, it expects either a <code>#read<\/code> or a <code>#write<\/code> request.<\/p>\n<pre>\r\nLET future_beh = \\msg.[\r\n\tCASE msg OF\r\n\t(cust, #write, value) : [\r\n\t\tBECOME value_beh(value)\r\n\t\tSEND SELF TO cust\r\n\t]\r\n\t(cust, #read) : [\r\n\t\tBECOME wait_beh(cust)\r\n\t]\r\n\tEND\r\n]\r\n<\/pre>\n<p>When an actor with <var>future_beh<\/var> receives a <code>#write<\/code> request, it becomes <a href=\"#value\">bound<\/a> to the <var>value<\/var> and sends its <code>SELF<\/code> to the customer <var>cust<\/var>.  This serves as a synchronization signal, indicating that the <var>value<\/var> has been set.<\/p>\n<p \/>\nWhen an actor with <var>future_beh<\/var> receives a <code>#read<\/code> request, it becomes <a href=\"#wait\">waiting<\/a> for the customer <var>cust<\/var>.  Notice that there is <strong>no reply<\/strong> to the customer at this time.<\/p>\n<p><a name=\"value\"><\/a><\/p>\n<h3>Value<\/h3>\n<p>When a Future has been bound to a value, it expects only <code>#read<\/code> requests.  Any other messages (including <code>#write<\/code> requests) are silently ignored.<\/p>\n<pre>\r\nLET value_beh(value) = \\msg.[\r\n\tCASE msg OF\r\n\t(cust, #read) : [\r\n\t\tSEND value TO cust\r\n\t]\r\n\tEND\r\n]\r\n<\/pre>\n<p>When an actor with <var>value_beh<\/var> receives a <code>#read<\/code> request, it simply sends its <var>value<\/var> to the customer <var>cust<\/var>.<\/p>\n<p><a name=\"wait\"><\/a><\/p>\n<h3>Wait<\/h3>\n<p>When a Future receives <code>#read<\/code> requests before a value is provided by a <code>#write<\/code> request, the deferred readers are buffered in the waiting actor.<\/p>\n<pre>\r\nLET wait_beh(waiting) = \\msg.[\r\n\tCASE msg OF\r\n\t(cust, #write, value) : [\r\n\t\tBECOME value_beh(value)\r\n\t\tSEND SELF TO cust\r\n\t\tSEND waiting TO NEW broadcast_beh(value)\r\n\t]\r\n\t(cust, #read) : [\r\n\t\tBECOME wait_beh(cust, waiting)\r\n\t]\r\n\tEND\r\n]\r\n<\/pre>\n<p>When an actor with <var>wait_beh<\/var> receives a <code>#write<\/code> request, it becomes <a href=\"#value\">bound<\/a> to the <var>value<\/var> and sends its <code>SELF<\/code> to the customer <var>cust<\/var>.  Now that a <var>value<\/var> is available, it creates a <a href=\"#broadcast\">broadcast<\/a> actor to send replies to all the <var>waiting<\/var> readers.<\/p>\n<p \/>\nWhen an actor with <var>wait_beh<\/var> receives a <code>#read<\/code> request, it adds the customer <var>cust<\/var> to the list of deferred readers.<\/p>\n<p><a name=\"broadcast\"><\/a><\/p>\n<h3>Broadcast<\/h3>\n<p>A Broadcast actor is created specifically to send a <var>value<\/var> to a list of customers.  A Future uses a Broadcast actor to deliver replies to deferred readers.<\/p>\n<pre>\r\nLET broadcast_beh(value) = \\waiting.[\r\n\tCASE waiting OF\r\n\t(first, rest) : [\r\n\t\tSEND value TO first\r\n\t\tSEND rest TO SELF\r\n\t]\r\n\tlast : [\r\n\t\tSEND value TO last\r\n\t]\r\n\tEND\r\n]\r\n<\/pre>\n<p>An actor with <var>broadcast_beh<\/var> is created with a <var>value<\/var>.  When it receives a <var>waiting<\/var> list, it uses pattern matching to determine if the list is compound, or just a single value.  If the list is compound (a pair), it sends the <var>value<\/var> to the <var>first<\/var> customer, and sends the <var>rest<\/var> of the waiting list back to itself.  If the list is just a single value, it simply sends the <var>value<\/var> to the <var>last<\/var> customer.<\/p>\n<p \/>\nOnce the <var>value<\/var> has been delivered to all the <var>waiting<\/var> customers, there will be no further references to the Broadcast actor, so it can be reclaimed by the garbage-collector.<\/p>\n<p><a name=\"example\"><\/a><\/p>\n<h3>Example<\/h3>\n<p>The following example demonstrates the operation of a Future receiving concurrent <code>#read<\/code> and <code>#write<\/code> requests.  We create two customers, <var>foo<\/var> and <var>bar<\/var>, which simply label any message they receive and send it to the console (via <var>println<\/var>).  These customers are used in two concurrent <code>#read<\/code> requests for the Future <var>var<\/var>.  A concurrent <code>#write<\/code> request sets the value of the Future to <code>42<\/code>.  The customer for the <code>#write<\/code> request is <var>sink<\/var> (which ignores all messages) because, in this case, we don&#8217;t care about when the value is set.<\/p>\n<pre>\r\nCREATE var WITH future_beh\r\nCREATE foo WITH \\msg.[ SEND (#foo, msg) TO println ]\r\nCREATE bar WITH \\msg.[ SEND (#bar, msg) TO println ]\r\nSEND (foo, #read) TO var\r\nSEND (bar, #read) TO var\r\nSEND (sink, #write, 42) TO var\r\n<\/pre>\n<p>Since the <code>#read<\/code> and <code>#write<\/code> requests are issued concurrently, the Future <var>var<\/var> will receive them in a non-deterministic order.  The <code>#write<\/code> request could arrive first, in which case the <code>#read<\/code> requests will be satisfied immediately.  The <code>#read<\/code> requests could both arrive before the <code>#write<\/code>, in which case the read-replies will be deferred until the value is set by <code>#write<\/code>.  Or, the <code>#write<\/code> request could arrive between the two <code>#read<\/code> requests, as shown in Figure 1.<\/p>\n<div id=\"attachment_146\" style=\"width: 517px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/dalnefre.com\/wp\/2012\/03\/futures-and-capabilities\/futures-fig1\/\" rel=\"attachment wp-att-146\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-146\" src=\"https:\/\/dalnefre.com\/wp\/wp-content\/uploads\/2012\/03\/futures-fig1.png\" alt=\"\" title=\"Future Message Flow\" width=\"507\" height=\"400\" class=\"size-full wp-image-146\" srcset=\"https:\/\/dalnefre.com\/wp\/wp-content\/uploads\/2012\/03\/futures-fig1.png 507w, https:\/\/dalnefre.com\/wp\/wp-content\/uploads\/2012\/03\/futures-fig1-150x118.png 150w, https:\/\/dalnefre.com\/wp\/wp-content\/uploads\/2012\/03\/futures-fig1-300x236.png 300w\" sizes=\"auto, (max-width: 507px) 100vw, 507px\" \/><\/a><p id=\"caption-attachment-146\" class=\"wp-caption-text\">Figure 1 - Future Message Flow<\/p><\/div>\n<p><a name=\"capability\"><\/a><\/p>\n<h2>Capability<\/h2>\n<p>Access to a Future, as described <a href=\"#future\">above<\/a>, implies the capability [2] to <code>#read<\/code> or <code>#write<\/code> its value.  In many cases we would like to separate those capabilities.  We may want to give read-only access to several potential consumers, while reserving write access for the producer.  One powerful feature of pure-actor systems is that Actors act as <a href=\"http:\/\/www.erights.org\/elib\/capability\/overview.html\">security capabilities<\/a>.  In order to attenuate the capability of a client, we simply create a <a href=\"http:\/\/c2.com\/cgi\/wiki?ProxyPattern\">proxy<\/a> actor that enforces our desired security policy.<\/p>\n<pre>\r\nLET read_only_beh(future) = \\msg.[\r\n\tCASE msg OF\r\n\t(cust, #read) : [\r\n\t\tSEND msg TO future\r\n\t]\r\n\tEND\r\n]\r\nCREATE ro_var WITH read_only_beh(var)\r\n<\/pre>\n<p>An actor with <var>read_only_beh<\/var> is created with a reference to a <var>future<\/var>.  When a <code>#read<\/code> request is received, the message is forwarded to the <var>future<\/var>.  All other messages are silently ignored.<\/p>\n<p \/>\nSimilarly, we might want to create a proxy that provides only write capability.  This is slightly more complicated due to the write synchronization signal.  The Future responds to a <code>#write<\/code> request by sending its <code>SELF<\/code> back to the customer.  Our proxy must intercept this response and substitute its own identity to maintain encapsulation of the future.<\/p>\n<pre>\r\nLET write_sync_beh(cust, msg) = \\_.[ SEND msg TO cust ]\r\nLET write_only_beh(future) = \\msg.[\r\n\tCASE msg OF\r\n\t(cust, #write, value) : [\r\n\t\tSEND (k_write, #write, value) TO future\r\n\t\tCREATE k_write WITH write_sync_beh(cust, SELF)\r\n\t]\r\n\tEND\r\n]\r\nCREATE wo_var WITH write_only_beh(var)\r\n<\/pre>\n<p>When an actor with <var>write_only_beh<\/var> receives a <code>#write<\/code> request, it sends a <code>#write<\/code> request to the <var>future<\/var>, providing a customer <var>k_write<\/var> with <var>write_sync_beh<\/var>.  When the future responds, <var>k_write<\/var> sends the identity of the proxy to the original customer <var>cust<\/var>.<\/p>\n<p><a name=\"race\"><\/a><\/p>\n<h3>Race<\/h3>\n<p>Sometimes it is useful to arrange a race among multiple producers.  You may have multiple algorithms competing to provide a result.  Different algorithms may win under different circumstances.  The first one to determine a result will <code>#write<\/code> to the Future.  Subsequent results are ignored.  In this case, the write synchronization signal is unimportant, so we change the protocol to expect a <code>#result<\/code> message with no customer.  This behavior acts like an <a href=\"http:\/\/c2.com\/cgi\/wiki?AdapterPattern\">adapter<\/a> between the racers (sending <code>#result<\/code> messages, expecting no reply) and the future (expecting <code>#write<\/code> requests and sending a synchronization reply).<\/p>\n<pre>\r\nLET result_race_beh(future) = \\msg.[\r\n\tCASE msg OF\r\n\t(#result, value) : [\r\n\t\tSEND (SELF, #write, value) TO future\r\n\t\tBECOME \\_.[]\r\n\t]\r\n\tEND\r\n]\r\n<\/pre>\n<p>When an actor with <var>result_race_beh<\/var> receives a <code>#result<\/code> message, it sends a <code>#write<\/code> request to the <var>future<\/var> with the result <var>value<\/var> and its <code>SELF<\/code> as the customer.  Then it becomes a behavior that ignores all subsequent messages.  Note that this serves two purposes; to ignore any other race results, and to throw away the write synchronization signal.<\/p>\n<p><a name=\"summary\"><\/a><\/p>\n<h2>Summary<\/h2>\n<p>Futures are a fundamental synchronization mechanism in concurrent systems.  We have shown how futures work through an actor-based description, illustrating the events that transition a Future through its life-cycle.  Building on that foundation, we have demonstrated how, following the <a href=\"http:\/\/c2.com\/cgi\/wiki?ObjectCapabilityModel\">Object Capability Model<\/a>, we can exercise fine-grained control over access to the Future.  This is extended to the case of arranging a race among concurrent speculative computations.<\/p>\n<p><a name=\"references\"><\/a><\/p>\n<h2>References<\/h2>\n<dl>\n<dt>[1]<\/dt>\n<dd>P. Van Roy, S. Haridi. <a href=\"http:\/\/www.info.ucl.ac.be\/~pvr\/book.html\"><em>Concepts, Techniques, and Models of Computer Programming<\/em><\/a>. MIT Press, 2004.<\/dd>\n<dt>[2]<\/dt>\n<dd>J. Dennis, E. Van Horn.  <a href=\"http:\/\/citeseerx.ist.psu.edu\/viewdoc\/summary?doi=10.1.1.16.9948\">Programming Semantics for Multiprogrammed Computations<\/a>. ACM Conference on Programming Languages and Pragmatics, San Dimas, CA, August, 1965.<\/dd>\n<\/dl>\n","protected":false},"excerpt":{"rendered":"<p>In the Actor Model, concurrency is the default. Sequencing must by arranged explicitly. An important case of sequencing occurs when there is a data dependency between different parts of a system. One part produces a value that another part needs to perform its function. One mechanism for sequencing data-dependent operations is to create a Future. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[4,84,26,16,49,23,12,15,79,80,81,17,83,82,24,30,19],"class_list":["post-140","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-actor","tag-adapter","tag-asynchronous","tag-blocking","tag-capability","tag-concurrency","tag-data-flow","tag-deadlock","tag-dependency","tag-future","tag-promise","tag-protocol","tag-proxy","tag-security","tag-sequence","tag-synchronization","tag-value"],"_links":{"self":[{"href":"https:\/\/dalnefre.com\/wp\/wp-json\/wp\/v2\/posts\/140","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dalnefre.com\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dalnefre.com\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dalnefre.com\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dalnefre.com\/wp\/wp-json\/wp\/v2\/comments?post=140"}],"version-history":[{"count":0,"href":"https:\/\/dalnefre.com\/wp\/wp-json\/wp\/v2\/posts\/140\/revisions"}],"wp:attachment":[{"href":"https:\/\/dalnefre.com\/wp\/wp-json\/wp\/v2\/media?parent=140"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dalnefre.com\/wp\/wp-json\/wp\/v2\/categories?post=140"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dalnefre.com\/wp\/wp-json\/wp\/v2\/tags?post=140"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}