[nanomsg] Re: [nanomsg] RE: [Non-DoD Source] [nanomsg] status of nng… another update

  • From: "Garrett D'Amore" <garrett@xxxxxxxxxx>
  • To: "nanomsg@xxxxxxxxxxxxx" <nanomsg@xxxxxxxxxxxxx>
  • Date: Mon, 13 Mar 2017 08:48:53 -0700

Sadly I don’t have any such paper already written.  For my own use cases,
I’d probably write in Go first, and indeed the Go version (mangos) has
worked out really really well.

If I was not worried about interoperability I might consider something like
libdill as foundation layer, and then writing the same way I’d have done
with Go.  Unfortunately, I don’t think the state of C is such that one can
safely use any of the various coroutine libraries in a library intended for
broad consumption — there are simply too many caveats (no interop with real
threads, limits on stack analysis tools, compiler optimizations, etc.)
 Really we need coroutines in C itself, and I’ve come to believe that the C
committee would do us all a big favor by adding coroutine support into the
language properly.  It seems to me that this would not be very onerous for
compiler folks to add, and frankly the cost of doing so would be smaller
than the cost of creating the real C11 threads.

I’m not a big fan of writing in another language and providing C bindings….
that may make it easier for you to work with, but it makes the library more
complex for your consumers, and can limit portability to other platforms.
For example, Rust isn’t available on many embedded targets.  In fact, even
going the other way, where a C core is used and FFI bindings are used to
map the library to other languages, feels kind of dirty to me.  I’d far
rather have good RFCs for what the protocols are, and native language
implementations.  This is more work for sure, but for the languages where
the native code exists, I believe the result is superior for all parties
concerned.

In terms of shim vs. going native to the OS target — the latter is
generally preferable if you have a comfortable development environment.
Sometimes you don’t, or need to work with parties who don’t have access to
real hardware.  (This comes up in embedded work.)  In *those* cases
simulation layers can allow progress to be made.  That said, it also helps
if you can isolate your access to OS-specific services into a portability
layer.  This allows the greatest portability, and allows work to be done on
multiple platforms.  For example, I primarily work on macOS (my desktop)
these days, but the ability to quickly run the code on Linux gives me
access to some extra tooling (valgrind in particular), which is immensely
helpful.

The main thing I’d say, if you’re planning to undertake such a project, is
start by determining what your goals are.  nanomsg has a pretty broad set
of goals which makes a lot of what we had to do harder (interop with
~everything, wide portability, high scalability, use in environments to
which I likely will never have access,  etc.)  If your goals are more
limited in scope, you can probably take a greatly simplified approach — for
example if I didn’t have to worry about portability or coexistence with OS
threads, I’d have been able to use a coroutine library pretty darn easily,
and saved myself many hours of work.

 - Garrett



On Mon, Mar 13, 2017 at 6:25 AM, Karan, Cem F CIV USARMY RDECOM ARL (US) <
cem.f.karan.civ@xxxxxxxx> wrote:

Garrett, this is not a request to change how nng works, it's just a
request for your opinion if you had to do it all over again, so please take
it in that grain.

If you had to do it all over again with all of the knowledge you now have,
would you use callbacks, or would you use something else (green threads,
coroutines, etc.)?  Would you write it all in C, or would you write the
core in another language and provide bindings in C (and other languages)?
Would you make the core work directly with calls the OS provides, or would
you develop some kind of shim layer so that you could test the core in
simulation before making it live?   I'm thinking about various methods of
writing my own communications library, and would like to get your opinions
on what you think worked well, and what would need to be changed.

For those wondering why I would consider writing my own, it's because my
target is unreliable and semi-reliable communications similar to what the
Licklider transmission protocol (https://en.wikipedia.org/
wiki/Licklider_Transmission_Protocol) was designed to handle, but over
networks whose topology is constantly in flux.  In my ideal world the heart
of the code could be ported over to real networks after being tested out on
a simulator, but this requires some careful design and planning, which is
why I wanted to see what Garrett has learned.

Actually, now that I think about it, Garrett, if you have a 'lesson's
learned' type of paper or article that you've written, I'd love to have a
pointer to it so I can see the lay of the land before I get there...

Thanks,
Cem Karan

-----Original Message-----
From: nanomsg-bounce@xxxxxxxxxxxxx [mailto:nanomsg-bounce@xxxxxxxxxxxxx]
On Behalf Of Garrett D'Amore
Sent: Saturday, March 11, 2017 12:07 AM
To: nanomsg@xxxxxxxxxxxxx
Subject: [Non-DoD Source] [nanomsg] status of nng… another update

I’ve finished the first and hardest part of making all the patterns
callback-driven.  This also eliminates a number of threads I was firing up
per socket.

Things still aren’t ready really, and in particular the TCP and IPC
transports for POSIX need to be altered significantly.  Still most of the
groundwork for them is already done.  Windows will follow thereafter
(and will actually be easier since I modeled much on IOCP.)

At this point, I think I’m probably only a week or two from being ready
for others to start experimenting with it, and merging it into the
master branch.

Stay tuned.

 - Garrett


Other related posts: