Exemple #1
0
        virtual void process( Message& m , AbstractMessagingPort* port , LastError * le) {
            while ( true ) {
                if ( inShutdown() ) {
                    log() << "got request after shutdown()" << endl;
                    break;
                }

                lastError.startRequest( m , le );

                DbResponse dbresponse;
                try {
                    assembleResponse( m, dbresponse, port->remote() );
                }
                catch ( const ClockSkewException & ) {
                    log() << "ClockSkewException - shutting down" << endl;
                    exitCleanly( EXIT_CLOCK_SKEW );
                }

                if ( dbresponse.response ) {
                    port->reply(m, *dbresponse.response, dbresponse.responseTo);
                    if( dbresponse.exhaust ) {
                        MsgData *header = dbresponse.response->header();
                        QueryResult *qr = (QueryResult *) header;
                        long long cursorid = qr->cursorId;
                        if( cursorid ) {
                            verify( dbresponse.exhaust && *dbresponse.exhaust != 0 );
                            string ns = dbresponse.exhaust; // before reset() free's it...
                            m.reset();
                            BufBuilder b(512);
                            b.appendNum((int) 0 /*size set later in appendData()*/);
                            b.appendNum(header->id);
                            b.appendNum(header->responseTo);
                            b.appendNum((int) dbGetMore);
                            b.appendNum((int) 0);
                            b.appendStr(ns);
                            b.appendNum((int) 0); // ntoreturn
                            b.appendNum(cursorid);
                            m.appendData(b.buf(), b.len());
                            b.decouple();
                            DEV log() << "exhaust=true sending more" << endl;
                            beNice();
                            continue; // this goes back to top loop
                        }
                    }
                }
                break;
            }
        }
Exemple #2
0
        virtual void process( Message& m , AbstractMessagingPort* port , LastError * le) {
            OperationContextImpl txn;
            while ( true ) {
                if ( inShutdown() ) {
                    log() << "got request after shutdown()" << endl;
                    break;
                }

                lastError.startRequest( m , le );

                DbResponse dbresponse;
                assembleResponse( &txn, m, dbresponse, port->remote() );

                if ( dbresponse.response ) {
                    port->reply(m, *dbresponse.response, dbresponse.responseTo);
                    if( dbresponse.exhaustNS.size() > 0 ) {
                        MsgData *header = dbresponse.response->header();
                        QueryResult *qr = (QueryResult *) header;
                        long long cursorid = qr->cursorId;
                        if( cursorid ) {
                            verify( dbresponse.exhaustNS.size() && dbresponse.exhaustNS[0] );
                            string ns = dbresponse.exhaustNS; // before reset() free's it...
                            m.reset();
                            BufBuilder b(512);
                            b.appendNum((int) 0 /*size set later in appendData()*/);
                            b.appendNum(header->id);
                            b.appendNum(header->responseTo);
                            b.appendNum((int) dbGetMore);
                            b.appendNum((int) 0);
                            b.appendStr(ns);
                            b.appendNum((int) 0); // ntoreturn
                            b.appendNum(cursorid);
                            m.appendData(b.buf(), b.len());
                            b.decouple();
                            DEV log() << "exhaust=true sending more" << endl;
                            beNice();
                            continue; // this goes back to top loop
                        }
                    }
                }
                break;
            }
        }
Exemple #3
0
    /* we create one thread for each connection from an app server database.
       app server will open a pool of threads.
       todo: one day, asio...
    */
    void connThread( MessagingPort * inPort )
    {
        TicketHolderReleaser connTicketReleaser( &connTicketHolder );

        /* todo: move to Client object */
        LastError *le = new LastError();
        lastError.reset(le);

        inPort->_logLevel = 1;
        auto_ptr<MessagingPort> dbMsgPort( inPort );
        Client& c = Client::initThread("conn", inPort);

        try {

            c.getAuthenticationInfo()->isLocalHost = dbMsgPort->farEnd.isLocalHost();

            Message m;
            while ( 1 ) {

                if ( !dbMsgPort->recv(m) ) {
                    if( !cmdLine.quiet )
                      log() << "end connection " << dbMsgPort->farEnd.toString() << endl;
                    dbMsgPort->shutdown();
                    break;
                }
sendmore:
                if ( inShutdown() ) {
                    log() << "got request after shutdown()" << endl;
                    break;
                }
                
                lastError.startRequest( m , le );

                DbResponse dbresponse;
                if ( !assembleResponse( m, dbresponse, dbMsgPort->farEnd ) ) {
                    log() << curTimeMillis() % 10000 << "   end msg " << dbMsgPort->farEnd.toString() << endl;
                    /* todo: we may not wish to allow this, even on localhost: very low priv accounts could stop us. */
                    if ( dbMsgPort->farEnd.isLocalHost() ) {
                        dbMsgPort->shutdown();
                        sleepmillis(50);
                        problem() << "exiting end msg" << endl;
                        dbexit(EXIT_CLEAN);
                    }
                    else {
                        log() << "  (not from localhost, ignoring end msg)" << endl;
                    }
                }

                if ( dbresponse.response ) {
                    dbMsgPort->reply(m, *dbresponse.response, dbresponse.responseTo);
                    if( dbresponse.exhaust ) { 
                        MsgData *header = dbresponse.response->header();
                        QueryResult *qr = (QueryResult *) header;
                        long long cursorid = qr->cursorId;
                        if( cursorid ) {
                            assert( dbresponse.exhaust && *dbresponse.exhaust != 0 );
                            string ns = dbresponse.exhaust; // before reset() free's it...
                            m.reset();
                            BufBuilder b(512);
                            b.appendNum((int) 0 /*size set later in appendData()*/);
                            b.appendNum(header->id);
                            b.appendNum(header->responseTo);
                            b.appendNum((int) dbGetMore);
                            b.appendNum((int) 0);
                            b.appendStr(ns);
                            b.appendNum((int) 0); // ntoreturn
                            b.appendNum(cursorid);
                            m.appendData(b.buf(), b.len());
                            b.decouple();
                            DEV log() << "exhaust=true sending more" << endl;
                            beNice();
                            goto sendmore;
                        }
                    }
                }

                m.reset();
            }

        }
        catch ( AssertionException& e ) {
            log() << "AssertionException in connThread, closing client connection" << endl;
            log() << ' ' << e.what() << endl;
            dbMsgPort->shutdown();
        }
        catch ( SocketException& ) {
            problem() << "SocketException in connThread, closing client connection" << endl;
            dbMsgPort->shutdown();
        }
        catch ( const ClockSkewException & ) {
            exitCleanly( EXIT_CLOCK_SKEW );
        }        
        catch ( std::exception &e ) {
            problem() << "Uncaught std::exception: " << e.what() << ", terminating" << endl;
            dbexit( EXIT_UNCAUGHT );
        }
        catch ( ... ) {
            problem() << "Uncaught exception, terminating" << endl;
            dbexit( EXIT_UNCAUGHT );
        }

        // thread ending...
        {
            Client * c = currentClient.get();
            if( c ) c->shutdown();
        }
        globalScriptEngine->threadDone();
    }