[nanomsg] NNG bindings report (C++, SWIG, C#)

  • From: Michael Powell <mwpowellhtx@xxxxxxxxx>
  • To: "nanomsg@xxxxxxxxxxxxx" <nanomsg@xxxxxxxxxxxxx>
  • Date: Sun, 5 Nov 2017 18:06:18 -0500

Dear Fellow Msg'ers:

I felt it was time to provide a little feedback to my fellow travelers
concerning my bindings progress, especially regarding the state of
NNG. To be clear, this is couched in the fact that NNG is still very
much under development, about which the community deserves to know for
itself. But don't take my word for it; do feel free to conduct your
own investigations, and I welcome constructive feedback as well.

Thus far I have successfully written, more than less, two language
level bindings for the NNG C code. First was a C++ binding, followed
by an attempted SWIG conversion to C#, and next a direct binding to
C#/.NET.

First, C++. I believe I've provided C++ API interfaces for NNG
features up to and including the AIO support. I have also provided
Catch based unit testing, which is directly based on the C API unit
tests. I wrote several other more focused unit tests, such as for
messaging parts, and around message pipe. Things of this nature. But
for a couple of binding quirks, and with a hat tip to Garrett
explaining some nuances along the way, the binding has gone pretty
well in my opinion.

https://github.com/mwpowellhtx/nngcpp/

I then took a fairly deep gander at a possible SWIG mapping from C++
to C#, with, shall we say, mixed results. I think the notion of SWIG
holds promise, and I cannot rule it out with more of a time
commitment. However, the SWIG ecosystem just suffers from poorly
organized documentation; to be fair, I cannot fault the SWIG
community, though, owing to the fact that it is all volunteer. It is
what it is, and I struggled, at best, as a result. So, that to say, I
will not rule it out, at which point I became curious what sort of
progress I would make with a direct C# language binding. So I did
exactly that and put SWIG on the shelf for the time being; I may
circle back for it or not, I do not know yet.

I am pleased to report that I have been making stellar progress this
week on the direct C# bindings. Some of that I attribute to C# and
.NET in general being among my strengths; but also due to the fact
that it has been relatively easy to hook into the C API DLL calling
conventions. In fact, that's been extremely easy to do. Today, as a
matter of fact, I just introduced MessagePipe to the C# API, with
fairly straightforward unit testing to boot.

https://github.com/mwpowellhtx/csnng

Next, I will be looking closely at the Async I/O; this could be
interesting, because I hope to leverage C#/.NET Task oriented async
features at the same time. If the C API hooks go as smoothly as the
rest, I don't expect any major issues, but we'll see; I remain
cautiously optimistic here. There are a couple of caveats enumerated
below among the ugly truths, however.

Before moving on, also, I have not quite got all the unit testing done
that I'd like to do, especially around obvious accessible API, as
contrasted with the C++, in which I've taken one or two side long
liberties that could be considered by some (you know who you are) to
be rather, shall we say, unconventional. As such, some of the
transport unit testing just does not make as much sense to do in C#,
because the API are standing on NNG internals in order for them to
work. That being said, for the most part, it is working pretty well so
far around core NNG competencies.

Now for some ugly truths about the API that I've learned thus far.

* As long as you maintain homogeneous transport usage, I think you're
probably safe to do so.

* Additionally, as long as you are running in a single thread, this
also seems pretty safe to do so thus far.

* I will also caveat, I have not performed much in the way of
scaleability testing, in threads, or at volume, yet.

C++ unit testing was fine with both of these, but the unit tests were
also pretty much focused, and ran sequentially. With C# unit testing,
well, that is another story:

* As long as I run a single transport, one test fixture at a time,
things ran successfully to completion. I would even venture to guess
that running multiple test fixtures in sequential mode would also
work. However, that is untried at this moment. My contention here is
that it is unrealistic to expect consumers would be single threaded,
but rather multi-threaded, at least.

* The rub, when you mix multiple, concurrently running threads, and/or
heterogeneous transports, you are faced with severe problems. For
instance, maybe you want to do IPv6 for external clients, and Inproc
for internal ones. It is a problem so much so that my unit tests,
which are powered by Visual Studio 2015, ReSharper, and xUnit, fall
flat on their face straight out of the gate.

  - I've documented this for Garrett ad nauseam, ad infinitum,
including evidence that this is not an "address reuse" issue, and the
boilerplate unit tests, based directly on his C unit tests, also have
not changed. At least not beyond obvious language level
simplification.

  - I have intentionally maintained logical consistency from the C
unit tests for precisely the reason that there must be a common
talking point when things do go wrong, especially against which to
compare notes. At a couple of key moments during the C++ maturation
this approach did make a huge difference. Same holds true for the C#
binding.

  - Careful analysis of the code will show that, and I will let that
body of work speak for itself as an exercise for the reader. The
bindings are there, whether in C++ or in C#, and work very well.

* Finally, I don't like getting into interpersonal junk, but I will
preface by saying, if I've got a correction to make, I like to own it
and make it right. However, Garrett can do no wrong. Perhaps that is
the benevolent dictator in him speaking. Certainly, if I have over
taxed him, that is my fault. I just see it as routine OSS community
engagement, demonstrated by a willingness to edify one's fellow
travelers.

  - Whatever the case may be, there comes a point when the trenches
are too deep, or the stone walls too high, and one has to make a
decision whether forge ahead or make contingency plans. I'm not sure
I'm quite at that point yet, but time will tell.

  - Giving credit where credit is due, taking absolutely nothing away
from his contribution to Nanomsg or NNG whatsoever, he knows his
stuff. I just think one must be open to critique and constructive
criticism without necessarily disparaging the community, whether
individually or at large, if one wants to survive for very long in the
wild.

In conclusion, I think NNG has potential, but does have a couple of
serious defects which require attention, as I've enumerated here. From
one professional to another, looking forward to a positive future
employing messaging frameworks like NNG in interesting and productive
ways.

Cheers,

Michael Powell

Other related posts: