title: How can I know that all Futures are resolved in Tornado?
body: <p>I have some parsing application and it basically do the following</p>
  
  <ul>
  <li>Adds <code>start()</code> method to the IOLoop as a callback to call on the next iteration</li>
  <li><code>start()</code> calls another function, let's call it <code>get_input()</code></li>
  <li><code>get_input()</code> is a coroutine which fetches some data over the net, then schedules another coroutine, <code>process_input()</code>, by adding it as  <code>start()</code> was added in the first step.</li>
  <li><code>get_input()</code> also checks some condition which depends on fetched data and may schedule itself with adjusted arguments</li>
  </ul>
  
  <p>Now, after this condition renders <code>False</code> I know that there won't be any new input items to process. <br>
  But how do I know that there are no Futures of <code>get_input()</code> and <code>process_input()</code> which are still unresolved?</p>
  
  <p>I suppose this could be solved by implementing a kind of counter, which is incremented every time <code>process_input()</code> is called and decrementing after it is resolved<br>
  But if there is a chain of different coroutines? How can I track their state so that if I stop IOLoop, no tasks will die before they get resolved?</p>
  
  <p>Maybe, there should be some kind of hierarchical counting...</p>
  
  <p><em>edit:</em></p>
  
  <p>2 @dano
  OK, I see now... I was inattentive. You really do not block as its own call is inside this list<br>
  But!</p>
  
  <ol>
  <li>Such organization reqires that only <code>yield</code> construction must be used, no <code>add_callback</code> as otherwise we lose "waiting" concept</li>
  <li>The recursion level grows.. Mmm, dunno if it's too bad</li>
  </ol>
  
  <p>What I came up with today is "metafuture"<br>
  I create a bare <code>Future()</code> object. <br>
  I decorate every <code>@coroutine</code>-enabled method with my decorator, which increments counter field in "metafuture" and adds a custom done callback to their futures, that should decrement it.</p>
  
  <p>When it reaches zero, "metafuture" resolves by calling <code>set_result(None)</code>
  THere is also a IOLoop callback that yields exactly that metafuture:</p>
  
  <pre><code>    @coroutine
      def wait_for_complete(self):
        yield self._input_data_collected
        yield self._all_futures_resolved
        self.complete()
  </code></pre>
  
  <p>So after that we know no futures are pending. THat's a hard way like manually implementing refcounting but it covers <code>IOLoop.add_callback()</code> way of adding tasks as well</p>