SwiftNIO: How "expensive" is transformation in each ChannelHandler? - nio

Checking this tutorial: https://rderik.com/blog/understanding-swiftnio-by-building-a-text-modifying-server/
One thing I do not understand that the main point using NIO directly is to increase speed of a backend service.
But, when we has this pipe:
Client: hello
|
v
Server
|
v
BackPressureHandler (Receives a ByteBuffer - passes a ByteBuffer)
|
v
UpcaseHandler(Receives a ByteBuffer - passes a [CChar])
|
v
VowelsHandler(Receives a [CChar] - passes a ByteBuffer)
|
v
ColourHandler(Receives a ByteBuffer - passes a ByteBuffer)
|
v
Client: receives
H*LL* (In green colour)
parameter gets transformed many times. In UpcaseHandler NIOAny -> ByteBuffer -> string -> CChar -> NIOAny
then in VowelsHandler again: NIOAny -> ByteBuffer -> string -> CChar -> NIOAny
What is the advantage to have so many independent handlers?
If server receive a 'flat' JSON, is it worth to process it with with JSONEncoder, if speed, each microseconds are critical? try JSONEncoder().encode(d2)
Or is it worth, is it common to implement own JSON processor. I.e. an event driven JSON parser?

I think it's useful to use things like an UppercasingHandler when trying to learn and understand SwiftNIO. In the real world however, this is too fine grained for a ChannelHandler.
Typically, the use-case for a ChannelHandler is usually one of the following (not exhaustive):
a whole network protocol (example NIOSSLClientHandler which adds TLS for a client connection)
added value that may be useful with multiple protocols (such as the BackpressureHandler)
added value that may be useful for debugging (example NIOWritePCAPHandler)
So whilst the overhead of a ChannelHandler isn't huge, it is definitely not completely free and I would recommend not overusing them. Abstraction is useful but even in a SwiftNIO-based application or library we should try to express everything as ChannelHandlers in a ChannelPipeline.
The value-add of having something in a ChannelHandler is mostly around reusability (the HTTP/1, HTTP/2, ... implementations don't need to know about TLS), testability (we can test a network protocol without actually needing a network connection) and debuggability (if something goes wrong, we can easily log the inputs/outputs of a ChannelHandler).
The NIOWritePCAPHandler for example is a great example: In most cases, we don't need it. But if something goes wrong, we can add it in between a TLS handler and say the HTTP/2 handler(s) and we get a plaintext .pcap file without having to touch any code apart from the code that inserts it into the ChannelPipeline which can even be done dynamically after the TCP connection is already established.
There's absolutely nothing wrong with a very short ChannelPipeline. Many great examples have just a few handlers, for example:
TLS handler <--> network protocol handler(s) [HTTP/1.1 for example] <--> application handler (business logic)

Related

How to create FMU slave and initialise FMU in C using Modelica's fmi headers

I'm creating a simple FMI demo system to try out FMI where I have 1 simulator connected to an FMU which computes the state of the system (represented as a number calculated from a closed-form equation) and another FMU that controls the system via a parameter in the closed-form equation. So the system looks something like
FMU-system <--> Simulator <--> FMU-control
In every iteration, I'm updating the system state based on 1 equation, and passing it to the control, which returns a parameter to be passed to the system.
I'm using FMI 2.0.3, and have read the specification. Right now I have 3 files, 1 to act as a simulator and 2 to act as the FMUs. But I'm having difficulties with the implementation of the FMUs and the initialisation of the simulator.
To initialise the FMU, my understanding is I need to call fmi2Instantiate which has this signature.
fmi2Component fmi2Instantiate(fmi2String instanceName, fmi2Type fmuType, fmi2String fmuGUID, fmi2String fmuResourceLocation, const fmi2CallbackFunctions* functions, fmi2Boolean visible, fmi2Boolean loggingOn);
But I don't know what to pass in the function for the GUID, resource location and callback function. How should I implement the callback function and initialisation?
Then to implement the FMU, my understanding is I need to implement fmi2SetReal, fmi2GetReal and fmi2DoStep, but I can't figure out how to implement them in terms of code. These are the signatures
fmi2Status setReal(fmi2Component c, fmi2ValueReference vr[], size_t nvr, fmi2Real value[])
fmi2Status getReal(fmi2Component c, fmi2ValueReference vr[], size_t nvr, fmi2Real value[])
fmi2Status doStep(fmi2Component c, fmi2Real currentCommunicationPoint, fmi2Real communicationStepSize, fmi2Boolean noSetFMUStatePriorToCurrentPoint)
But I can't figure out how to implement these functions. Is fmi2Component c meaningless here? And I suppose I have to do the system state computation for the FMU-system in doStep. How should I update the state and pass the code here?
Sorry if this is too many questions but I was trying to look for a tutorial too and I couldn't find any.
https://github.com/traversaro/awesome-fmi
This is a curated list of Functional Mock-up Interface (FMI) libraries, tools and resources.
There are non commercial tools available. Check them out, you will get idea to implement these functions for your application.
A good starting point to implement FMI support are the open source Reference FMUs (which recently also got a simple FMU simulator) and fmpy:
https://github.com/CATIA-Systems/FMPy
https://github.com/modelica/Reference-FMUs/tree/main/fmusim

Modular program design

My question is unfortunately badly formed as I'm not entirely certain to call what I'm trying to do. My apologies for that.
It came up since I'm trying to code a really basic browser that I want to implement in C and I was thinking about how best to go about it. The basic idea being something like libcurl (for network interaction) -> libxml2 (parse HTML) -> UI and then some manner of getting libcurl to accept GET or POST requests from the UI (haven't gotten to this point yet).
However, this approuch is severely limited, if I say want to check whether it's a PDF and then send it off to libpoppler before handing it to libxml2 I'll have to recode my entire program flow. Further, if I want to use parts of my program (say, the libcurl -> pdftohtml -> libxml2 part) and send it off to another program (for example w3m instead of my UI), I again don't see how I will manage that.
I could instead simply write a Perl or Python wrapper for curl, libxml2, etc, or do something along the lines of "curl example.com | parser | UI". However doing it in Perl or Python still seems like I'll have to recode my program logic every time I want to do something new, and piping everything seems inelegant. I would also like to do this in C if possible.
So my question is; what do one call this idea? I've been driving myself crazy trying to figure out how to search for a solution for a problem that I can't name. I know it has something to do with modularity, however I don't know what specifically and modularity is a very broad term. Secondly and optionally if anybody could point me in the direction of a solution I would appreciate that as well although it's not as important as what it's called.
Thanks to all who read this. :)
First I suggest you take a look at http://www.amazon.com/Interfaces-Implementations-Techniques-Creating-Reusable/dp/0201498413. Second most browsers are asynchronous so you are going to need a event library like libuv or libev. Also most modern websites require javascript to function properly, but adding a javascript engine to your browser would greatly complicate the project. I also don't see any mention of how you plan on parsing the http being sent to and from your browser, I suggest https://github.com/joyent/http-parser.
As for your question on control flow, I would have a function that parse's the response from the server and use's switch() to handle the various types of data being sent to your browser. There is a field in the http header which explains the content type and that way your browser should be able to call different functions based of what the content type is.
Also take a look at function pointers, both here Polymorphism (in C) and here How do function pointers in C work? . Function pointers would/could be a more eloquent way to solve your problem instead having large switch statements through out your code. With function pointers you can have one function that when called in your program behaves differently.
I will try to explain below with a browser as an example.
So lets say your browser just got back a http response from some server. The http response looks something like this in C.
struct http_res
{
struct http_header *header;
struct http_body *body
int (*decode_body)(char **);
};
So first your http parser will parse the http header and figure out if it's a valid response and if there's content, etc, etc. If there is content the parser will check the type and based off, if it's html, javascript, css, or whatever the parser will set the function pointer to point at the right function to decode the http body.
static int decode_javascript(char **body)
{
/* Whatever it takes to parse javascript from http. */
return 0;
}
static int decode_html(char **body)
{
/* Whatever it takes to parse html from http. */
return 0;
}
static int decode_css(char **body)
{
/* Whatever it takes to parse css from http. */
return 0;
}
int parse_http_header(struct http_res *http)
{
/* ... lots of other code to figure out content type. ... */
switch(body_content_type)
{
case BCT_JAVASCRIPT:
http->decode_body = &decode_javascript;
break;
case BCT_HTML:
http->decode_body = &decode_html;
break;
case BCT_CSS:
http->decode_body = &decode_css;
break;
default:
printf("Error can't parse body type.\n");
return -1;
}
return 0;
}
Now when we pass the http request to another part of the browser that function can call decode_body() in the http response object and it will end up with a decoded body it can understand, with out knowing what it's decoding.
int next_function(struct http_res * res)
{
char *decoded_body;
int rtrn;
/* Now we can decode the http body with out knowing anything about
it. We just call decode_body() and end up with a buffer with the
decoded data in it. */
rtrn = res->decode_body(&decoded_body);
if(rtrn < 0)
{
printf("Can't decode body.\n");
return -1;
}
return 0;
}
To make your program really modular at least in C, you would stick the various parts of your browser in different shared libraries, like the HTTP parser, event library, Javascript engine, html parser, etc, etc. Then you would create interfaces between each library and you would be able to swap out each library with a different one with having to change your program, you would link a different library at run time. Take a look at Dr Robert martin(uncle bob) he talks about this extensively. This talk is good but it lacks slides https://www.youtube.com/watch?v=asLUTiJJqdE , starts at 8:20. This one is also interesting, and it has slides: https://www.youtube.com/watch?v=WpkDN78P884 .
And finally nothing about C, perl or python means you will have to recode your program logic. You will have to design your program so that each module does not know about each other. The module knows about the interface and if you connect two modules that both "speak" the same interface you will have created a modular system. It's just like how the internet works the various computers on the internet do not need to know what the other computer is, or what it's doing, or it's operating system, all they need to know is TCP/IP and they can communicate with all the other devices on the internet.

What ZeroMQ socket type to use for inter process communication?

When I had two threads, I used PAIR socket type. But now I am using two processes that can be either on one machine or on different machines. I don't need requests and responses, I don't need sending to multiple nodes, etc. I need same thing that I had with PAIR (async, bidirectional), but with processes and with network. What socket types should I use?
Unfortunately, your world has gotten a bit more complicated. There's no direct analog to the PAIR/PAIR socket pairing in more widely distributed systems.
That said, if you keep roughly the same shape of the topology (two nodes connecting exclusively to each other and no other nodes) then you can pretty much achieve what you want using ROUTER/DEALER or even DEALER/DEALER (as you suggested in comments). Those sockets are sort of like REQ/REP, but they don't enforce a strict request/response communication pattern, they are entirely unrestricted, so in effect you get the same thing. The only problem comes if you intend to add more nodes, at which point you have to start managing things a little differently, in particular the DEALER socket doesn't allow you to choose which node you send to, it's strictly round robin.
But, doing that should get you what you're looking for (async, bidirectional).
The ROUTER socket type can require a little additional complexity since you need to keep track of the "identifier" of the other node to be able to send back to it (you can get this almost for free, especially in your case with just one peer, by using it directly out of the sent message). Because this is an exclusive pair, you can ignore the round-robin uncertainty introduced by the DEALER socket, and just go straight to DEALER/DEALER, which gives you an unrestricted message pattern and doesn't require any management of identities.
#Marko let me notice,
there is a principal separation between a ZMQ.SOCKET's (formal-communication-pattern) "type" and whatever a transport, one opts to .bind() / .connect() over
Once your architecture was happy (as you have written ) to work with PAIR/PAIR "session"
you may just without a single additional SLOC change the transport that is to be used
it works
Python 2.7.3 ...
>>> import zmq
>>> zmq.zmq_version()
'2.1.11'
>>> aZmqCONTEXT = zmq.Context() # --<BoCTX>-- [SideA] Node
>>> aZmqSOCKET = aZmqCONTEXT.socket( zmq.PAIR ) # here one decides about a type
>>> aZmqSOCKET.bind( "tcp://192.168.0.62:2027" ) # here is the transport // used to be ( "ipc://...")
>>> aZmqSOCKET.recv() # here the PAIR waits for 1st MSG
'aMSG from the opposite PAIR/PAIR zmq-session Node arrived via TCP-transport ... QED'
>>> aZmqSOCKET.setsockopt( zmq.LINGER, 0 ) # pre-termination tidy-up
>>> aZmqSOCKET.close()
>>> aZmqCONTEXT.term() # --<EoCTX>-- safe to clean-exit
>>>

What is a MsgPack 'zone'

I have seen references to 'zone' in the MsgPack C headers, but can find no documentation on what it is or what it's for. What is it? Furthermore, where's the function-by-function documentation for the C API?
msgpack_zone is an internal structure used for memory management & lifecycle at unpacking time. I would say you will never have to interact with it if you use the standard, high-level interface for unpacking or the alternative streaming version.
To my knowledge, there is no detailed documentation: instead you should refer to the test suite that provides convenient code samples to achieve the common tasks, e.g. see pack_unpack_c.cc and streaming_c.cc.
From what I could gather, it is a move-only type that stores the actual data of a msgpack::object. It very well might intended to be an implementation detail, but it actually leaks into users' code sometimes. For example, any time you want to capture a msgpack::object in a lambda, you have to capture the msgpack::zone object as well. Sometimes you can't use move capture (e.g. asio handlers in some cases will only take copyable handlers, or your compiler doesn't support the feature). To work around this, you can:
msgpack::unpacked r;
while (pac_.next(&r)) {
auto msg = result.get();
io_->post([this, msg, z = std::shared_ptr<msgpack::zone>(r.zone().release())]() {
// msg is valid here
}));
}

Only one write() call sends data over socket connection

First stackoverflow question! I've searched...I promise. I haven't found any answers to my predicament. I have...a severely aggravating problem to say the least. To make a very long story short, I am developing the infrastructure for a game where mobile applications (an Android app and an iOS app) communicate with a server using sockets to send data to a database. The back end server script (which I call BES, or Back End Server), is several thousand lines of code long. Essentially, it has a main method that accepts incoming connections to a socket and forks them off, and a method that reads the input from the socket and determines what to do with it. Most of the code lies in the methods that send and receive data from the database and sends it back to the mobile apps. All of them work fine, except for the newest method I have added. This method grabs a large amount of data from the database, encodes it as a JSON object, and sends it back to the mobile app, which also decodes it from the JSON object and does what it needs to do. My problem is that this data is very large, and most of the time does not make it across the socket in one data write. Thus, I added one additional data write into the socket that informs the app of the size of the JSON object it is about to receive. However, after this write happens, the next write sends empty data to the mobile app.
The odd thing is, when I remove this first write that sends the size of the JSON object, the actual sending of the JSON object works fine. It's just very unreliable and I have to hope that it sends it all in one read. To add more oddity to the situation, when I make the size of the data that the second write sends a huge number, the iOS app will read it properly, but it will have the data in the middle of an otherwise empty array.
What in the world is going on? Any insight is greatly appreciated! Below is just a basic snippet of my two write commands on the server side.
Keep in mind that EVERYWHERE else in this script the read's and write's work fine, but this is the only place where I do 2 write operations back to back.
The server script is on a Ubuntu server in native C using Berkeley sockets, and the iOS is using a wrapper class called AsyncSocket.
int n;
//outputMessage contains a string that tells the mobile app how long the next message
//(returnData) will be
n = write(sock, outputMessage, sizeof(outputMessage));
if(n < 0)
//error handling is here
//returnData is a JSON encoded string (well, char[] to be exact, this is native-C)
n = write(sock, returnData, sizeof(returnData));
if(n < 0)
//error handling is here
The mobile app makes two read calls, and gets outputMessage just fine, but returnData is always just a bunch of empty data, unless I overwrite sizeof(returnData) to some hugely large number, in which case, the iOS will receive the data in the middle of an otherwise empty data object (NSData object, to be exact). It may also be important to note that the method I use on the iOS side in my AsyncSocket class reads data up to the length that it receives from the first write call. So if I tell it to read, say 10000 bytes, it will create an NSData object of that size and use it as the buffer when reading from the socket.
Any help is greatly, GREATLY appreciated. Thanks in advance everyone!
It's just very unreliable and I have to hope that it sends it all in one read.
The key to successful programming with TCP is that there is no concept of a TCP "packet" or "block" of data at the application level. The application only sees a stream of bytes, with no boundaries. When you call write() on the sending end with some data, the TCP layer may choose to slice and dice your data in any way it sees fit, including coalescing multiple blocks together.
You might write 10 bytes two times and read 5 then 15 bytes. Or maybe your receiver will see 20 bytes all at once. What you cannot do is just "hope" that some chunks of bytes you send will arrive at the other end in the same chunks.
What might be happening in your specific situation is that the two back-to-back writes are being coalesced into one, and your reading logic simply can't handle that.
Thanks for all of the feedback! I incorporated everyone's answers into the solution. I created a method that writes to the socket an iovec struct using writev instead of write. The wrapper class I'm using on the iOS side, AsyncSocket (which is fantastic, by the way...check it out here -->AsyncSocket Google Code Repo ) handles receiving an iovec just fine, and behind the scenes apparently, as it does not require any additional effort on my part for it to read all of the data correctly. The AsyncSocket class does not call my delegate method didReadData now until it receives all of the data specified in the iovec struct.
Again, thank you all! This helped greatly. Literally overnight I got responses for an issue I've been up against for a week now. I look forward to becoming more involved in the stackoverflow community!
Sample code for solution:
//returnData is the JSON encoded string I am returning
//sock is my predefined socket descriptor
struct iovec iov[1];
int iovcnt = 0;
iov[0].iov_base = returnData;
iov[0].iov_len = strlen(returnData);
iovcnt = sizeof(iov) / sizeof(struct iovec);
n = writev(sock, iov, iovcnt)
if(n < 0)
//error handling here
while(n < iovcnt)
//rebuild iovec struct with remaining data from returnData (from position n to the end of the string)
You should really define a function write_complete that completely writes a buffer to a socket. Check the return value of write, it might also be a positive number, but smaller than the size of the buffer. In that case you need to write the remaining part of the buffer again.
Oh, and using sizeof is error-prone, too. In the above write_complete function you should therefore print the given size and compare it to what you expect.
Ideally on the server you want to write the header (the size) and the data atomically, I'd do that using the scatter/gather calls writev() also if there is any chance multiple threads can write to the same socket concurrently you may want to use a mutex in the write call.
writev() will also write all the data before returning (if you are using blocking I/O).
On the client you may have to have a state machine that reads the length of the buffer then sits in a loop reading until all the data has been received, as large buffers will be fragmented and come in in various sized blocks.

Resources