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)