summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/db.cpp113
-rw-r--r--db/javajs.cpp2
-rw-r--r--db/javajs.h4
-rw-r--r--db/jsobj.cpp3
-rw-r--r--db/pdfile.cpp3
-rw-r--r--db/query.cpp1
-rw-r--r--grid/message.h17
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);