Well not really, obviously we shall Flush but let me provide you with some context. In my effort of putting together a .NET client for NATS time has eventually come to get it more performant. This time I'm attacking BufferedStream.Flush. In my current code, I can push 600000msg/s with a call to Flush on every cycle. Without it, much, much, more.
The Official client is using a background flusher thread construct for flushing and it also notifies this after a Publish. My initial thought was:
I don't want that
But then again, the guys behind it seem really skilled and has lots of experience so my second thought was:
Or do I?
I could see that the responsibility instead would be put on the user of the client:
public void Usage(INatsClient client) {
client.Publish("foo", "test one");
client.Publish("foo", "test two");
client.Flush();
}
This could also be expressed via some block construct API thing:
public void Usage(INatsClient client) {
//When enough publish calls has been done
//and buffer is full it will Flush
//It will also Flush at the end
client.PublishMany(p => {
p("foo", "test one");
p("foo", "test two");
});
}
I don' really see any downside with this, but it only helps when the usage pattern is batch oriented.
So what about if there's a background FlushTask?
public void Usage(INatsClient client) {
//Each call to Publish notifies FlushTask
client.Publish("foo", "test one");
client.Publish("foo", "test two");
//You can force one if wanted
client.Flush();
}
The downside of a FlushTask would be: There's a slight risk that something isn't sent after the call to Publish has been done due to failure in between. This risk can how-ever be reduced by optionally allowing a client.Flush() when the user needs one.
What's your take on this? Feel free to share your thoughts?
//Daniel