Archive for March, 2014
Duetto (C++ for the Web) 0.9.4: Async RPCs, Promises, JavaScript interoperability
Posted by Alessandro Pignotti in Uncategorized on March 17, 2014
Around a month has passed since our talk at mloc.js. There we had a great opportunity to talk about the technology behind the duetto C++ compiler for the Web. We also made our first public announcement of our promise based support for asynchronous type safe RPC, which fits in our vision of C++ as the platform language for the Web, both on the client and on the server side.
Today, we announce the new, feature-packed release of Duetto — 0.9.4! This time, we really splurged, and added some quality features that we’re sure you’ll find interesting:
-
Initial support for promise-based async RPC
-
Strong interoperability with JavaScript
-
__asm__ to execute JavaScript from C++ code
-
[[jsexport]] attribute to use C++ objects from JavaScript
-
-
Support for C++ mutex/atomic/thread headers
As usual, you can find the full source code of the release here, plus binary packages for Debian/Ubuntu on our PPA, a binary setup for windows and a binary archive for Mac OS X here.
Asynchronous RPC using promises
With duetto you can “tag” a method to let the compiler know that the code should be compiled for the server side. The compiler also takes care of generating RPC boilerplate including type safe serialization of parameters and deserialization of the return value. While the basic model is synchronous, you can take advantage of promises to use fully type safe asynchronous RPC in duetto. See e.g. the following code:
// Pending requests for messages
vector<Promise<string>*> pendingRequests;
Promise<string>* getChatMessageRemote() [[server]]
{
auto ret=new Promise<string>();
// Store the new promise, you can use it later to complete
// the request in asynchronous manner
pendingRequests.push_back(ret);
return ret;
}
void sendMessageRemote(const string& str) [[server]]
{
for (auto p: pendingRequests)
p->done(str);
pendingRequests.clear();
}
void messageHandler(const string& newMessage) [[client]]
{
client::console.log("Message received",newMessage.c_str());
}
void webMain() [[client]]
{
// First wait for messages
auto promise = getChatMessageRemote();
// Add a callback to the promise
promise->then(messageHandler);
// Tell the promise that no more callbacks will be added
promise->complete();
// Now send a message, it will be echoed back
sendMessageRemote("Test message");
}
The code is a simple but working example of a multi-user chat application. The getChatMessageRemote method returns a promise immediately after being called, without waiting for the server answer. On the server side we create a promise and return it. We also need to store it somewhere to eventually fulfill the promise by sending a value.
The client code needs to set a callback to receive the value when the promise will be eventually fulfilled. Later on the client send a chat message using the sendMessageRemote server method. This method is synchronous and will return only after the server side execution is completed. The server echoes the message back to all connected clients by fulfilling all pending promises.
Strong JS interoperability
This release of duetto includes two features that provide a superior integration with manually written JavaScript code: the [[jsexport]] class attribute and __asm__ support for inline JavaScript.
[[jsexport]] class attribute
We have introduced preliminary support for a new attribute: [[jsexport]]. This attribute is designed to be applied on C++ classes, doing so will cause make the class available to manually written JavaScript code. The following example shows its typical use:
class [[jsexport]] ExportExample
{
private:
float a;
int b;
public:
ExportExample(float _a, int _b):a(_a),b(_b)
{
}
void testMethod()
{
client::console.log(“Float value is”, a);
}
};
During compilation duetto will generate bridge code to expose the ExportExample C++ class to JavaScript code. You can then use the class when writing JS code
// Using jsexport-ed classes from JavaScript code
var cppobj = new ExportExample(0.1, 42);
cppobj.testMethod();
The [[jexport]] attribute places some limitations on the class. In particular, the object must have a trivial destructor and no overloaded methods. Moreover operators can’t be exported to JavaScript. Having a trivial destructor is necessary to make sure that the regular Garbage Collection mechanism is sufficient to reclaim the object. We plan to expand this feature in the future to reduce any limitations as much as possible.
Inline JavaScript using __asm__
This release also adds support for inserting arbitrary JavaScript code inside C++ code using the __asm__ functionality. Our design choice has been to put no limit on what you can do inside __asm__, including breaking the program, so be careful when taking advantage of this capability.
void webMain()
{
__asm__(“alert(‘JavaScript code inside __asm__’);”);
}
At the moment only this simple form of JS code insertion is supported. It’s not currently possible to pass variables from surrounding C++ code or return a value from __asm__, but we will extend this support in the future.
Support for C++ mutex/atomic/thread headers
Some C++ functionalities, especially the ones related to multi-threading, do not have a direct mapping on the browser platform. That said, we want to provide as much compatibility as possible with existing C++ code to reduce the effort when using duetto for porting.
As of duetto 0.9.4, we support the following C++ threading primitives:
-
mutex: Implemented as plain counters, mutexes cannot block execution but report an error if a non-recursive mutex is acquired twice.
-
atomic: Implemented as plain integers, since the browser is not actually concurrent there is no real support for atomic operations.
-
thread: Modern browsers support WebWorkers, but the threading model does not map to the one expected by C++ threads. We chose to make the user aware that C++ threads are not supported by adding an explicit error message when the thread header is included in code compiled with duetto.
Follow us on @leaningtech, Facebook and at www.leaningtech.com for updates.
Duetto (C++ for the Web) 0.9.4: Async RPCs, Promises, JavaScript interoperability
Posted by Alessandro Pignotti in Uncategorized on March 17, 2014
Around a month has passed since our talk at mloc.js. There we had a great opportunity to talk about the technology behind the duetto C++ compiler for the Web. We also made our first public announcement of our promise based support for asynchronous type safe RPC, which fits in our vision of C++ as the platform language for the Web, both on the client and on the server side.
Today, we announce the new, feature-packed release of Duetto — 0.9.4! This time, we really splurged, and added some quality features that we’re sure you’ll find interesting:
-
Initial support for promise-based async RPC
-
Strong interoperability with JavaScript
-
__asm__ to execute JavaScript from C++ code
-
[[jsexport]] attribute to use C++ objects from JavaScript
-
-
Support for C++ mutex/atomic/thread headers
As usual, you can find the full source code of the release here, plus binary packages for Debian/Ubuntu on our PPA, a binary setup for windows and a binary archive for Mac OS X here.
Asynchronous RPC using promises
With duetto you can “tag” a method to let the compiler know that the code should be compiled for the server side. The compiler also takes care of generating RPC boilerplate including type safe serialization of parameters and deserialization of the return value. While the basic model is synchronous, you can take advantage of promises to use fully type safe asynchronous RPC in duetto. See e.g. the following code:
// Pending requests for messages
vector<Promise<string>*> pendingRequests;
Promise<string>* getChatMessageRemote() [[server]]
{
auto ret=new Promise<string>();
// Store the new promise, you can use it later to complete
// the request in asynchronous manner
pendingRequests.push_back(ret);
return ret;
}
void sendMessageRemote(const string& str) [[server]]
{
for (auto p: pendingRequests)
p->done(str);
pendingRequests.clear();
}
void messageHandler(const string& newMessage) [[client]]
{
client::console.log("Message received",newMessage.c_str());
}
void webMain() [[client]]
{
// First wait for messages
auto promise = getChatMessageRemote();
// Add a callback to the promise
promise->then(messageHandler);
// Tell the promise that no more callbacks will be added
promise->complete();
// Now send a message, it will be echoed back
sendMessageRemote("Test message");
}
The code is a simple but working example of a multi-user chat application. The getChatMessageRemote method returns a promise immediately after being called, without waiting for the server answer. On the server side we create a promise and return it. We also need to store it somewhere to eventually fulfill the promise by sending a value.
The client code needs to set a callback to receive the value when the promise will be eventually fulfilled. Later on the client send a chat message using the sendMessageRemote server method. This method is synchronous and will return only after the server side execution is completed. The server echoes the message back to all connected clients by fulfilling all pending promises.
Strong JS interoperability
This release of duetto includes two features that provide a superior integration with manually written JavaScript code: the [[jsexport]] class attribute and __asm__ support for inline JavaScript.
[[jsexport]] class attribute
We have introduced preliminary support for a new attribute: [[jsexport]]. This attribute is designed to be applied on C++ classes, doing so will cause make the class available to manually written JavaScript code. The following example shows its typical use:
class [[jsexport]] ExportExample
{
private:
float a;
int b;
public:
ExportExample(float _a, int _b):a(_a),b(_b)
{
}
void testMethod()
{
client::console.log(“Float value is”, a);
}
};
During compilation duetto will generate bridge code to expose the ExportExample C++ class to JavaScript code. You can then use the class when writing JS code
// Using jsexport-ed classes from JavaScript code
var cppobj = new ExportExample(0.1, 42);
cppobj.testMethod();
The [[jexport]] attribute places some limitations on the class. In particular, the object must have a trivial destructor and no overloaded methods. Moreover operators can’t be exported to JavaScript. Having a trivial destructor is necessary to make sure that the regular Garbage Collection mechanism is sufficient to reclaim the object. We plan to expand this feature in the future to reduce any limitations as much as possible.
Inline JavaScript using __asm__
This release also adds support for inserting arbitrary JavaScript code inside C++ code using the __asm__ functionality. Our design choice has been to put no limit on what you can do inside __asm__, including breaking the program, so be careful when taking advantage of this capability.
void webMain()
{
__asm__(“alert(‘JavaScript code inside __asm__’);”);
}
At the moment only this simple form of JS code insertion is supported. It’s not currently possible to pass variables from surrounding C++ code or return a value from __asm__, but we will extend this support in the future.
Support for C++ mutex/atomic/thread headers
Some C++ functionalities, especially the ones related to multi-threading, do not have a direct mapping on the browser platform. That said, we want to provide as much compatibility as possible with existing C++ code to reduce the effort when using duetto for porting.
As of duetto 0.9.4, we support the following C++ threading primitives:
-
mutex: Implemented as plain counters, mutexes cannot block execution but report an error if a non-recursive mutex is acquired twice.
-
atomic: Implemented as plain integers, since the browser is not actually concurrent there is no real support for atomic operations.
-
thread: Modern browsers support WebWorkers, but the threading model does not map to the one expected by C++ threads. We chose to make the user aware that C++ threads are not supported by adding an explicit error message when the thread header is included in code compiled with duetto.
Follow us on @leaningtech, Facebook and at www.leaningtech.com for updates.