summaryrefslogtreecommitdiff
path: root/src/mongo/db/clientlistplugin.cpp
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-12-03 10:17:12 -0500
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-12-03 19:48:31 -0500
commita07f232ff52244a70244afe0b0ba00f77fe044ae (patch)
treec94f287284037793b8beafe9782014590a1f51b0 /src/mongo/db/clientlistplugin.cpp
parent3b1d97d430a229bf57c46bc7bc4977801b5bb553 (diff)
downloadmongo-a07f232ff52244a70244afe0b0ba00f77fe044ae.tar.gz
SERVER-14062 Remove the global OperationContext registry
Diffstat (limited to 'src/mongo/db/clientlistplugin.cpp')
-rw-r--r--src/mongo/db/clientlistplugin.cpp203
1 files changed, 111 insertions, 92 deletions
diff --git a/src/mongo/db/clientlistplugin.cpp b/src/mongo/db/clientlistplugin.cpp
index 31381c87a16..607c37f4131 100644
--- a/src/mongo/db/clientlistplugin.cpp
+++ b/src/mongo/db/clientlistplugin.cpp
@@ -28,6 +28,8 @@
#include "mongo/platform/basic.h"
+#include <boost/thread/locks.hpp>
+
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_session.h"
@@ -43,64 +45,8 @@
#include "mongo/util/stringutils.h"
namespace mongo {
-
- class OperationsDataBuilder : public GlobalEnvironmentExperiment::ProcessOperationContext {
- public:
- OperationsDataBuilder(std::stringstream& stringStream)
- : _stringStream(stringStream) {
-
- }
-
- virtual void processOpContext(OperationContext* txn) {
- using namespace html;
-
- CurOp& co = *(txn->getCurOp());
-
- _stringStream << "<tr><td>" << txn->getClient()->desc() << "</td>";
-
- tablecell(_stringStream, co.opNum());
- tablecell(_stringStream, co.active());
-
- // LockState
- {
- Locker::LockerInfo lockerInfo;
- txn->lockState()->getLockerInfo(&lockerInfo);
-
- BSONObjBuilder lockerInfoBuilder;
- fillLockerInfo(lockerInfo, lockerInfoBuilder);
-
- tablecell(_stringStream, lockerInfoBuilder.obj());
- }
-
- if (co.active()) {
- tablecell(_stringStream, co.elapsedSeconds());
- }
- else {
- tablecell(_stringStream, "");
- }
-
- tablecell(_stringStream, co.getOp());
- tablecell(_stringStream, html::escape(co.getNS()));
- if (co.haveQuery()) {
- tablecell(_stringStream, html::escape(co.query().toString()));
- }
- else {
- tablecell(_stringStream, "");
- }
-
- tablecell(_stringStream, co.getRemoteString());
-
- tablecell(_stringStream, co.getMessage());
- tablecell(_stringStream, co.getProgressMeter().toString());
-
- _stringStream << "</tr>\n";
- }
-
- private:
- std::stringstream& _stringStream;
- };
-
namespace {
+
class ClientListPlugin : public WebStatusPlugin {
public:
ClientListPlugin() : WebStatusPlugin( "clients" , 20 ) {}
@@ -125,31 +71,35 @@ namespace {
<< "</tr>\n";
- OperationsDataBuilder opCtxDataBuilder(ss);
- getGlobalEnvironment()->forEachOperationContext(&opCtxDataBuilder);
+ _processAllClients(ss);
ss << "</table>\n";
-
}
- } clientListPlugin;
+ private:
- class CommandHelper : public GlobalEnvironmentExperiment::ProcessOperationContext {
- public:
- CommandHelper( MatchExpression* me )
- : matcher( me ) {
- }
+ static void _processAllClients(std::stringstream& ss) {
+ using namespace html;
+
+ boost::mutex::scoped_lock scopedLock(Client::clientsMutex);
+
+ ClientSet::const_iterator it = Client::clients.begin();
+ for (; it != Client::clients.end(); it++) {
+ Client* client = *it;
+ invariant(client);
+
+ // Make the client stable
+ boost::unique_lock<Client> clientLock(*client);
+ const OperationContext* txn = client->getOperationContext();
+ if (!txn) continue;
+
+ CurOp* curOp = txn->getCurOp();
+ if (!curOp) continue;
- virtual void processOpContext(OperationContext* txn) {
- BSONObjBuilder b;
- if ( txn->getClient() )
- txn->getClient()->reportState( b );
- if ( txn->getCurOp() )
- txn->getCurOp()->reportState( &b );
- if ( txn->lockState() ) {
- StringBuilder ss;
- ss << txn->lockState();
- b.append("lockStatePointer", ss.str());
+ ss << "<tr><td>" << client->desc() << "</td>";
+
+ tablecell(ss, curOp->opNum());
+ tablecell(ss, curOp->active());
// LockState
{
@@ -159,24 +109,37 @@ namespace {
BSONObjBuilder lockerInfoBuilder;
fillLockerInfo(lockerInfo, lockerInfoBuilder);
- b.append("lockState", lockerInfoBuilder.obj());
+ tablecell(ss, lockerInfoBuilder.obj());
}
- }
- if ( txn->recoveryUnit() )
- txn->recoveryUnit()->reportState( &b );
- BSONObj obj = b.obj();
+ if (curOp->active()) {
+ tablecell(ss, curOp->elapsedSeconds());
+ }
+ else {
+ tablecell(ss, "");
+ }
- if ( matcher && !matcher->matchesBSON( obj ) ) {
- return;
- }
+ tablecell(ss, curOp->getOp());
+ tablecell(ss, html::escape(curOp->getNS()));
+
+ if (curOp->haveQuery()) {
+ tablecell(ss, html::escape(curOp->query().toString()));
+ }
+ else {
+ tablecell(ss, "");
+ }
+
+ tablecell(ss, curOp->getRemoteString());
+
+ tablecell(ss, curOp->getMessage());
+ tablecell(ss, curOp->getProgressMeter().toString());
- array.append( obj );
+ ss << "</tr>\n";
+ }
}
- BSONArrayBuilder array;
- MatchExpression* matcher;
- };
+ } clientListPlugin;
+
class CurrentOpContexts : public Command {
public:
@@ -219,14 +182,70 @@ namespace {
filter.reset( res.getValue() );
}
- CommandHelper helper( filter.get() );
- getGlobalEnvironment()->forEachOperationContext(&helper);
-
- result.appendArray( "operations", helper.array.arr() );
+ result.appendArray("operations", _processAllClients(filter.get()));
return true;
}
+
+ private:
+
+ static BSONArray _processAllClients(MatchExpression* matcher) {
+ BSONArrayBuilder array;
+
+ boost::mutex::scoped_lock scopedLock(Client::clientsMutex);
+
+ ClientSet::const_iterator it = Client::clients.begin();
+ for (; it != Client::clients.end(); it++) {
+ Client* client = *it;
+ invariant(client);
+
+ BSONObjBuilder b;
+
+ // Make the client stable
+ boost::unique_lock<Client> clientLock(*client);
+
+ client->reportState(b);
+
+ const OperationContext* txn = client->getOperationContext();
+ if (txn) {
+
+ // CurOp
+ if (txn->getCurOp()) {
+ txn->getCurOp()->reportState(&b);
+ }
+
+ // LockState
+ if (txn->lockState()) {
+ StringBuilder ss;
+ ss << txn->lockState();
+ b.append("lockStatePointer", ss.str());
+
+ Locker::LockerInfo lockerInfo;
+ txn->lockState()->getLockerInfo(&lockerInfo);
+
+ BSONObjBuilder lockerInfoBuilder;
+ fillLockerInfo(lockerInfo, lockerInfoBuilder);
+
+ b.append("lockState", lockerInfoBuilder.obj());
+ }
+
+ // RecoveryUnit
+ if (txn->recoveryUnit()) {
+ txn->recoveryUnit()->reportState(&b);
+ }
+ }
+
+ const BSONObj obj = b.obj();
+
+ if (!matcher || matcher->matchesBSON(obj)) {
+ array.append(obj);
+ }
+ }
+
+ return array.arr();
+ }
+
} currentOpContexts;
} // namespace