Open jamesjwarren opened 7 years ago
In fact, this was the idea from the beginning. I have been wanting to port cote to Swift for a long time, for one. But anything that can speak raw TCP sockets and broadcast / multicast, is a potential target.
The communication protocol is based on node-amp, and discovery piece is something proprietary loosely based on node-discover that we want to abstract away to introduce the capability of using another technology like redis instead of relying on IP broadcast.
So allowing services implemented in multiple languages speak to one another is certainly doable, although it's honestly a tremendous work.
Node js can't be used for processor intensive tasks. So cote for some other language like python will be a great addition.
I've been using Cotejs and it's terrific but I'm also reaching a point where we need multiple language support. I'd be happy to pitch in but I'd need guidance on where to start and what exactly would need to be done.
@theproductiveprogrammer most of cote's logic is about the transfer protocol over the wire, which is carried out by axon. In order to be portable, first, axon needs to be ported in other languages. But this makes it a little cumbersome — since axon is also not actively maintained, I can't justify the effort. I'm also thinking of replacing axon with HTTP2, and then it would be a little easier to port. Other remaining bits are about service discovery over UDP, and cote's internal logic, but they are much easier.
Migrating to HTTP2 would make porting to other languages (Java/Golang) much easier. When would you think the porting would be done? Also would it add overhead over to use HTTP2 over axon?
I'm now doing a benchmark, and I'm shocked with the results.
with 100,000 messages, axon is 35-50 times faster than zeromq, 10-15 times faster than HTTP2, and 2-2.5 times faster than redis (with ioredis).
I'm now very skeptical — if we port axon to other languages, the world's energy consumption will drop tremendously.
If we had a nice specification of axon that would go a long way to making ports happen. I'd be happy to work on that unless you think there's a better way.
On Sun., 5 Aug. 2018, 11:30 pm Armagan Amcalar, notifications@github.com wrote:
I'm now doing a benchmark, and I'm shocked with the results.
with 100,000 messages, axon is 35-50 times faster than zeromq, 10-15 times faster than HTTP2, and 2-2.5 times faster than redis (with ioredis).
I'm now very skeptical — if we port axon to other languages, the world's energy consumption will drop tremendously.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/dashersw/cote/issues/50#issuecomment-410520393, or mute the thread https://github.com/notifications/unsubscribe-auth/AWmoggrvvbhzh2yRetjGFiM5NDpssZS6ks5uNvOBgaJpZM4N2fA_ .
It feels very awkward that there are no better alternatives at the moment.
axon makes use of node-amp-message and node-amp.
The only starting point is in amp's documentation:
AMP is a simple versioned protocol for framed messages containing zero or more "arguments". Each argument is opaque binary, thus you may use JSON, BSON, msgpack and others on top of AMP. Multiple argument support is used to allow a hybrid of binary/non-binary message args without requiring higher level serialization libraries like msgpack or BSON.
All multi-byte integers are big endian. The version
and argc
integers are stored in the first byte, followed by a sequence of zero or more <length>
/ <data>
pairs, where length
is a 32-bit unsigned integer.
0 1 2 3 4 <length> ...
+------------+----------+------------+
| <ver/argc> | <length> | <data> | additional arguments
+------------+----------+------------+
Apart from this, we need to document how axon behaves with disconnects, reconnects, and especially queues, where for example the requesters store the requests until a responder is available.
In the end this also means writing amp, amp-message, axon, and cote in every other language. Although tests in each repo may help with the spec, it seems like a huge effort. What language would you start with? The starting point should be documenting and porting amp first, which is around ~200 lines in total. Then amp-message, and finally axon's req, rep, pub-emitter and sub-emitter components with its queue plugin.
Phew! That sounds like a lot. I think the key could be porting to a language with lots of bindings (like C) - but that could be a massive effort. Let me take a look at amp/-message/axon and estimate how hard it'll be before deciding.
Another option would be to use Golang - it seems to have bindings to C that could be used. This would be easier to code but probably somewhat harder to reuse.
Another option!
The first line of axon's description says:
Axon is a message-oriented socket library for node.js heavily inspired by zeromq.
Would you be against porting cote to use zeromq? Boom! Cross language support with a stable, rock-solid socket backend. I'd be happy to help here too.
As I have earlier said, zeromq was 35-50 times slower than axon in my tests — I wouldn’t therefore switch. Maybe I’m using it wrong, though.
Good point! Could we look at nanomsg / nng and see if it performs much better?
For ZeroMQ, our stated mission was "Fastest. Messaging. Ever." This is a nice, and nearly impossible answer to a problem we could all agree on: namely, the slow, bloated technology available at that time. However, my co-founder Martin and I had conflicting goals. He wanted to build the best software possible, while I wanted to build the largest community possible. As the user base grew, his dramatic changes, which broke existing applications, caused increasing pain. In that case, we were able to make everyone happy (Martin went off to build a new library called "Nano").
I found nng to be less maintained, with lacking cross-platform support. Overall it didn’t seem so reliable. Go sounds like a good opportunity though.
Ok. I'll try porting axon/amp to Go and see how that goes.
Did anybody consider using NATS instead of axon? I don't know if they are comparable in terms of functionality, but NATS is supported in many different languages and I have heard it is quite performant.
Yes, but NATS requires a central server, and that's not inline with cote's zero-dependency approach.
Ah. Well, it is only a single executable. But I understand the principles. (doesn't cote optionally leverage redis? or did I misunderstand something?)
Actually, since the NATS server is just a single, statically linked executable, you could just bundle it with the Node distribution and invoke it. I don't think it is so much a zero-dependency issue as much as that it seems to violate a the decentralized approach. Of course, the README outlines how that approach is problematic anyway. It seems that practical concerns are pushing things in the direction of having some centralized discovery system anyway. But I don't really know very much about the cote architecture so I could be completely off base. But I would not that adding redis
is a much bigger issue than adding NATS since NATS is just a single executable.
Redis is also just a single executable, depending on from where you look at it. The issue is as you said; violating decentralization — now you also have to care about the high availability of NATS servers. This is true in Redis as well, but Redis is offered as an alternative, not as the only solution. In this case if you want to go multi-language, you would have to use NATS, and this would change how cote operates in Node.js as well. I still believe rewriting 2000 lines in multiple languages is a better approach, that could be solved with the help from the community.
Hey any update on this topic? The project looks amazing but I'd rather not be locked to nodejs only.
There’s been no work on this — however if anyone wants to pick it up, I can help.
Very interesting subject ! I just started using cote with nodejs but because of various reasons I would like also to connect services written using another language. C will be my target and a cross platform library will be the best. I'm also thinking to micro-controllers (ESP32, STM32...) who can take advantage of this.
I have worked with axon in the past and I confirm it's really fast for example compared to zeromq (I also made a benchmark of this). For me the protocol is quite clear and not so difficult to implement in another language. As it was said previously, it's mainly socket stuff.
Actually I'm less aware of the cote part itself : how the discovery is done, what is the port strategy, etc. @dashersw do you have a piece of documentation about the internals of cote ? Even if it is a draft or something not fully documented, as soon as it's up to date with the current cote implementation, I'm interested.
Then will see how it's possible to switch in C language, I would like to have a global overview before starting working on this.
Joel
@myfreescalewebpage Hello Joel! cote is in fact a thin, smart layer on top of axon, coupled with node-discover. We currently don't have detailed docs, but what it does is to use (a fork of) node-discover to discover nodes on either multicast, broadcast, or redis, and then based on their advertisement objects (depending on their component type) establish a connection to the newly discovered object.
As a starting point, responder component is a great place to start — you can easily see how cote brings together axon and node-discover. The other components follow suit.
@dashersw writing from this account (I'm @myfreescalewebpage too). Thanks for your answer.
I had a look and it doesn't seems very complicated. Moreover the cote tools/examples such as monitor and the standard tools for example wireshark will help.
I have started converting amp-message and axon yesterday. After few hours I have quite finished the libs and written pub / sub examples, works like a charm but need to test again and again and to develop rep / req ... examples in C now. The API will be very closed to the nodejs version so it's possible to easily switch from one language to the other.
Will then look after node-discovery, but seems not so much complicated too (UDP socket).
I will indicate here when I publish the libs :-)
Joel
You are amazing! 🙏
Starting right now with Axon translated to : C https://github.com/joelguittet/c-axon using AMP message in C : https://github.com/joelguittet/c-amp. Almost working on Linux OS, need to be finalized, API should not move now.
Currently working on discover. Scheduled to have a cote version in C by mid December.
Will then work on other platform, thinking right now to FreeRTOS to address MCUs.
Joel
Now published Discover in C : https://github.com/joelguittet/c-discover.
Starting working on cote itself now!
Joel
Wow, @joelguittet, that's tremendous progress! Keep up the fantastic work!
@dashersw and all following this subject,
C cote version is now available at https://github.com/joelguittet/c-cote :-)
Coming soon:
Some modifications may be done due to above work in progress, but the c-cote library API should not change now.
I will be happy to have comment/suggestions on this job, people should use https://github.com/joelguittet/c-cote/issues for that.
@dashersw I have also notice several possible improvements that I will share with you creating a new issue for you.
Enjoy! Joel
Are there any plans to draw up a spec for the various communication elements (particularly service discovery)? To perhaps allow implementations in other languages? A key aspect of micro-services for me (and I expect many others) is the ability to use different languages for different services (as appropriate). I appreciate this library is primarily aimed at Node.js but if there was at least a spec it would open up the possibility of using it in a multi-language environment.