Archived

This forum has been archived. Please start a new discussion on GitHub.

Help with servant implement

Folks,
In my servant implement, i just do some database query. I have to call something like pdatabase->attach() for multithread reason. I have put it in servant construction function, but it doesn't work, but after i put it in interface operation, it works! Anyway, the call should to be called only once.
Where should put the function to be called?

Comments

  • Well, without seeing any code, I don't know how to help. How about you add some trace and find out whether the constructor is called when you expect it to and whether it is called by the thread you think it is called? And, some trace to show the reason for the failure might give you a clue too.

    Cheers,

    Michi.
  • The construct of servant is really called from trace info, Anyway it is really in the main thread.

    I think if i have set some init flag , it surely can be work, the price is check of every operation . Is there any thread entry that i can call my funcition ?


    //server.cpp
    dbDatabase db;
    int init_db()
    {
    if( !db.open( databaseName.c_str(), filePath.c_str()) ){
    cerr<<"db open fail"<<endl;
    assert( 0 );
    }
    cout<<"fastdb inited"<<endl;
    return 0;
    }
    int main( int argc , char* argv[] )
    {
    init_db();
    int status = 0;
    Ice::CommunicatorPtr ic;
    try{
    ic = Ice::initialize( argc, argv );
    Ice::ObjectAdapterPtr adapter
    =ic->createObjectAdapterWithEndpoints(
    "SimpleAdapter", "default -p 10000");

    Commu2SimulatorI * commu = new Commu2SimulatorI;
    Ice::ObjectPtr object = commu;
    adapter->add( object,
    Ice::stringToIdentity("Commu2Simulator"));


    adapter->activate();
    //commu->attachdb();
    ic->waitForShutdown();
    }catch( const Ice::Exception &e ){
    cerr << e <<endl;
    status = 1;
    }catch( const char * msg ){
    cerr << msg << endl;
    status = 1;
    }
    if( ic )
    ic->destroy();
    return status;
    }
    //Implement.cpp
    extern dbDatabase db;
    DTSServer::Commu2SimulatorI::Commu2SimulatorI()
    {
    cout<<"Commu2SimulatorI constructed"<<endl;
    db.attach();
    }
    void
    DTSServer::Commu2SimulatorI::getOlfResult(::DTSServer::olfResults& retVal,
    const Ice::Current& current) const
    {
    //db.attach();
    cout<<"getOlfResult"<<endl;
    dbCursor<OutputData> result;
    int nCount = result.select();
    retVal.resize( nCount );
    cout<<"nCount is "<<nCount<<endl;
    int i=0;
    do{
    retVal.nd = result->nd;
    retVal.V= result->V;
    retVal.theta= result->theta;
    cout<<result->V<<endl;
    ++i;
    }while( result.next() );
    db.commit();
    cout<<"ret is "<<nCount<<endl;
    }
  • Well, if you want to make sure that something happens before any other member function of a servant is called, the servant constructor is the right place to do it.

    Cheers,

    Michi.
  • But construction and other member function are seems not in the same thread. i trace it by call cout<<pthread_self()<<endl;

    How can i call my_init() per thread?

    thread id in construct: 3071877792
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
    thread id in getresourceids: 3044031408
  • If you must make the initialization call in the same thread, one option is to use lazy initialization and call the initialization function in the first operation that is invoked.

    But, generally, there is no way to bind client invocations to a specific thread.

    A better option would probably be to pass incoming invocation to a dedicated worker thread that actually accesses the database.

    Cheers,

    Michi.
  • I got it :)
    Thank you very much!