+1

I'd be very interested in seeing this checked in on a branch.

-Ted

On 11/19/2013 03:33 PM, Robbie Gemmell wrote:
I think its worth mentioning that branches are ideally suited to this sort
of work....whether it actually ends up on trunk or not in the end, theres
no need to keep things local until it is actually ready for landing on
trunk...

Robbie

On 19 November 2013 19:56, Fraser Adams <fraser.ad...@blueyonder.co.uk>wrote:

Hey all,
For the last couple of weekends I've been working on a Proof of Concept
JavaScript implementation of Proton.

The approach that I've taken is (I think) quite interesting/unusual but
it's an approach that offers a high level of synergy with implementations
for other languages that are essentially bindings to proton-c.

The "magic elixir" in this is the downright amazing emscripten
https://github.com/kripken/emscripten/wiki which (believe it or not) is
essentially a cross-compiler that can compile C/C++ to JavaScript. Moreover
the JavaScript that it compiles to is a particular subset called asm.js
http://asmjs.org/ which can be extremely aggressively optimised and is
subject to a lot of research by Mozilla in particular (the main emscripten
maintainer is actually a Mozilla researcher, though I believe emscripten is
something of a side project).

It's well worth visiting the emscripten page with a modern browser, the
Epic Citadel demo is awesome :-)

So in a nutshell what I've done is to compile proton-c into JavaScript

So I'm underselling it a bit :-) I had to do a fair bit of work to make it
that simple, in particular I had to add/fix a number of emscripten's
library functions (Proton used a few things that weren't implemented) but
the cool thing is that those are now in emscripten for everyone's benefit.

A really nice thing is that I've not actually had to modify any of the
engine/messenger code at all - one I started to figure out what I was doing
wrong that is :-) all I've really needed to to was to modify send.c/recv.c
so that they behave in a non-blocking manner (you may have seen my mail at
the weekend before I finally figured it out :-))

I've got CMake able to cross-compile in a repeatable fashion so the only
change to any existing Proton stuff that is required is an addition to the
top-level CMakeLists.txt that detects the presence of emscripten and its
dependencies and if present fires off "add_subdirectory(bindings/javascript)"
e.g.


# Build the JavaScript language binding.
# This is somewhat different to the other language bindings in that it
does not use swig. It uses a C/C++ to
# JavaScript cross-compiler called emscripten (https://github.com/kripken/
emscripten). Emscripten takes C/C++
# and "compiles" it into a highly optimisable subset of JavaScript called
asm.js (http://asmjs.org/) that can
# be aggressively optimised and run at near-native speed (usually between
1.5 to 10 times slower than native C/C++).
option("BUILD_JAVASCRIPT" "Build JavaScript language binding" ON)
if (BUILD_JAVASCRIPT)
   # First check that Node.js is installed as that is needed by emscripten.
   find_program(NODE node)
   if (NOT NODE)
     message(STATUS "Node.js (http://nodejs.org) is not installed: can't
build JavaScript binding")
   else (NOT NODE)
     # Check that the emscripten C/C++ to JavaScript cross-compiler is
installed.
     find_program(EMCC emcc)
     if (NOT EMCC)
       message(STATUS "Emscripten (https://github.com/kripken/emscripten)
is not installed: can't build JavaScript binding")
     else (NOT EMCC)
       add_subdirectory(bindings/javascript)
     endif (NOT EMCC)
   endif (NOT NODE)
endif (BUILD_JAVASCRIPT)


So the main purpose of this mail is to give a heads up of it and to ask if
it'd be OK to start commiting it and give others some visibility of it.

At this stage it's something of a Proof of Concept, in particular:
* I haven't exported any actual JavaScript bindings so although it's
JavaScript actual JavaScript clients would find it awkward to call the API
as yet.
* As alluded above and at the weekend the demo code I've got calling
messenger isn't especially elegant, I think I know how to get things
behaving more asynchronously, but haven't tried it yet (and my hunch may be
wrong).
* Transport is entirely over WebSockets :-) so I've actually got send and
recv running on Node.js (and also send on a browser) but it'd be useful to
have them communicate via TCP sockets too - though that'd need a proxy.
* I still (perhaps amusingly given this) don't know that much about
Proton, so I've only really got send and recv to play with I'm not really
sure where there may be other messenger examples to exercise it a bit
better (in particular message type interoperability would be good to test).
I'd be grateful for pointers - is the object.c test the best place to look
for this? And I couldn't see any tests for the "tracker" capabilities??
* In case it wasn't clear from the WebSockets it'll only work in a
relatively modern browser at the moment both for the WebSocket stuff and
for the fact that it relies on ArrayBuffers (though there's an emscripten
compile option to allow the use of native JavaScript Arrays instead)


Finally it's probably worth pointing out some pros and cons for this
approach to creating a JavaScript Proton
Pro:
* It's using the existing proton-c code base with the posix driver.c
completely unchanged (with the simple test I've done to date) so from a
broad maintenance/"Total cost of Ownership" perspective it means
essentially very little extra maintenance costs.
* It follows the same "pattern" as Python/Perl/PHP/Ruby/Java JNI albeit
it's cross-compiled rather than a pure binding.
* It should be somewhat faster than "handwritten" JavaScript. This might
seem counter-intuitive but it's worth looking at the emscripten/asm.js
documentation. From my own experience I've ported zlib to JavaScript for
another project I'm working on and inflate was *significantly* faster than
the literal port of tinflate that I had previously used - and that was on a
relatively old Firefox without asm.js optimisations.

Con:
* The compiled code is likely to be somewhat larger than hand written
JavaScript. I haven't done an optimised & minified build yet so I can't say
for sure how big it will actually be. The unoptimised send.js/recv.js are
1.5MB each so at a guess they'll probably come out at arounf the ~500K mark
(though they should also gzip quite well).
* The compiled code isn't necessarily hugely readable. It's "OK" when not
optimised but.... (to be fair I used it to figure out how to get the
missing library calls working so it's not *totally* impenetrable :-))


I hope that this is something that'll be useful/interesting please do let
me know if you're all happy for me to get it kicked off into the Proton
code base.

Best regards,
Frase



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@qpid.apache.org
For additional commands, e-mail: users-h...@qpid.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@qpid.apache.org
For additional commands, e-mail: users-h...@qpid.apache.org

Reply via email to