diff options
author | Dwight <dmerriman@gmail.com> | 2009-01-05 15:30:07 -0500 |
---|---|---|
committer | Dwight <dmerriman@gmail.com> | 2009-01-05 15:30:07 -0500 |
commit | 2e35206b4781ee72378ddddc4c2f99a1c290ab58 (patch) | |
tree | 9fc17cd26512cc9680d13b11cd196369908cca97 /db | |
parent | ffc3bb2216da756a77c18065a52c3cc1bb694cd3 (diff) | |
download | mongo-2e35206b4781ee72378ddddc4c2f99a1c290ab58.tar.gz |
getlasterror
Diffstat (limited to 'db')
-rw-r--r-- | db/db.cpp | 6 | ||||
-rw-r--r-- | db/db.vcproj | 8 | ||||
-rw-r--r-- | db/dbcommands.cpp | 70 | ||||
-rw-r--r-- | db/instance.cpp | 1 | ||||
-rw-r--r-- | db/lasterror.cpp | 6 | ||||
-rw-r--r-- | db/lasterror.h | 44 | ||||
-rw-r--r-- | db/makefile | 4 |
7 files changed, 137 insertions, 2 deletions
diff --git a/db/db.cpp b/db/db.cpp index 3e662b5c2cc..619e9a43069 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -136,11 +136,15 @@ public: Message & container; }; +#include "lasterror.h" + /* we create one thread for each connection from an app server database. app server will open a pool of threads. */ void connThread() { + LastError *le = new LastError(); + lastError.reset(le); try { MessagingPort& dbMsgPort = *grab; @@ -156,6 +160,8 @@ void connThread() break; } + le->nPrev++; + DbResponse dbresponse; if ( !assembleResponse( m, dbresponse ) ) { cout << curTimeMillis() % 10000 << " end msg " << dbMsgPort.farEnd.toString() << endl; diff --git a/db/db.vcproj b/db/db.vcproj index bfda85c5f79..bf1b32c5e33 100644 --- a/db/db.vcproj +++ b/db/db.vcproj @@ -328,6 +328,10 @@ >
</File>
<File
+ RelativePath=".\lasterror.cpp"
+ >
+ </File>
+ <File
RelativePath=".\matcher.cpp"
>
</File>
@@ -545,6 +549,10 @@ >
</File>
<File
+ RelativePath=".\lasterror.h"
+ >
+ </File>
+ <File
RelativePath="..\util\log.h"
>
</File>
diff --git a/db/dbcommands.cpp b/db/dbcommands.cpp index 5d81ddb426d..37cf1d7b239 100644 --- a/db/dbcommands.cpp +++ b/db/dbcommands.cpp @@ -30,6 +30,7 @@ #include "commands.h" #include "db.h" #include "instance.h" +#include "lasterror.h" extern bool quiet; extern int queryTraceLevel; @@ -177,6 +178,75 @@ string validateNS(const char *ns, NamespaceDetails *d) { return ss.str(); } +/* reset any errors so that getlasterror comes back clean. + + useful before performing a long series of operations where we want to + see if any of the operations triggered an error, but don't want to check + after each op as that woudl be a client/server turnaround. +*/ +class CmdResetError : public Command { +public: + virtual bool logTheOp() { return false; } + virtual bool slaveOk() { return true; } + CmdResetError() : Command("reseterror") {} + bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { + LastError *le = lastError.get(); + assert( le ); + le->resetError(); + return true; + } +} cmdResetError; + +class CmdGetLastError : public Command { +public: + virtual bool logTheOp() { return false; } + virtual bool slaveOk() { return true; } + CmdGetLastError() : Command("getlasterror") {} + bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { + LastError *le = lastError.get(); + assert( le ); + le->nPrev--; // we don't count as an operation + if( le->nPrev != 1 || !le->haveError() ) { + result.appendNull("err"); + return true; + } + result.append("err", le->msg); + return true; + } +} cmdGetLastError; + +/* for testing purposes only */ +class CmdForceError : public Command { +public: + virtual bool logTheOp() { return false; } + virtual bool slaveOk() { return true; } + CmdForceError() : Command("forceerror") {} + bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { + uassert("forced error", false); + return true; + } +} cmdForceError; + +class CmdGetPrevError : public Command { +public: + virtual bool logTheOp() { return false; } + virtual bool slaveOk() { return true; } + CmdGetPrevError() : Command("getpreverror") {} + bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { + LastError *le = lastError.get(); + assert( le ); + le->nPrev--; // we don't count as an operation + if( !le->haveError() ) { + result.appendNull("err"); + result.append("nPrev", 1); + return true; + } + result.append("err", le->msg); + result.append("nPrev", le->nPrev); + return true; + } +} cmdGetPrevError; + class CmdDropDatabase : public Command { public: virtual bool logTheOp() { diff --git a/db/instance.cpp b/db/instance.cpp index 6d1250b046c..2dcb0f4dbc8 100644 --- a/db/instance.cpp +++ b/db/instance.cpp @@ -24,6 +24,7 @@ #include "repl.h" #include "dbmessage.h" #include "instance.h" +#include "lasterror.h" int nloggedsome = 0; #define LOGSOME if( ++nloggedsome < 1000 || nloggedsome % 100 == 0 ) diff --git a/db/lasterror.cpp b/db/lasterror.cpp new file mode 100644 index 00000000000..a3f33cd5703 --- /dev/null +++ b/db/lasterror.cpp @@ -0,0 +1,6 @@ +// lasterror.cpp
+
+#include "stdafx.h"
+#include "lasterror.h"
+
+boost::thread_specific_ptr<LastError> lastError;
diff --git a/db/lasterror.h b/db/lasterror.h new file mode 100644 index 00000000000..6030cb9e19b --- /dev/null +++ b/db/lasterror.h @@ -0,0 +1,44 @@ +// lasterror.h
+
+/** +* Copyright (C) 2009 10gen Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +
+#pragma once
+
+#include <boost/thread/tss.hpp>
+
+struct LastError {
+ string msg;
+ int nPrev;
+ void raiseError(const char *_msg) {
+ msg = _msg;
+ nPrev = 1;
+ }
+ bool haveError() const { return !msg.empty(); }
+ void resetError() { msg.clear(); }
+ LastError() { nPrev = 0; }
+};
+
+extern boost::thread_specific_ptr<LastError> lastError;
+
+inline void raiseError(const char *msg) {
+ LastError *le = lastError.get();
+ if( le == 0 ) {
+ DEV log() << "warning: lastError==0 can't report:" << msg << '\n';
+ return;
+ }
+ le->raiseError(msg);
+}
diff --git a/db/makefile b/db/makefile index b819ddd3bc9..fdc05d8df2e 100644 --- a/db/makefile +++ b/db/makefile @@ -12,9 +12,9 @@ DBTEST_LIBS= $(LIBS) -lunittest JVM_LIBS = -L/opt/java/lib/ -OBJS=../stdafx.o ../util/sock.o ../grid/message.o ../util/mmap.o pdfile.o query.o jsobj.o introspect.o btree.o clientcursor.o ../util/util.o javajs.o tests.o json.o repl.o ../client/dbclient.o btreecursor.o cloner.o namespace.o commands.o matcher.o dbcommands.o dbeval.o ../util/background.o ../util/miniwebserver.o dbwebserver.o dbinfo.o instance.o dbhelpers.o +OBJS=../stdafx.o ../util/sock.o ../grid/message.o ../util/mmap.o pdfile.o query.o jsobj.o introspect.o btree.o clientcursor.o ../util/util.o javajs.o tests.o json.o repl.o ../client/dbclient.o btreecursor.o cloner.o namespace.o commands.o matcher.o dbcommands.o dbeval.o ../util/background.o ../util/miniwebserver.o dbwebserver.o dbinfo.o instance.o dbhelpers.o lasterror.o -DBGRID_OBJS=../stdafx.o json.o ../util/sock.o ../grid/message.o ../util/util.o jsobj.o ../client/dbclient.o ../dbgrid/dbgrid.o ../dbgrid/request.o ../client/connpool.o ../dbgrid/gridconfig.o commands.o ../dbgrid/dbgrid_commands.o ../dbgrid/griddatabase.o ../client/model.o ../util/background.o ../dbgrid/shard.o +DBGRID_OBJS=../stdafx.o json.o ../util/sock.o ../grid/message.o ../util/util.o jsobj.o ../client/dbclient.o ../dbgrid/dbgrid.o ../dbgrid/request.o ../client/connpool.o ../dbgrid/gridconfig.o commands.o ../dbgrid/dbgrid_commands.o ../dbgrid/griddatabase.o ../client/model.o ../util/background.o ../dbgrid/shard.o lasterror.o DBTEST_OBJS= $(OBJS) ../dbtests/dbtests.o ../dbtests/btreetests.o ../dbtests/jsobjtests.o ../dbtests/namespacetests.o ../dbtests/pairingtests.o |