title: How to get the result of a future in a callback?
body: <p>The <code>add_done_callback</code> method was recently added to the distributed <code>Future</code> object which allows you to take some action after the future finishes, irrespective of whether it succeeded or not.</p>
  
  <p><a href="http://distributed.readthedocs.io/en/latest/api.html?highlight=add_done_callback#distributed.client.Future.add_done_callback" rel="nofollow noreferrer">http://distributed.readthedocs.io/en/latest/api.html?highlight=add_done_callback#distributed.client.Future.add_done_callback</a></p>
  
  <p>The callback function will hang if you try to directly call any of the methods <code>result</code>, <code>exception</code> or <code>traceback</code> on the passed future object.</p>
  
  <p>The exception and traceback can however be accessed in the callback as follows:
  <code>fut._exception().result()</code>
  <code>fut._traceback().result()</code></p>
  
  <p>Trying the same pattern with the result - i.e. <code>fut._result().result()</code> raises an exception:</p>
  
  <pre><code>  File "C:\Python\lib\site-packages\tornado\concurrent.py", line 316, in _check_done
      raise Exception("DummyFuture does not support blocking for results")
  Exception: DummyFuture does not support blocking for results
  </code></pre>
  
  <p>Without being able to access the result of the future in the callback, being able to add a callback is of limited use to me.</p>
  
  <p>Am I missing something - <em>is</em> there a way to get the result of the future in the callback?</p>
  
  <p>In the asyncio documentation it seems to give an example where accessing the <code>result</code> method directly is possible:</p>
  
  <p><a href="https://docs.python.org/3/library/asyncio-task.html#example-future-with-run-forever" rel="nofollow noreferrer">https://docs.python.org/3/library/asyncio-task.html#example-future-with-run-forever</a></p>
  
  <p>...I'm not sure how this related to tornado/distributed, but it would be <em>very</em> useful to be able to do the same.</p>
  
  <pre class="lang-py prettyprint-override"><code>from distributed import Client
  
  
  client = Client("127.0.0.1:8786")
  
  def f(delay):
      from time import sleep
      from numpy.random import randn
      sleep(delay)
      if randn() &gt; 1:
          1/0
      return delay
  
  def callback(fut):
      import logging
      logger = logging.getLogger('distributed')
      if fut.status == 'finished':
          res = future._result().result()  # &lt;-------------- Doesn't work!
          logger.info("{!r} - {!s}".format(fut, res))
      else:
          logger.info("{!r} - {!s}".format(fut, fut.status))
  
  
  args = rand(10)
  futs = client.map(f, args)
  for fut in futs:
      fut.add_done_callback(callback)
  </code></pre>