How to make your RPCs more responsive in Autobahn|Cpp?

#1

Hi all,

I have a callee C++ program that runs on a single thread and does computation (nothing related to DB) who takes at least 30 seconds each and I would like it to handle simultaneous calls (from callers).

For avoiding my (single-threaded) WAMP component to be unresponsive from the outside (to Crossbar router and the other callers) while the callee code is “busy” sitting and waiting for the call to return, I read in this newsgroup that boost::future and boost::promise could be used for that.

I have seen Autobahn|JS can defer and then resolve the results when they’re ready but there are very few explanations (and examples) on how to implement all this in Autobahn|Cpp. I’m wondering if someone has ever “cooked” something to provide asynchronous support to RPCs.

0 Likes

#2

Hi François,

As far as I know, there are three “types” of endpoint in Autobahn|Cpp (it starts here: https://github.com/tavendo/AutobahnCpp/blob/master/autobahn/autobahn_impl.hpp#L703)

  1. You return a definite result.

  2. You return multiple results.

  3. You return a future (async) containing multiple results. (endpoint_fvm_t)

The endpoint_fvm_t type is defined as the following: https://github.com/tavendo/AutobahnCpp/blob/master/autobahn/autobahn.hpp#L107

Which means all you need to have is to return a boost::future from your function.

Next, you just need to use the boost::future object in your computation logic.

Hope it helps you!

Kind regards,

Raito Bezarius.

···

Le mercredi 6 mai 2015 21:32:27 UTC+2, François Guertin a écrit :

Hi all,

I have a callee C++ program that runs on a single thread and does computation (nothing related to DB) who takes at least 30 seconds each and I would like it to handle simultaneous calls (from callers).

For avoiding my (single-threaded) WAMP component to be unresponsive from the outside (to Crossbar router and the other callers) while the callee code is “busy” sitting and waiting for the call to return, I read in this newsgroup that boost::future and boost::promise could be used for that.

I have seen Autobahn|JS can defer and then resolve the results when they’re ready but there are very few explanations (and examples) on how to implement all this in Autobahn|Cpp. I’m wondering if someone has ever “cooked” something to provide asynchronous support to RPCs.

0 Likes

#3

Hi Raito,

First, I want to thank you for help.

I have followed your guidelines about returning a boost::future from my function but I get this compilation error.

11:14:45 **** Incremental Build of configuration Debug for project ARTS-coreVhf ****
make all
Building file: …/src/main.cpp
Invoking: GCC C++ Compiler
g++ -std=c++11 -I/home/fguertin/boost_1_56_0-x86 -I/home/fguertin/AutobahnCpp/autobahn -O2 -g3 -pedantic -w -Wall -c -fmessage-length=0 -Wunused-local-typedefs -MMD -MP -MF"src/main.d" -MT"src/main.d" -o “src/main.o” “…/src/main.cpp”
In file included from /home/fguertin/AutobahnCpp/autobahn/autobahn.hpp:41:0,
from …/src/main.cpp:18:
/home/fguertin/boost_1_56_0-x86/boost/any.hpp: In instantiation of ‘boost::any::holder::holder(const ValueType&) [with ValueType = boost::futureboost::any]’:
/home/fguertin/boost_1_56_0-x86/boost/any.hpp:199:39: required from ‘boost::any::placeholder* boost::any::holder::clone() const [with ValueType = boost::futureboost::any]’
…/src/main.cpp:749:1: required from here
/home/fguertin/boost_1_56_0-x86/boost/any.hpp:180:27: error: use of deleted function ‘boost::future::future(const boost::future&) [with R = boost::any]’
: held(value)
^
In file included from /home/fguertin/boost_1_56_0-x86/boost/thread/detail/move.hpp:26:0,
from /home/fguertin/boost_1_56_0-x86/boost/thread/exceptional_ptr.hpp:9,
from /home/fguertin/boost_1_56_0-x86/boost/thread/future.hpp:20,
from /home/fguertin/AutobahnCpp/autobahn/autobahn.hpp:38,
from …/src/main.cpp:18:
/home/fguertin/boost_1_56_0-x86/boost/thread/future.hpp:72:29: error: declared here
#define BOOST_THREAD_FUTURE future
^
/home/fguertin/boost_1_56_0-x86/boost/thread/detail/delete.hpp:21:7: note: in definition of macro ‘BOOST_THREAD_DELETE_COPY_CTOR’
CLASS(CLASS const&) = delete;
^
/home/fguertin/boost_1_56_0-x86/boost/thread/detail/move.hpp:240:3: note: in expansion of macro ‘BOOST_THREAD_NO_COPYABLE’
BOOST_THREAD_NO_COPYABLE(TYPE)
^
/home/fguertin/boost_1_56_0-x86/boost/thread/future.hpp:1574:9: note: in expansion of macro ‘BOOST_THREAD_MOVABLE_ONLY’
BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
^
/home/fguertin/boost_1_56_0-x86/boost/thread/future.hpp:1574:35: note: in expansion of macro ‘BOOST_THREAD_FUTURE’
BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
^
make: *** [src/main.o] Error 1

11:14:54 Build Finished (took 9s.213ms)

``

I can’t figure out why I get a “use of deleted function” error. Here is my implementation.

int DoSomethingLong(int val);

void asyncFun(promise & anyPromise, int & val)
{
int result;

try
{
    // Do your long calculation here
    result = DoSomethingLong(val);

    // Set promise value
    anyPromise.set_value(result);
}
catch (std::exception& e)
{
    anyPromise.set_exception(std::copy_exception(e));
}

}

// Define procedure to be called remotely
future testFutureAny(const anyvec& args, const anymap& kwargs)
{
promise anyPromise;
future anyFuture = anyPromise.get_future();
int intVal = 123;

std::thread t(std::bind(asyncFun, std::ref(anyPromise), std::ref(intVal)));

return anyFuture;

}

``

// Register procedure for remote call
auto r1 = session->provide(“com.example.test_future_any”, &testFutureAny);
r1.then([&](future reg)
{
cout << “Procedure test_future_any registered.” << endl;
}).wait();

``

Any help would be appreciated.

Regards,

François,

···

On Sunday, May 10, 2015 at 1:52:11 PM UTC-4, Raito Bezarius wrote:

Hi François,

As far as I know, there are three “types” of endpoint in Autobahn|Cpp (it starts here: https://github.com/tavendo/AutobahnCpp/blob/master/autobahn/autobahn_impl.hpp#L703)

  1. You return a definite result.
  1. You return multiple results.
  1. You return a future (async) containing multiple results. (endpoint_fvm_t)

The endpoint_fvm_t type is defined as the following: https://github.com/tavendo/AutobahnCpp/blob/master/autobahn/autobahn.hpp#L107

Which means all you need to have is to return a boost::future from your function.

Next, you just need to use the boost::future object in your computation logic.

Hope it helps you!

Kind regards,

Raito Bezarius.

Le mercredi 6 mai 2015 21:32:27 UTC+2, François Guertin a écrit :

Hi all,

I have a callee C++ program that runs on a single thread and does computation (nothing related to DB) who takes at least 30 seconds each and I would like it to handle simultaneous calls (from callers).

For avoiding my (single-threaded) WAMP component to be unresponsive from the outside (to Crossbar router and the other callers) while the callee code is “busy” sitting and waiting for the call to return, I read in this newsgroup that boost::future and boost::promise could be used for that.

I have seen Autobahn|JS can defer and then resolve the results when they’re ready but there are very few explanations (and examples) on how to implement all this in Autobahn|Cpp. I’m wondering if someone has ever “cooked” something to provide asynchronous support to RPCs.

0 Likes

#4

Hi François,

I’m not sure of it, but I think that it’s this:

r1.then([&](future<registration> reg)

You should try to pass the future by reference because futures are not copyable.
Else, the second possibility is :

future<any> anyFuture = anyPromise.get_future();

You should try to pass it by reference too I think, but I don’t see mention of a deleted assignation operator…
Hope it helps you!

Kind regards,
Raito Bezarius.

···

Le lundi 11 mai 2015 17:47:49 UTC+2, François Guertin a écrit :

Hi Raito,

First, I want to thank you for help.

I have followed your guidelines about returning a boost::future from my function but I get this compilation error.

11:14:45 **** Incremental Build of configuration Debug for project ARTS-coreVhf ****
make all
Building file: …/src/main.cpp
Invoking: GCC C++ Compiler
g++ -std=c++11 -I/home/fguertin/boost_1_56_0-x86 -I/home/fguertin/AutobahnCpp/autobahn -O2 -g3 -pedantic -w -Wall -c -fmessage-length=0 -Wunused-local-typedefs -MMD -MP -MF"src/main.d" -MT"src/main.d" -o “src/main.o” “…/src/main.cpp”
In file included from /home/fguertin/AutobahnCpp/autobahn/autobahn.hpp:41:0,
from …/src/main.cpp:18:
/home/fguertin/boost_1_56_0-x86/boost/any.hpp: In instantiation of ‘boost::any::holder::holder(const ValueType&) [with ValueType = boost::futureboost::any]’:
/home/fguertin/boost_1_56_0-x86/boost/any.hpp:199:39: required from ‘boost::any::placeholder* boost::any::holder::clone() const [with ValueType = boost::futureboost::any]’
…/src/main.cpp:749:1: required from here
/home/fguertin/boost_1_56_0-x86/boost/any.hpp:180:27: error: use of deleted function ‘boost::future::future(const boost::future&) [with R = boost::any]’
: held(value)
^
In file included from /home/fguertin/boost_1_56_0-x86/boost/thread/detail/move.hpp:26:0,
from /home/fguertin/boost_1_56_0-x86/boost/thread/exceptional_ptr.hpp:9,
from /home/fguertin/boost_1_56_0-x86/boost/thread/future.hpp:20,
from /home/fguertin/AutobahnCpp/autobahn/autobahn.hpp:38,
from …/src/main.cpp:18:
/home/fguertin/boost_1_56_0-x86/boost/thread/future.hpp:72:29: error: declared here
#define BOOST_THREAD_FUTURE future
^
/home/fguertin/boost_1_56_0-x86/boost/thread/detail/delete.hpp:21:7: note: in definition of macro ‘BOOST_THREAD_DELETE_COPY_CTOR’
CLASS(CLASS const&) = delete;
^
/home/fguertin/boost_1_56_0-x86/boost/thread/detail/move.hpp:240:3: note: in expansion of macro ‘BOOST_THREAD_NO_COPYABLE’
BOOST_THREAD_NO_COPYABLE(TYPE)
^
/home/fguertin/boost_1_56_0-x86/boost/thread/future.hpp:1574:9: note: in expansion of macro ‘BOOST_THREAD_MOVABLE_ONLY’
BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
^
/home/fguertin/boost_1_56_0-x86/boost/thread/future.hpp:1574:35: note: in expansion of macro ‘BOOST_THREAD_FUTURE’
BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)

``

0 Likes

#5

Endpoints returning futures don’t actually work right now in AutobahnCpp: https://github.com/tavendo/AutobahnCpp/issues/42

I would suggest looking at CppWAMP if you’re looking to do those sorts of things: https://github.com/ecorm/cppwamp

···

On Monday, May 11, 2015 at 10:22:19 AM UTC-7, Raito Bezarius wrote:

Hi François,

I’m not sure of it, but I think that it’s this:

r1.then([&](future<registration> reg)

You should try to pass the future by reference because futures are not copyable.
Else, the second possibility is :

future<any> anyFuture = anyPromise.get_future();

You should try to pass it by reference too I think, but I don’t see mention of a deleted assignation operator…
Hope it helps you!

Kind regards,
Raito Bezarius.
Le lundi 11 mai 2015 17:47:49 UTC+2, François Guertin a écrit :

Hi Raito,

First, I want to thank you for help.

I have followed your guidelines about returning a boost::future from my function but I get this compilation error.

11:14:45 **** Incremental Build of configuration Debug for project ARTS-coreVhf ****
make all
Building file: …/src/main.cpp
Invoking: GCC C++ Compiler
g++ -std=c++11 -I/home/fguertin/boost_1_56_0-x86 -I/home/fguertin/AutobahnCpp/autobahn -O2 -g3 -pedantic -w -Wall -c -fmessage-length=0 -Wunused-local-typedefs -MMD -MP -MF"src/main.d" -MT"src/main.d" -o “src/main.o” “…/src/main.cpp”
In file included from /home/fguertin/AutobahnCpp/autobahn/autobahn.hpp:41:0,
from …/src/main.cpp:18:
/home/fguertin/boost_1_56_0-x86/boost/any.hpp: In instantiation of ‘boost::any::holder::holder(const ValueType&) [with ValueType = boost::futureboost::any]’:
/home/fguertin/boost_1_56_0-x86/boost/any.hpp:199:39: required from ‘boost::any::placeholder* boost::any::holder::clone() const [with ValueType = boost::futureboost::any]’
…/src/main.cpp:749:1: required from here
/home/fguertin/boost_1_56_0-x86/boost/any.hpp:180:27: error: use of deleted function ‘boost::future::future(const boost::future&) [with R = boost::any]’
: held(value)
^
In file included from /home/fguertin/boost_1_56_0-x86/boost/thread/detail/move.hpp:26:0,
from /home/fguertin/boost_1_56_0-x86/boost/thread/exceptional_ptr.hpp:9,
from /home/fguertin/boost_1_56_0-x86/boost/thread/future.hpp:20,
from /home/fguertin/AutobahnCpp/autobahn/autobahn.hpp:38,
from …/src/main.cpp:18:
/home/fguertin/boost_1_56_0-x86/boost/thread/future.hpp:72:29: error: declared here
#define BOOST_THREAD_FUTURE future
^
/home/fguertin/boost_1_56_0-x86/boost/thread/detail/delete.hpp:21:7: note: in definition of macro ‘BOOST_THREAD_DELETE_COPY_CTOR’
CLASS(CLASS const&) = delete;
^
/home/fguertin/boost_1_56_0-x86/boost/thread/detail/move.hpp:240:3: note: in expansion of macro ‘BOOST_THREAD_NO_COPYABLE’
BOOST_THREAD_NO_COPYABLE(TYPE)
^
/home/fguertin/boost_1_56_0-x86/boost/thread/future.hpp:1574:9: note: in expansion of macro ‘BOOST_THREAD_MOVABLE_ONLY’
BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
^
/home/fguertin/boost_1_56_0-x86/boost/thread/future.hpp:1574:35: note: in expansion of macro ‘BOOST_THREAD_FUTURE’
BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)

``

0 Likes

#6

Thank you very much for the enlightenment guys!

Does that mean we can’t do asynch RPCs using promise/future in Autobahn|Cpp (see attached picture)?

Regards,

Francois.

···

On Wednesday, May 6, 2015 at 3:32:27 PM UTC-4, François Guertin wrote:

Hi all,

I have a callee C++ program that runs on a single thread and does computation (nothing related to DB) who takes at least 30 seconds each and I would like it to handle simultaneous calls (from callers).

For avoiding my (single-threaded) WAMP component to be unresponsive from the outside (to Crossbar router and the other callers) while the callee code is “busy” sitting and waiting for the call to return, I read in this newsgroup that boost::future and boost::promise could be used for that.

I have seen Autobahn|JS can defer and then resolve the results when they’re ready but there are very few explanations (and examples) on how to implement all this in Autobahn|Cpp. I’m wondering if someone has ever “cooked” something to provide asynchronous support to RPCs.

0 Likes

#7

Since you can’t return a future from an RPC method currently, I don’t see how you’d do it. Note that this is a bug, not a missing feature - it shouldn’t be too much effort to make returning futures work.

···

On Tue, May 12, 2015 at 9:38 AM François Guertin f.guer...@gmail.com wrote:

Thank you very much for the enlightenment guys!

Does that mean we can’t do asynch RPCs using promise/future in Autobahn|Cpp (see attached picture)?

Regards,

Francois.

On Wednesday, May 6, 2015 at 3:32:27 PM UTC-4, François Guertin wrote:

Hi all,

I have a callee C++ program that runs on a single thread and does computation (nothing related to DB) who takes at least 30 seconds each and I would like it to handle simultaneous calls (from callers).

For avoiding my (single-threaded) WAMP component to be unresponsive from the outside (to Crossbar router and the other callers) while the callee code is “busy” sitting and waiting for the call to return, I read in this newsgroup that boost::future and boost::promise could be used for that.

I have seen Autobahn|JS can defer and then resolve the results when they’re ready but there are very few explanations (and examples) on how to implement all this in Autobahn|Cpp. I’m wondering if someone has ever “cooked” something to provide asynchronous support to RPCs.

You received this message because you are subscribed to a topic in the Google Groups “Autobahn” group.

To unsubscribe from this topic, visit https://groups.google.com/d/topic/autobahnws/Y2cligI8FJY/unsubscribe.

To unsubscribe from this group and all its topics, send an email to autobahnws+...@googlegroups.com.

To post to this group, send email to autob...@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/autobahnws/5449a463-aa54-49c0-82a0-41140dc33d0b%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

0 Likes