diff options
-rw-r--r-- | db/db.cpp | 113 | ||||
-rw-r--r-- | db/javajs.cpp | 2 | ||||
-rw-r--r-- | db/javajs.h | 4 | ||||
-rw-r--r-- | db/jsobj.cpp | 3 | ||||
-rw-r--r-- | db/pdfile.cpp | 3 | ||||
-rw-r--r-- | db/query.cpp | 1 | ||||
-rw-r--r-- | grid/message.h | 17 |
7 files changed, 133 insertions, 10 deletions
diff --git a/db/db.cpp b/db/db.cpp index 301a3310c6b..8aeea6e4331 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -155,7 +155,7 @@ void receivedDelete(Message& m) { deleteObjects(ns, pattern, flags & 1);
}
-void receivedQuery(MessagingPort& dbMsgPort, Message& m, stringstream& ss) {
+void receivedQuery(AbstractMessagingPort& dbMsgPort, Message& m, stringstream& ss) {
DbMessage d(m);
const char *ns = d.getns();
setClient(ns);
@@ -198,7 +198,7 @@ void receivedQuery(MessagingPort& dbMsgPort, Message& m, stringstream& ss) { dbMsgPort.reply(m, resp);
}
-void receivedGetMore(MessagingPort& dbMsgPort, Message& m, stringstream& ss) {
+void receivedGetMore(AbstractMessagingPort& dbMsgPort, Message& m, stringstream& ss) {
DbMessage d(m);
const char *ns = d.getns();
ss << ns;
@@ -255,7 +255,7 @@ void testTheDb() { int port = DBPort;
MessagingPort *grab = 0;
-void t();
+void connThread();
class OurListener : public Listener {
public:
@@ -263,7 +263,7 @@ public: virtual void accepted(MessagingPort *mp) {
assert( grab == 0 );
grab = mp;
- boost::thread thr(t);
+ boost::thread thr(connThread);
while( grab )
sleepmillis(1);
}
@@ -279,8 +279,111 @@ void listen(int port) { }
int ctr = 0;
+extern int callDepth;
-void t()
+class JniMessagingPort : public AbstractMessagingPort {
+public:
+ JniMessagingPort(Message& _container) : container(_container) { }
+ void reply(Message& received, Message& response) {
+ container = response;
+ }
+ Message container;
+};
+
+/* a call from java/js to the database locally.
+
+ m - inbound message
+ out - outbound message, if there is any, will be set here.
+ if there is one, out.data will be non-null on return.
+ The out.data buffer will automatically clean up when out
+ goes out of scope (out.freeIt==true)
+*/
+void jniCallback(Message& m, Message& out)
+{
+ Client *clientOld = client;
+
+ JniMessagingPort jmp(out);
+ callDepth++;
+ int curOpOld = curOp;
+
+ try {
+
+ stringstream ss;
+ char buf[64];
+ time_t_to_String(time(0), buf);
+ buf[20] = 0; // don't want the year
+ ss << buf << " dbjs ";
+
+ {
+ Timer t;
+
+ bool log = false;
+ curOp = m.data->operation;
+ if( m.data->operation == dbQuery ) {
+ receivedQuery(jmp, m, ss);
+ }
+ else if( m.data->operation == dbInsert ) {
+ ss << "insert ";
+ receivedInsert(m, ss);
+ }
+ else if( m.data->operation == dbUpdate ) {
+ ss << "update ";
+ receivedUpdate(m, ss);
+ }
+ else if( m.data->operation == dbDelete ) {
+ ss << "remove ";
+ receivedDelete(m);
+ }
+ else if( m.data->operation == dbGetMore ) {
+ log = true;
+ ss << "getmore ";
+ receivedGetMore(jmp, m, ss);
+ }
+ else if( m.data->operation == dbKillCursors ) {
+ try {
+ log = true;
+ ss << "killcursors ";
+ receivedKillCursors(m);
+ }
+ catch( AssertionException ) {
+ cout << "Caught Assertion in kill cursors, continuing" << endl;
+ ss << " exception ";
+ }
+ }
+ else {
+ cout << " jnicall: operation isn't supported: " << m.data->operation << endl;
+ assert(false);
+ }
+
+ int ms = t.millis();
+ log = log || ctr++ % 128 == 0;
+ if( log || ms > 100 ) {
+ ss << ' ' << t.millis() << "ms";
+ cout << ss.str().c_str() << endl;
+ }
+ if( client && client->profile >= 1 ) {
+ if( client->profile >= 2 || ms >= 100 ) {
+ // profile it
+ profile(ss.str().c_str()+20/*skip ts*/, ms);
+ }
+ }
+ }
+
+ }
+ catch( AssertionException ) {
+ cout << "Caught AssertionException in jniCall()" << endl;
+ }
+
+ curOp = curOpOld;
+ callDepth--;
+
+ if( client != clientOld ) {
+ client = clientOld;
+ wassert(false);
+ }
+}
+
+void connThread()
{
try {
diff --git a/db/javajs.cpp b/db/javajs.cpp index 7f3cc97728f..49c5d6b25b9 100644 --- a/db/javajs.cpp +++ b/db/javajs.cpp @@ -204,7 +204,7 @@ int JavaJSImpl::scopeSetNumber( jlong id , const char * field , double val ){ return _getEnv()->CallStaticBooleanMethod( _dbhook , _scopeSetNumber , id , _getEnv()->NewStringUTF( field ) , val ); } -int JavaJSImpl::scopeSetString( jlong id , const char * field , char * val ){ +int JavaJSImpl::scopeSetString( jlong id , const char * field , const char * val ){ return _getEnv()->CallStaticBooleanMethod( _dbhook , _scopeSetString , id , _getEnv()->NewStringUTF( field ) , _getEnv()->NewStringUTF( val ) ); } diff --git a/db/javajs.h b/db/javajs.h index a8cccad7342..57f0056a482 100644 --- a/db/javajs.h +++ b/db/javajs.h @@ -48,7 +48,7 @@ class JavaJSImpl { } int scopeSetNumber( jlong id , const char * field , double val ); - int scopeSetString( jlong id , const char * field , char * val ); + int scopeSetString( jlong id , const char * field , const char * val ); int scopeSetObject( jlong id , const char * field , JSObj * obj ); int scopeSetBoolean( jlong id , const char * field , jboolean val ) { return _getEnv()->CallStaticBooleanMethod( _dbhook , _scopeSetNumber , id , _getEnv()->NewStringUTF( field ) , val ); @@ -141,7 +141,7 @@ class Scope { int type(const char *field ) { return JavaJS->scopeGetType(s,field); } void setNumber(const char *field, double val ) { JavaJS->scopeSetNumber(s,field,val); } - void setString(const char *field, char * val ) { JavaJS->scopeSetString(s,field,val); } + void setString(const char *field, const char * val ) { JavaJS->scopeSetString(s,field,val); } void setObject(const char *field, JSObj& obj ) { JavaJS->scopeSetObject(s,field,&obj); } void setBoolean(const char *field, jboolean val ) { JavaJS->scopeSetBoolean(s,field,val); } diff --git a/db/jsobj.cpp b/db/jsobj.cpp index 6078fa4ce4d..500bfcc2a19 100644 --- a/db/jsobj.cpp +++ b/db/jsobj.cpp @@ -224,6 +224,8 @@ int getGtLtOp(Element& e) { return op;
}
+#include "pdfile.h"
+
JSMatcher::JSMatcher(JSObj &_jsobj) :
where(0), jsobj(_jsobj), nRegex(0)
{
@@ -246,6 +248,7 @@ JSMatcher::JSMatcher(JSObj &_jsobj) : javajstest();
}
where->scope = JavaJS->scopeCreate();
+ JavaJS->scopeSetString(where->scope, "$client", client->name.c_str());
where->func = JavaJS->functionCreate( code );
continue;
}
diff --git a/db/pdfile.cpp b/db/pdfile.cpp index 62a92e4f776..9c53860ccb7 100644 --- a/db/pdfile.cpp +++ b/db/pdfile.cpp @@ -27,12 +27,13 @@ Client *client; const char *curNs = "";
int MAGIC = 0x1000;
int curOp = -2;
+int callDepth = 0;
extern int otherTraceLevel;
void sayDbContext() {
cout << " client: " << (client ? client->name.c_str() : "null");
- cout << " op:" << curOp << endl;
+ cout << " op:" << curOp << ' ' << callDepth << endl;
if( client )
cout << " ns: " << curNs << endl;
}
diff --git a/db/query.cpp b/db/query.cpp index 981cb91bf58..be66b77bc28 100644 --- a/db/query.cpp +++ b/db/query.cpp @@ -400,6 +400,7 @@ bool dbEval(JSObj& cmd, JSObjBuilder& result) { }
Scope s;
+ s.setString("$client", client->name.c_str());
Element args = cmd.findElement("args");
if( args.type() == Array ) {
JSObj eo = args.embeddedObject();
diff --git a/grid/message.h b/grid/message.h index 4dfdcdef06c..92691b65f61 100644 --- a/grid/message.h +++ b/grid/message.h @@ -20,7 +20,12 @@ private: int port;
};
-class MessagingPort {
+class AbstractMessagingPort {
+public:
+ virtual void reply(Message& received, Message& response) = 0;
+};
+
+class MessagingPort : public AbstractMessagingPort {
public:
MessagingPort(int sock, SockAddr& farEnd);
MessagingPort();
@@ -82,6 +87,16 @@ public: SockAddr from;
MsgData *data;
+ Message& operator=(Message& r) {
+ assert( data == 0 );
+ data = r.data;
+ assert( r.freeIt );
+ r.freeIt = false;
+ r.data = 0;
+ freeIt = true;
+ return *this;
+ }
+
void reset() {
if( freeIt && data )
free(data);
|