Uploaded image for project: 'Mesos'
  1. Mesos
  2. MESOS-8448

Future::then does not execute continuation if a discard was requested.

    XMLWordPrintableJSON

Details

    • Story
    • Status: Open
    • Major
    • Resolution: Unresolved
    • None
    • None
    • libprocess

    Description

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

      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();
        }
      }
      

      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:

      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;
          });
      }
      

      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.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              bmahler Benjamin Mahler
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated: