Permalink
Browse files

new killOp(opnumber)

  • Loading branch information...
1 parent 2c1085d commit 62522b905bf96e12abd5d176ad1b70c2cb669930 @dwight dwight committed Dec 22, 2009
Showing with 79 additions and 54 deletions.
  1. +2 −1 db/btree.cpp
  2. +2 −1 db/btreecursor.cpp
  3. +1 −0 db/client.cpp
  4. +27 −4 db/curop.h
  5. +16 −0 db/cursor.cpp
  6. +1 −30 db/cursor.h
  7. +1 −1 db/db.cpp
  8. +3 −2 db/dbcommands_admin.cpp
  9. +14 −10 db/instance.cpp
  10. +1 −1 db/jsobj.h
  11. +2 −1 db/reci.h
  12. +4 −0 jstests/basic1.js
  13. +5 −3 shell/db.js
View
@@ -24,6 +24,7 @@
#include "clientcursor.h"
#include "client.h"
#include "dbhelpers.h"
+#include "curop.h"
namespace mongo {
@@ -84,7 +85,7 @@ namespace mongo {
massert("assert is misdefined", f);
}
- checkForInterrupt();
+ killCurrentOp.checkForInterrupt();
assertValid(order, true);
// if( bt_fv==0 )
// return;
View
@@ -20,6 +20,7 @@
#include "btree.h"
#include "pdfile.h"
#include "jsobj.h"
+#include "curop.h"
namespace mongo {
@@ -125,7 +126,7 @@ namespace mongo {
}
bool BtreeCursor::advance() {
- checkForInterrupt();
+ killCurrentOp.checkForInterrupt();
if ( bucket.isNull() )
return false;
bucket = bucket.btree()->advance(bucket, keyOfs, direction, "BtreeCursor::advance");
View
@@ -89,4 +89,5 @@ namespace mongo {
}
BSONObj CurOp::_tooBig = fromjson("{\"$msg\":\"query not recording (too large)\"}");
+ WrappingInt CurOp::_nextOpNum;
}
View
@@ -11,12 +11,13 @@ namespace mongo {
/* Current operation (for the current Client).
an embedded member of Client class, and typically used from within the mutex there. */
class CurOp {
+ static WrappingInt _nextOpNum;
static BSONObj _tooBig; // { $msg : "query not recording (too large)" }
bool _active;
- // unsigned opNum;
time_t startTime;
int _op;
+ WrappingInt _opNum;
char _ns[Namespace::MaxNsLen+2];
struct sockaddr_in client;
@@ -34,14 +35,14 @@ namespace mongo {
public:
void reset(time_t now, const sockaddr_in &_client) {
_active = true;
-// opNum++;
+ _opNum = _nextOpNum.atomicIncrement();
startTime = now;
_ns[0] = '?'; // just in case not set later
resetQuery();
- killCurrentOp = 0;
client = _client;
}
+ WrappingInt opNum() const { return _opNum; }
bool active() const { return _active; }
void setActive(bool active) { _active = active; }
@@ -81,7 +82,7 @@ namespace mongo {
BSONObj infoNoauth() {
BSONObjBuilder b;
-// b.append("opid", opNum);
+ b.append("opid", _opNum);
b.append("active", _active);
if( _active )
b.append("secs_running", (int) (time(0)-startTime));
@@ -110,4 +111,26 @@ namespace mongo {
}
};
+ /* 0 = ok
+ 1 = kill current operation and reset this to 0
+ future: maybe use this as a "going away" thing on process termination with a higher flag value
+ */
+ extern class KillCurrentOp {
+ enum { Off, On, All } state;
+ WrappingInt toKill;
+ public:
+ void killAll() { state = All; }
+ void kill(WrappingInt i) { toKill = i; state = On; }
+
+ void checkForInterrupt() {
+ if( state != Off ) {
+ if( state == All )
+ uasserted("interrupted at shutdown");
+ if( cc().curop()->opNum() == toKill ) {
+ state = Off;
+ uasserted("interrupted");
+ }
+ }
+ }
+ } killCurrentOp;
}
View
@@ -16,9 +16,25 @@
#include "stdafx.h"
#include "pdfile.h"
+#include "curop.h"
namespace mongo {
+ bool BasicCursor::advance() {
+ killCurrentOp.checkForInterrupt();
+ if ( eof() ) {
+ if ( tailable_ && !last.isNull() ) {
+ curr = s->next( last );
+ } else {
+ return false;
+ }
+ } else {
+ last = curr;
+ curr = s->next( curr );
+ }
+ return ok();
+ }
+
/* these will be used outside of mutexes - really functors - thus the const */
class Forward : public AdvanceStrategy {
virtual DiskLoc next( const DiskLoc &prev ) const {
View
@@ -25,22 +25,6 @@ namespace mongo {
class Record;
- /* 0 = ok
- 1 = kill current operation and reset this to 0
- future: maybe use this as a "going away" thing on process termination with a higher flag value
- */
- extern int killCurrentOp;
-
- inline void checkForInterrupt() {
- if( killCurrentOp ) {
- if( !goingAway ) {
- // if we are shutting down, we leave this on so potentially we can stop multiple operations
- killCurrentOp = 0;
- }
- uasserted("interrupted");
- }
- }
-
/* Query cursors, base class. This is for our internal cursors. "ClientCursor" is a separate
concept and is for the user's cursor.
@@ -154,20 +138,7 @@ namespace mongo {
return curr.isNull() ? last : curr;
}
- bool advance() {
- checkForInterrupt();
- if ( eof() ) {
- if ( tailable_ && !last.isNull() ) {
- curr = s->next( last );
- } else {
- return false;
- }
- } else {
- last = curr;
- curr = s->next( curr );
- }
- return ok();
- }
+ bool advance();
BasicCursor(DiskLoc dl, const AdvanceStrategy *_s = forward()) : curr(dl), s( _s ) {
init();
View
@@ -945,7 +945,7 @@ namespace mongo {
void exitCleanly() {
goingAway = true;
- killCurrentOp = 1;
+ killCurrentOp.killAll();
{
dblock lk;
log() << "now exiting" << endl;
View
@@ -29,6 +29,7 @@
#include "commands.h"
#include "cmdline.h"
#include "btree.h"
+#include "curop.h"
namespace mongo {
@@ -111,7 +112,7 @@ namespace mongo {
e->assertOk();
el = e->xnext;
ne++;
- checkForInterrupt();
+ killCurrentOp.checkForInterrupt();
}
ss << " # extents:" << ne << '\n';
} catch (...) {
@@ -200,7 +201,7 @@ namespace mongo {
delSize += d->lengthWithHeaders;
loc = d->nextDeleted;
k++;
- checkForInterrupt();
+ killCurrentOp.checkForInterrupt();
}
} catch (...) {
ss <<" ?exception in deleted chain for bucket " << i << endl;
View
@@ -59,8 +59,7 @@ namespace mongo {
/* we use new here so we don't have to worry about destructor orders at program shutdown */
MongoMutex &dbMutex( *(new MongoMutex) );
- MutexInfo dbMutexInfo;
-
+// MutexInfo dbMutexInfo;
string dbExecCommand;
@@ -85,11 +84,7 @@ namespace mongo {
int ctr = 0;
- /* 0 = ok
- 1 = kill current operation and reset this to 0
- future: maybe use this as a "going away" thing on process termination with a higher flag value
- */
- int killCurrentOp = 0;
+ KillCurrentOp killCurrentOp;
int lockFile = 0;
@@ -124,11 +119,20 @@ namespace mongo {
if( !ai->isAuthorized("admin") ) {
obj = fromjson("{\"err\":\"unauthorized\"}");
}
- else if( !dbMutexInfo.isLocked() )
+ /*else if( !dbMutexInfo.isLocked() )
obj = fromjson("{\"info\":\"no op in progress/not locked\"}");
+ */
else {
- killCurrentOp = 1;
- obj = fromjson("{\"info\":\"attempting to kill op\"}");
+ DbMessage d(m);
+ QueryMessage q(d);
+ BSONElement e = q.query.getField("op");
+ if( !e.isNumber() ) {
+ obj = fromjson("{\"err\":\"no op number field specified?\"}");
+ }
+ else {
+ obj = fromjson("{\"info\":\"attempting to kill op\"}");
+ killCurrentOp.kill( (unsigned) e.number() );
+ }
}
replyToQuery(0, m, dbresponse, obj);
}
View
@@ -811,7 +811,7 @@ namespace mongo {
/** @return subobject of the given name */
BSONObj getObjectField(const char *name) const;
- /** @return INT_MIN if not present */
+ /** @return INT_MIN if not present - does some type conversions */
int getIntField(const char *name) const;
/** @return false if not present */
View
@@ -11,12 +11,13 @@ namespace mongo {
class RecStoreInterface {
public:
virtual ~RecStoreInterface() {}
+
/* Get a pointer to the data at diskloc d. Pointer guaranteed to stay in
scope through the current database operation's life.
*/
virtual char* get(DiskLoc d, unsigned len) = 0;
- /* indicate that the diskloc specified has been updated. note that as-is today,tl he modification may come AFTER this
+ /* indicate that the diskloc specified has been updated. note that as-is today, the modification may come AFTER this
call -- we handle that currently -- until the dblock finishes.
*/
virtual void modified(DiskLoc d) = 0;
View
@@ -15,3 +15,7 @@ t.save( o );
assert.eq( 2 , t.findOne().a , "second" );
assert(t.validate().valid);
+
+// not a very good test of currentOp, but tests that it at least
+// is sort of there:
+assert( db.currentOp().inprog != null );
View
@@ -259,7 +259,7 @@ DB.prototype.help = function() {
print("\tdb.getProfilingLevel()");
print("\tdb.getReplicationInfo()");
print("\tdb.getSisterDB(name) get the db at the same server as this onew");
- print("\tdb.killOp() kills the current operation in the db" );
+ print("\tdb.killOp(opid) kills the current operation in the db" );
print("\tdb.printCollectionStats()" );
print("\tdb.printReplicationInfo()");
print("\tdb.printSlaveReplicationInfo()");
@@ -513,8 +513,10 @@ DB.prototype.currentOp = function(){
}
DB.prototype.currentOP = DB.prototype.currentOp;
-DB.prototype.killOp = function(){
- return db.$cmd.sys.killop.findOne();
+DB.prototype.killOp = function(op) {
+ if( !op )
+ throw "no opNum to kill specified";
+ return db.$cmd.sys.killop.findOne({'op':op});
}
DB.prototype.killOP = DB.prototype.killOp;

0 comments on commit 62522b9

Please sign in to comment.