ojosilva
ojosilva

Reputation: 2094

How to get connections in Mongo through driver

The system I work on uses the connection table (inprog array) in Mongo to monitor and control system availability and concurrency. This is achieved with the wonderful $cmd.sys.inprog collection.

One can get a nice list of connected clients from the mongo client:

db.getCollection('$cmd.sys.inprog').findOne({ $all: 1 }).inprog

Using the Perl driver, the only way I was able to run that command was with:

$db->eval( q{ db.getCollection('$cmd.sys.inprog').findOne({ $all: 1 }) } )->{ inprog };

But now eval has been deprecated and is generating a load of deprecation warnings in our Mongo log.

The following alternative method does not work from the Perl driver:

$db->get_collection('$cmd.sys.inprod')->find_one({ '$all': 1 })->{inprog};
# fails with "Invalid collection name"

Neither from the Node Mongo driver, so it's not just the Perl driver:

db.collection('$cmd.sys.inprog').findOne({$all:1});
# fails with invalid connection name just the same

Also, I couldn't find a $db->run_command(...) that would do this.

Are there any alternatives to eval to get the inprog list that will work from the Mongo drivers?

Upvotes: 1

Views: 279

Answers (2)

ojosilva
ojosilva

Reputation: 2094

I've found a way to do this with db.runCommand().

$client->get_database('admin')->run_command([ 'currentOp' => 1, '$all' => 1 ])->{inprog};

Basically, the currentOp command will receive the command option $all: 1 and that will resolve the call just the same as the previous collection.

It also works in Node:

const db = await mongo.connect('mongodb://localhost:27017/admin');
db.command({ "currentOp": true, $all: 1 });

Upvotes: 1

xdg
xdg

Reputation: 2995

That collection name isn't a real collection; it's a pseudo-command and was removed in the 3.6 server per SERVER-30181. You can use the currentOp command instead.

Note that currentOp is eventually going away in favor of the $currentOp aggregation stage. This works in the shell using db.aggregate but drivers don't currently support database-level (vs collection-level) aggregation pipelines. (That feature is currently on the roadmap for the 4.2-era drivers.)

Upvotes: 4

Related Questions