Design question: asynchronous API in C++

Discussion in 'C++' started by Marcel Müller, Dec 30, 2010.

  1. I want to provide an asynchronous C++ API. I.e. placing a request will
    not immediately provide a reply. Instead a callback signals the
    availability of the result.

    The classic solution is to provide an interface that must be implemented
    by a class of the caller. This interface contains a method for the
    asynchronous callback.

    Advantage: the implementing classes could also be used to track the
    state of the request. (In this case it is an abstract base class rather
    than an interface.)

    class AsyncBase
    {
    // Notify availability of result.
    virtual void OnCompleteion() = 0;

    // Cancel an outstanding request.
    // Do not call OnCompletion once it returns.
    void Cancel();

    // Fetch the result data (and wait if necessary).
    // If called from OnCompletion() the returned data must not be used
    // after OnCompletion returned.
    // If /not/ called from OnCompletion the lifetime of Result is
    // extended until this class instance dies.
    const Result& ReceiveResult();
    };

    Unfortunately this is very bulky, because the caller has to implement
    one class for each different call. So I would like to have a more
    convenient API.

    The requirements are:
    - 1. The caller places a request, does some other processing and then
    waits for the reply.
    - 2. The caller places a request and gets notified as soon as the reply
    is available.
    - 3. The caller places a request with fire and forget.

    Case 2 is the most important one. Whether the notification function
    already receives the reply as parameters is optional. An additional call
    to a method of the tracking object that is returned when placing the
    request is also fine.

    In fact the returned data could be rather large and a value copy should
    be avoided.


    Has anyone an idea that comes with less effort for the caller? I would
    prefer something with template meta programming and preferably no more
    than two code lines for each call.

    I think that Lambda expressions would help. However, my compiler does
    not support them.


    Marcel
    Marcel Müller, Dec 30, 2010
    #1
    1. Advertising

  2. On 12/30/2010 01:15 PM, Marcel Müller wrote:
    > I want to provide an asynchronous C++ API. I.e. placing a request will
    > not immediately provide a reply. Instead a callback signals the
    > availability of the result.
    >
    > The classic solution is to provide an interface that must be implemented
    > by a class of the caller. This interface contains a method for the
    > asynchronous callback.
    >
    > Advantage: the implementing classes could also be used to track the
    > state of the request. (In this case it is an abstract base class rather
    > than an interface.)
    >
    > class AsyncBase
    > {
    > // Notify availability of result.
    > virtual void OnCompleteion() = 0;
    >
    > // Cancel an outstanding request.
    > // Do not call OnCompletion once it returns.
    > void Cancel();
    >
    > // Fetch the result data (and wait if necessary).
    > // If called from OnCompletion() the returned data must not be used
    > // after OnCompletion returned.
    > // If /not/ called from OnCompletion the lifetime of Result is
    > // extended until this class instance dies.
    > const Result& ReceiveResult();
    > };
    >
    > Unfortunately this is very bulky, because the caller has to implement
    > one class for each different call. So I would like to have a more
    > convenient API.
    >
    > The requirements are:
    > - 1. The caller places a request, does some other processing and then
    > waits for the reply.
    > - 2. The caller places a request and gets notified as soon as the reply
    > is available.
    > - 3. The caller places a request with fire and forget.
    >
    > Case 2 is the most important one. Whether the notification function
    > already receives the reply as parameters is optional. An additional call
    > to a method of the tracking object that is returned when placing the
    > request is also fine.
    >
    > In fact the returned data could be rather large and a value copy should
    > be avoided.
    >
    >
    > Has anyone an idea that comes with less effort for the caller? I would
    > prefer something with template meta programming and preferably no more
    > than two code lines for each call.
    >
    > I think that Lambda expressions would help. However, my compiler does
    > not support them.


    C++0x support async operations and futures, which is what you are trying
    to create.
    Kevin P. Fleming, Dec 30, 2010
    #2
    1. Advertising

  3. Kevin P. Fleming wrote:
    > C++0x support async operations and futures, which is what you are trying
    > to create.


    Fine. But I do not need the implementation of the asynchronous
    processing. In fact that does already exist. I need a language interface
    to the library user. And I need it /without/ C++0x support. So
    std::async and anything related is not an option.


    Marcel
    Marcel Müller, Dec 30, 2010
    #3
  4. On 12/30/2010 02:21 PM, Marcel Müller wrote:
    > Kevin P. Fleming wrote:
    >> C++0x support async operations and futures, which is what you are
    >> trying to create.

    >
    > Fine. But I do not need the implementation of the asynchronous
    > processing. In fact that does already exist. I need a language interface
    > to the library user. And I need it /without/ C++0x support. So
    > std::async and anything related is not an option.


    Well, you mentioned lambdas as a way to simplify this mechanism (which
    is certainly likely to be true), but you'll need C++0x for that and
    "your compiler doesn't support them". That seemed to imply that C++0x
    was a possible way to address your goal :)

    If not, using Boost.Lambda and Boost.Thread would probably be a
    reasonable way to get started.
    Kevin P. Fleming, Dec 31, 2010
    #4
  5. Marcel Müller

    Öö Tiib Guest

    On Dec 30 2010, 9:15 pm, Marcel Müller <>
    wrote:
    > I want to provide an asynchronous C++ API. I.e. placing a request will
    > not immediately provide a reply. Instead a callback signals the
    > availability of the result.
    >
    > The classic solution is to provide an interface that must be implemented
    > by a class of the caller. This interface contains a method for the
    > asynchronous callback.


    The abstract interfaces are simply a way to loosely couple whatever
    that attaches to interface with whatever that provides the interface.
    Specifying such is likely of secondary importance. First design two
    concrete classes that can communicate asynchronously.

    > Advantage: the implementing classes could also be used to track the
    > state of the request. (In this case it is an abstract base class rather
    > than an interface.)
    >
    > class AsyncBase
    > {
    >    // Notify availability of result.
    >    virtual void OnCompleteion() = 0;
    >
    >    // Cancel an outstanding request.
    >    // Do not call OnCompletion once it returns.
    >    void Cancel();
    >
    >    // Fetch the result data (and wait if necessary).
    >    // If called from OnCompletion() the returned data must not be used
    >    // after OnCompletion returned.
    >    // If /not/ called from OnCompletion the lifetime of Result is
    >    // extended until this class instance dies.
    >    const Result& ReceiveResult();
    >
    > };
    >
    > Unfortunately this is very bulky, because the caller has to implement
    > one class for each different call. So I would like to have a more
    > convenient API.


    Usually modern asynchronous requests API consists of up to 6 different
    elements, so it feels that you are oversimplifying the issue.

    >
    > The requirements are:
    > - 1. The caller places a request, does some other processing and then
    > waits for the reply.
    > - 2. The caller places a request and gets notified as soon as the reply
    > is available.
    > - 3. The caller places a request with fire and forget.


    On case of long asynchronous operations there are usually some more
    requirements. One is that lets the client to query about progress with
    that pending request or put up interface where to report progress (mid-
    way completed) notifications. Other is that lets the client to cancel
    (and if needed roll back) pending requests.

    > Case 2 is the most important one. Whether the notification function
    > already receives the reply as parameters is optional. An additional call
    > to a method of the tracking object that is returned when placing the
    > request is also fine.
    >
    > In fact the returned data could be rather large and a value copy should
    > be avoided.
    >
    > Has anyone an idea that comes with less effort for the caller? I would
    > prefer something with template meta programming and preferably no more
    > than two code lines for each call.


    Client of asynchronous API has to provide some interface how to notify
    it and variable or function where to put the results. It can of course
    do it all with making the request.
    Öö Tiib, Jan 1, 2011
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Amir

    asynchronous design

    Amir, Oct 10, 2003, in forum: VHDL
    Replies:
    3
    Views:
    563
  2. dutchgoldtony

    Asynchronous Design

    dutchgoldtony, Apr 23, 2005, in forum: VHDL
    Replies:
    3
    Views:
    482
  3. Adam Skutt
    Replies:
    1
    Views:
    506
    Marcel Müller
    Jan 1, 2011
  4. Adam Skutt
    Replies:
    2
    Views:
    700
    Adam Skutt
    Jan 1, 2011
  5. Scott Sauyet

    API for aggregator of asynchronous calls

    Scott Sauyet, Jun 29, 2010, in forum: Javascript
    Replies:
    7
    Views:
    119
    Scott Sauyet
    Jul 1, 2010
Loading...

Share This Page