danielwertheim

danielwertheim


notes from a passionate developer

Share


Sections


Tags


Disclaimer

This is a personal blog. The opinions expressed here represent my own and not those of my employer, nor current or previous. All content is published "as is", without warranty of any kind and I don't take any responsibility and can't be liable for any claims, damages or other liabilities that might be caused by the content.

Flush or not to Flush that is the Question

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

View Comments