Will crossbar tolerate multiple threads trying to make the same RPC call simultaneously?

#1

Will crossbar tolerate multiple threads trying to make the same RPC call simultaneously?

0 Likes

#2

Hi James!

Unless there is a difference between threads and clients in general, your question boils down to: Can several clients call an RPC at the same time (i.e. in very quick succession)? Crossbar.io will router all of these.

Whether the component implementing the procedure can cope with the load is a different question. Several components can register the same procedure and Crossbar.io can do simple load-balancing across these - see http://crossbar.io/docs/Shared-Registrations/.

Hope I understood your question correctly and that this helps!

Regards,

Alex

···

Am Freitag, 23. Oktober 2015 14:48:48 UTC+2 schrieb James Webster:

Will crossbar tolerate multiple threads trying to make the same RPC call simultaneously?

0 Likes

#3

I just realized that I asked the question incorrectly.

Let me explain it this way. I have a caller that has two threads. If thread A makes an RPC call, and then thread B makes an RPC call (let’s say to a different function) before thread A’s RPC call completes, is this a problem? I’m just worried that the two simultaneous calls would interfere with each other, since they share the same process and port.

···

On Friday, October 23, 2015 at 12:43:39 PM UTC-4, Alexander Gödde wrote:

Hi James!

Unless there is a difference between threads and clients in general, your question boils down to: Can several clients call an RPC at the same time (i.e. in very quick succession)? Crossbar.io will router all of these.

Whether the component implementing the procedure can cope with the load is a different question. Several components can register the same procedure and Crossbar.io can do simple load-balancing across these - see http://crossbar.io/docs/Shared-Registrations/.

Hope I understood your question correctly and that this helps!

Regards,

Alex

Am Freitag, 23. Oktober 2015 14:48:48 UTC+2 schrieb James Webster:

Will crossbar tolerate multiple threads trying to make the same RPC call simultaneously?

0 Likes

#4

No, they won’t interefere. The calls run concurrently and asynchronously, and the time and order when they return doesn’t matter. If you are worried, try it. There is some “slow square” example somewhere in the crossbarexanples repo that illustrates some of these aspects …

···

Sent from Mobile (Google Nexus 5)

Am 23.10.2015 7:09 nachm. schrieb “James Webster” jamesp...@gmail.com:

I just realized that I asked the question incorrectly.

Let me explain it this way. I have a caller that has two threads. If thread A makes an RPC call, and then thread B makes an RPC call (let’s say to a different function) before thread A’s RPC call completes, is this a problem? I’m just worried that the two simultaneous calls would interfere with each other, since they share the same process and port.

On Friday, October 23, 2015 at 12:43:39 PM UTC-4, Alexander Gödde wrote:

Hi James!

Unless there is a difference between threads and clients in general, your question boils down to: Can several clients call an RPC at the same time (i.e. in very quick succession)? Crossbar.io will router all of these.

Whether the component implementing the procedure can cope with the load is a different question. Several components can register the same procedure and Crossbar.io can do simple load-balancing across these - see http://crossbar.io/docs/Shared-Registrations/.

Hope I understood your question correctly and that this helps!

Regards,

Alex

Am Freitag, 23. Oktober 2015 14:48:48 UTC+2 schrieb James Webster:

Will crossbar tolerate multiple threads trying to make the same RPC call simultaneously?

You received this message because you are subscribed to the Google Groups “Crossbar” group.

To unsubscribe from this group and stop receiving emails from it, send an email to crossbario+...@googlegroups.com.

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

To view this discussion on the web visit https://groups.google.com/d/msgid/crossbario/09058cd3-0e7d-4545-b48f-dcd14e154608%40googlegroups.com.

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

0 Likes

#5

Thanks, that’s awesome!

···

On Friday, October 23, 2015 at 2:12:46 PM UTC-4, Tobias Oberstein wrote:

No, they won’t interefere. The calls run concurrently and asynchronously, and the time and order when they return doesn’t matter. If you are worried, try it. There is some “slow square” example somewhere in the crossbarexanples repo that illustrates some of these aspects …

Sent from Mobile (Google Nexus 5)

Am 23.10.2015 7:09 nachm. schrieb “James Webster” jame...@gmail.com:

I just realized that I asked the question incorrectly.

Let me explain it this way. I have a caller that has two threads. If thread A makes an RPC call, and then thread B makes an RPC call (let’s say to a different function) before thread A’s RPC call completes, is this a problem? I’m just worried that the two simultaneous calls would interfere with each other, since they share the same process and port.

On Friday, October 23, 2015 at 12:43:39 PM UTC-4, Alexander Gödde wrote:

Hi James!

Unless there is a difference between threads and clients in general, your question boils down to: Can several clients call an RPC at the same time (i.e. in very quick succession)? Crossbar.io will router all of these.

Whether the component implementing the procedure can cope with the load is a different question. Several components can register the same procedure and Crossbar.io can do simple load-balancing across these - see http://crossbar.io/docs/Shared-Registrations/.

Hope I understood your question correctly and that this helps!

Regards,

Alex

Am Freitag, 23. Oktober 2015 14:48:48 UTC+2 schrieb James Webster:

Will crossbar tolerate multiple threads trying to make the same RPC call simultaneously?

You received this message because you are subscribed to the Google Groups “Crossbar” group.

To unsubscribe from this group and stop receiving emails from it, send an email to crossbario+...@googlegroups.com.

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

To view this discussion on the web visit https://groups.google.com/d/msgid/crossbario/09058cd3-0e7d-4545-b48f-dcd14e154608%40googlegroups.com.

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

0 Likes

#6

I tested this out, and was unable to demonstrate concurrent execution of the RPC calls.

In the code below, two RPCs are made. One returns immediately, the other sleeps for 10 seconds. If you call the slow one first, and then while it is working call the quick one, you would expect the quick one to return immediately. This is not what happens. The quick one blocks until the slow one has finished, and then executes.

Can you see if I am missing something fundamental in my strategy?

////////////////CALLER CODE/////////////////////////
#include
#include
#include <cppwamp/conversion.hpp>
#include <cppwamp/corosession.hpp>
#include <cppwamp/json.hpp>
#include <cppwamp/tcp.hpp>
#include <cppwamp/unpacker.hpp>
#include
#include <boost/thread/thread.hpp>
const std::string realm = “cppwamp.demo.time”;
const std::string address = “localhost”;
const short port = 12345;
void quick_job(){
wamp::AsioService iosvc;
auto tcp = wamp::connectorwamp::Json(iosvc, wamp::TcpHost(address,port));
using namespace wamp;
auto session = CoroSession<>::create(tcp);
boost::asio::spawn(iosvc, [&](boost::asio::yield_context yield)
{
session->connect(yield);
session->join(Realm(realm), yield);
session->call(Rpc(“quick_return”), yield);
std::cout << “Quick return\n”;
Reason aReason;
session->leave(aReason, yield);
session->disconnect();
});
iosvc.run();
}
void slow_job(){
wamp::AsioService iosvc;
auto tcp = wamp::connectorwamp::Json(iosvc, wamp::TcpHost(address,port));
using namespace wamp;
auto session = CoroSession<>::create(tcp);
boost::asio::spawn(iosvc, [&](boost::asio::yield_context yield)
{
session->connect(yield);
session->join(Realm(realm), yield);
session->call(Rpc(“slow_return”), yield);
std::cout << “Slow return\n”;
Reason aReason;
session->leave(aReason, yield);
session->disconnect();
});
iosvc.run();
}
int main()
{
boost::thread s(slow_job);
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
boost::thread q(quick_job);
s.join();
q.join();
return 0;
}

////////////////SERVICE CODE/////////////////////////
#include
#include
#include
#include <cppwamp/conversion.hpp>
#include <cppwamp/corosession.hpp>
#include <cppwamp/msgpack.hpp>
#include <cppwamp/json.hpp>
#include <cppwamp/tcp.hpp>
#include <boost/thread/thread.hpp>
const std::string realm = “cppwamp.demo.time”;
const std::string address = “localhost”;
const short port = 12345;
wamp::Outcome quick_return(wamp::Invocation){
return wamp::Result().withArgs(“Done”);
}
wamp::Outcome slow_return(wamp::Invocation){
boost::this_thread::sleep(boost::posix_time::milliseconds(10000));
return wamp::Result().withArgs(“Done”);
}
int main()
{
program_on = true;
wamp::AsioService iosvc;
auto tcp = wamp::connectorwamp::Json(iosvc, wamp::TcpHost(address,port));
using namespace wamp;
auto session = CoroSession<>::create(tcp);
boost::asio::spawn(iosvc, [&](boost::asio::yield_context yield)
{
session->connect(yield);
session->join(Realm(realm), yield);
session->enroll(Procedure(“quick_return”), &quick_return, yield);
session->enroll(Procedure(“slow_return”), &slow_return, yield);
});
iosvc.run();
return 0;
}

``

0 Likes

#7

Hi James!

This is not a Crossbar or WAMP issue. WAMP calls are supposed to be sent immediately when they are made, and the result is returned when it becomes available.

I have no experience with cppwamp (or C, for that matter), so my best guess is that either something in the library or in your code is blocking.

Take a look at this example to see how it works in principle: https://github.com/crossbario/autobahn-python/tree/master/examples/twisted/wamp/rpc/slowsquare

Regards,

Alex

···

Am Donnerstag, 29. Oktober 2015 14:44:58 UTC+1 schrieb James Webster:

I tested this out, and was unable to demonstrate concurrent execution of the RPC calls.

In the code below, two RPCs are made. One returns immediately, the other sleeps for 10 seconds. If you call the slow one first, and then while it is working call the quick one, you would expect the quick one to return immediately. This is not what happens. The quick one blocks until the slow one has finished, and then executes.

Can you see if I am missing something fundamental in my strategy?

////////////////CALLER CODE/////////////////////////
#include
#include
#include <cppwamp/conversion.hpp>
#include <cppwamp/corosession.hpp>
#include <cppwamp/json.hpp>
#include <cppwamp/tcp.hpp>
#include <cppwamp/unpacker.hpp>
#include
#include <boost/thread/thread.hpp>
const std::string realm = “cppwamp.demo.time”;
const std::string address = “localhost”;
const short port = 12345;
void quick_job(){
wamp::AsioService iosvc;
auto tcp = wamp::connectorwamp::Json(iosvc, wamp::TcpHost(address,port));
using namespace wamp;
auto session = CoroSession<>::create(tcp);
boost::asio::spawn(iosvc, [&](boost::asio::yield_context yield)
{
session->connect(yield);
session->join(Realm(realm), yield);
session->call(Rpc(“quick_return”), yield);
std::cout << “Quick return\n”;
Reason aReason;
session->leave(aReason, yield);
session->disconnect();
});
iosvc.run();
}
void slow_job(){
wamp::AsioService iosvc;
auto tcp = wamp::connectorwamp::Json(iosvc, wamp::TcpHost(address,port));
using namespace wamp;
auto session = CoroSession<>::create(tcp);
boost::asio::spawn(iosvc, [&](boost::asio::yield_context yield)
{
session->connect(yield);
session->join(Realm(realm), yield);
session->call(Rpc(“slow_return”), yield);
std::cout << “Slow return\n”;
Reason aReason;
session->leave(aReason, yield);
session->disconnect();
});
iosvc.run();
}
int main()
{
boost::thread s(slow_job);
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
boost::thread q(quick_job);
s.join();
q.join();
return 0;
}

////////////////SERVICE CODE/////////////////////////
#include
#include
#include
#include <cppwamp/conversion.hpp>
#include <cppwamp/corosession.hpp>
#include <cppwamp/msgpack.hpp>
#include <cppwamp/json.hpp>
#include <cppwamp/tcp.hpp>
#include <boost/thread/thread.hpp>
const std::string realm = “cppwamp.demo.time”;
const std::string address = “localhost”;
const short port = 12345;
wamp::Outcome quick_return(wamp::Invocation){
return wamp::Result().withArgs(“Done”);
}
wamp::Outcome slow_return(wamp::Invocation){
boost::this_thread::sleep(boost::posix_time::milliseconds(10000));
return wamp::Result().withArgs(“Done”);
}
int main()
{
program_on = true;
wamp::AsioService iosvc;
auto tcp = wamp::connectorwamp::Json(iosvc, wamp::TcpHost(address,port));
using namespace wamp;
auto session = CoroSession<>::create(tcp);
boost::asio::spawn(iosvc, [&](boost::asio::yield_context yield)
{
session->connect(yield);
session->join(Realm(realm), yield);
session->enroll(Procedure(“quick_return”), &quick_return, yield);
session->enroll(Procedure(“slow_return”), &slow_return, yield);
});
iosvc.run();
return 0;
}

``

0 Likes

#8

Ok – I’ll try doing a similar test using a different c++ client library (Autobahn)

Thank you,

···

On Thursday, October 29, 2015 at 11:06:41 AM UTC-4, Alexander Gödde wrote:

Hi James!

This is not a Crossbar or WAMP issue. WAMP calls are supposed to be sent immediately when they are made, and the result is returned when it becomes available.

I have no experience with cppwamp (or C, for that matter), so my best guess is that either something in the library or in your code is blocking.

Take a look at this example to see how it works in principle: https://github.com/crossbario/autobahn-python/tree/master/examples/twisted/wamp/rpc/slowsquare

Regards,

Alex

Am Donnerstag, 29. Oktober 2015 14:44:58 UTC+1 schrieb James Webster:

I tested this out, and was unable to demonstrate concurrent execution of the RPC calls.

In the code below, two RPCs are made. One returns immediately, the other sleeps for 10 seconds. If you call the slow one first, and then while it is working call the quick one, you would expect the quick one to return immediately. This is not what happens. The quick one blocks until the slow one has finished, and then executes.

Can you see if I am missing something fundamental in my strategy?

////////////////CALLER CODE/////////////////////////
#include
#include
#include <cppwamp/conversion.hpp>
#include <cppwamp/corosession.hpp>
#include <cppwamp/json.hpp>
#include <cppwamp/tcp.hpp>
#include <cppwamp/unpacker.hpp>
#include
#include <boost/thread/thread.hpp>
const std::string realm = “cppwamp.demo.time”;
const std::string address = “localhost”;
const short port = 12345;
void quick_job(){
wamp::AsioService iosvc;
auto tcp = wamp::connectorwamp::Json(iosvc, wamp::TcpHost(address,port));
using namespace wamp;
auto session = CoroSession<>::create(tcp);
boost::asio::spawn(iosvc, [&](boost::asio::yield_context yield)
{
session->connect(yield);
session->join(Realm(realm), yield);
session->call(Rpc(“quick_return”), yield);
std::cout << “Quick return\n”;
Reason aReason;
session->leave(aReason, yield);
session->disconnect();
});
iosvc.run();
}
void slow_job(){
wamp::AsioService iosvc;
auto tcp = wamp::connectorwamp::Json(iosvc, wamp::TcpHost(address,port));
using namespace wamp;
auto session = CoroSession<>::create(tcp);
boost::asio::spawn(iosvc, [&](boost::asio::yield_context yield)
{
session->connect(yield);
session->join(Realm(realm), yield);
session->call(Rpc(“slow_return”), yield);
std::cout << “Slow return\n”;
Reason aReason;
session->leave(aReason, yield);
session->disconnect();
});
iosvc.run();
}
int main()
{
boost::thread s(slow_job);
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
boost::thread q(quick_job);
s.join();
q.join();
return 0;
}

////////////////SERVICE CODE/////////////////////////
#include
#include
#include
#include <cppwamp/conversion.hpp>
#include <cppwamp/corosession.hpp>
#include <cppwamp/msgpack.hpp>
#include <cppwamp/json.hpp>
#include <cppwamp/tcp.hpp>
#include <boost/thread/thread.hpp>
const std::string realm = “cppwamp.demo.time”;
const std::string address = “localhost”;
const short port = 12345;
wamp::Outcome quick_return(wamp::Invocation){
return wamp::Result().withArgs(“Done”);
}
wamp::Outcome slow_return(wamp::Invocation){
boost::this_thread::sleep(boost::posix_time::milliseconds(10000));
return wamp::Result().withArgs(“Done”);
}
int main()
{
program_on = true;
wamp::AsioService iosvc;
auto tcp = wamp::connectorwamp::Json(iosvc, wamp::TcpHost(address,port));
using namespace wamp;
auto session = CoroSession<>::create(tcp);
boost::asio::spawn(iosvc, [&](boost::asio::yield_context yield)
{
session->connect(yield);
session->join(Realm(realm), yield);
session->enroll(Procedure(“quick_return”), &quick_return, yield);
session->enroll(Procedure(“slow_return”), &slow_return, yield);
});
iosvc.run();
return 0;
}

``

0 Likes

#9

After a little more testing, it’s clear that my code was blocking. Specifically the service code was failing to process both requests concurrently.

···

On Thursday, October 29, 2015 at 11:15:32 AM UTC-4, James Webster wrote:

Ok – I’ll try doing a similar test using a different c++ client library (Autobahn)

Thank you,

On Thursday, October 29, 2015 at 11:06:41 AM UTC-4, Alexander Gödde wrote:

Hi James!

This is not a Crossbar or WAMP issue. WAMP calls are supposed to be sent immediately when they are made, and the result is returned when it becomes available.

I have no experience with cppwamp (or C, for that matter), so my best guess is that either something in the library or in your code is blocking.

Take a look at this example to see how it works in principle: https://github.com/crossbario/autobahn-python/tree/master/examples/twisted/wamp/rpc/slowsquare

Regards,

Alex

Am Donnerstag, 29. Oktober 2015 14:44:58 UTC+1 schrieb James Webster:

I tested this out, and was unable to demonstrate concurrent execution of the RPC calls.

In the code below, two RPCs are made. One returns immediately, the other sleeps for 10 seconds. If you call the slow one first, and then while it is working call the quick one, you would expect the quick one to return immediately. This is not what happens. The quick one blocks until the slow one has finished, and then executes.

Can you see if I am missing something fundamental in my strategy?

////////////////CALLER CODE/////////////////////////
#include
#include
#include <cppwamp/conversion.hpp>
#include <cppwamp/corosession.hpp>
#include <cppwamp/json.hpp>
#include <cppwamp/tcp.hpp>
#include <cppwamp/unpacker.hpp>
#include
#include <boost/thread/thread.hpp>
const std::string realm = “cppwamp.demo.time”;
const std::string address = “localhost”;
const short port = 12345;
void quick_job(){
wamp::AsioService iosvc;
auto tcp = wamp::connectorwamp::Json(iosvc, wamp::TcpHost(address,port));
using namespace wamp;
auto session = CoroSession<>::create(tcp);
boost::asio::spawn(iosvc, [&](boost::asio::yield_context yield)
{
session->connect(yield);
session->join(Realm(realm), yield);
session->call(Rpc(“quick_return”), yield);
std::cout << “Quick return\n”;
Reason aReason;
session->leave(aReason, yield);
session->disconnect();
});
iosvc.run();
}
void slow_job(){
wamp::AsioService iosvc;
auto tcp = wamp::connectorwamp::Json(iosvc, wamp::TcpHost(address,port));
using namespace wamp;
auto session = CoroSession<>::create(tcp);
boost::asio::spawn(iosvc, [&](boost::asio::yield_context yield)
{
session->connect(yield);
session->join(Realm(realm), yield);
session->call(Rpc(“slow_return”), yield);
std::cout << “Slow return\n”;
Reason aReason;
session->leave(aReason, yield);
session->disconnect();
});
iosvc.run();
}
int main()
{
boost::thread s(slow_job);
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
boost::thread q(quick_job);
s.join();
q.join();
return 0;
}

////////////////SERVICE CODE/////////////////////////
#include
#include
#include
#include <cppwamp/conversion.hpp>
#include <cppwamp/corosession.hpp>
#include <cppwamp/msgpack.hpp>
#include <cppwamp/json.hpp>
#include <cppwamp/tcp.hpp>
#include <boost/thread/thread.hpp>
const std::string realm = “cppwamp.demo.time”;
const std::string address = “localhost”;
const short port = 12345;
wamp::Outcome quick_return(wamp::Invocation){
return wamp::Result().withArgs(“Done”);
}
wamp::Outcome slow_return(wamp::Invocation){
boost::this_thread::sleep(boost::posix_time::milliseconds(10000));
return wamp::Result().withArgs(“Done”);
}
int main()
{
program_on = true;
wamp::AsioService iosvc;
auto tcp = wamp::connectorwamp::Json(iosvc, wamp::TcpHost(address,port));
using namespace wamp;
auto session = CoroSession<>::create(tcp);
boost::asio::spawn(iosvc, [&](boost::asio::yield_context yield)
{
session->connect(yield);
session->join(Realm(realm), yield);
session->enroll(Procedure(“quick_return”), &quick_return, yield);
session->enroll(Procedure(“slow_return”), &slow_return, yield);
});
iosvc.run();
return 0;
}

``

0 Likes