Benjamin Mahler created MESOS-8448:
--------------------------------------

             Summary: Future::then does not execute continuation if a discard 
was requested.
                 Key: MESOS-8448
                 URL: https://issues.apache.org/jira/browse/MESOS-8448
             Project: Mesos
          Issue Type: Bug
          Components: libprocess
            Reporter: Benjamin Mahler


Currently, Future::then will cut the "chain" short if it sees that a discard 
request is present:

{code}
template <typename T, typename X>
void thenf(lambda::CallableOnce<Future<X>(const T&)>&& f,
           std::unique_ptr<Promise<X>> promise,
           const Future<T>& future)
{
  if (future.isReady()) {
    if (future.hasDiscard()) {
      promise->discard(); // XXX
    } else {
      promise->associate(std::move(f)(future.get()));
    }
  } else if (future.isFailed()) {
    promise->fail(future.failure());
  } else if (future.isDiscarded()) {
    promise->discard();
  }
}
{code}

However, this proves problematic because often the caller needs to control the 
discard semantics. An {{undiscardable}} helper was introduced to prevent 
discards from propagating in altogether, but this still leaves a problematic 
case. Consider the following code from the libevent SSL socket:

{code}
Future<std::shared_ptr<SocketImpl>> LibeventSSLSocketImpl::accept()
{
  return accept_queue.get()
    .then([](const Future<std::shared_ptr<SocketImpl>>& impl)
      -> Future<std::shared_ptr<SocketImpl>> {
      return impl;
    });
}
{code}

Here, we do want the caller to be able to discard if the accept queue get is 
still pending. However, if the queue.get returns a READY future, we need to 
execute the .then continuation otherwise the socket gets dropped on the floor. 
A workaround is to use an explicit promise here with .onAny.

Ideally, there is a way to use .then where it doesn't make this discard 
decision. Either by moving .then to this behavior by default, or considering 
providing a way for the continuation to check for the discard request, or only 
letting the discard propagate when a continuation is asynchronous (i.e. returns 
a future), and leaving all synchronous continuations as undiscardable.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to