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.

MyNatsClient - It flushes, but so can you

I finally managed to beat the official client in some metrics! This means that performance is finally good enough for a release!!!

The big difference in the producer side was that MyNatsClient was calling Flush for each send, while the official client was doing this on a separate thread.

There's some awesome constructs in the official client, like e.g. stashing away non flushed data in case of disconnect etc. which then is dispatched on reconnect (if any). I've chosen to go a more manual or simple way in not having Flush being done in the background. Instead, by default it's done for each Publish. How-ever, you can turn this off and flush your self. Lets have a look.

The default behaviour is PubFlushMode.Auto, but you can switch this for Manual:

var cnInfo = new ConnectionInfo(hosts) {
    PubFlushMode = PubFlushMode.Manual //Default is Auto
};

Now, if you call Pub there will only be a flush, if the BufferedStream needs to, so to make sure that data is flushed, you need to call client.Flush() or client.FlushAsync().

client.Pub("mysubject", "My message1");
client.Pub("mysubject", "My message2");
client.Flush();

There's is also client.PubMany which will Flush when buffer is full or when your injected delegate is done:

client.PubMany(p => {
  p.Pub("mysubject", "My message1");
  p.Pub("mysubject", "My message2");
});
//Here it will have been flushed

The PubMany method will sync-lock around all calls to Pub instead of for each call.

Metrics

So, running with PubFlushMode.Manual and calling Flush after each batch provided some far better metrics. I'm NOT using PubMany in these timings.

Since we are sending string messages, the official client also includes the time for doing Encoding.UTF8.GetBytes(message) which my client does underneath.

Also note, I'm not forcing a Flush when using the official client, but instead letting it do it's background flush.

You can find the sample code for timing this in the repo:






Feel free to look into it and give me feedback on API etc.

Cheers,

//Daniel

View Comments