How to support overlapped transactions

Hi, when reading this documentation: https://docs.newrelic.com/docs/agents/nodejs-agent/supported-features/nodejs-custom-instrumentation#background-txn, specifically:

var nr = require(‘newrelic’)
var redis = require(‘redis’).createClient()

setInterval(nr.createBackgroundTransaction(‘update:cache’, function () {
var newValue = someDataGenerator()

redis.set(‘some:cache:key’, newValue, function () {
nr.endTransaction() // End the transaction once redis is done
})
}), 30000) // Every 30s

What if the redis operation takes more than 30 seconds (I know Redis is supposed to be fast, just using it as an example), doesn’t this piece of code create a new transaction after 30s while redis is still processing the operation and has not ended the previous transaction?

I’m working on a program to handle messages from RabbitMQ, the handling of each message could take a minute or so (which talks to some external services asynchronously), I want to track the performance of each message processing, what’s the best way to do this? I thought about using only 1 background transaction and createTracer for each message, but in the case of RabbitMQ, the transaction will never end until the program exits because the program subscribes to the queue for new messages.

Thanks.

You are correct that the background transaction example with setInterval would not work well if the transaction took more than 30s. In that case, perhaps scheduling the next task after finishing would be better instead of using setInterval.

As far as message processing, it would not work to use a single transaction for all messages since the transaction would never end and therefore never be reported. Instead, you could create a transaction for each message that is being processed.

Note that we are planning to introduce an API for instrumenting message queues in the near future. This will likely include out-of-the-box instrumentation for RabbitMQ.

Thanks for the response. Any suggestion about how to track the performance of above example (assuming Redis is very slow and takes more than 30 seconds) ?

You could do something like: start transaction, run the task to completion, end transaction, schedule next run using setTimeout, repeat.

1 Like