PLearn 0.1
Public Member Functions | Static Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Private Member Functions | Static Private Attributes
PLearn::PLearnServer Class Reference

#include <PLearnServer.h>

Collaboration diagram for PLearn::PLearnServer:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 PLearnServer (const PStream &input_output)
virtual ~PLearnServer ()
bool run ()
 Enters the server loop which listens for commands and executes them.

Static Public Member Functions

static PLearnServergetInstance ()
static void cd (const string path)
 change directory (calls chdir)
static void binary ()
 change the mode of the io of the PLearnServer instance to plearn_binary
static void ascii ()
 change the mode of the io of the PLearnServer instance to plearn_ascii
static void implicit_storage (bool impl_stor)
 change the implicit_storage mode of the io of the PLearnServer instance.
static void loggingControl (int vlevel, TVec< string > modules)
 Set current logging level and modules to log.
static void setOptionLevel (const OptionBase::OptionLevel &level)
 Set current option level.

Protected Types

typedef map< int, PP< Object > > ObjMap

Protected Member Functions

virtual int findFreeObjID () const

Protected Attributes

PStream io
bool clear_maps
ObjMap objmap

Private Member Functions

void callFunction (const string &name, int nargs)
void printHelp ()

Static Private Attributes

static PLearnServerinstance = 0

Detailed Description

Definition at line 56 of file PLearnServer.h.


Member Typedef Documentation

typedef map<int, PP<Object> > PLearn::PLearnServer::ObjMap [protected]

Definition at line 66 of file PLearnServer.h.


Constructor & Destructor Documentation

PLearn::PLearnServer::PLearnServer ( const PStream input_output)

Definition at line 64 of file PLearnServer.cc.

References instance, io, PLERROR, and PLearn::PStream::remote_plearn_comm.

    :io(input_output), clear_maps(true)
{
    io.remote_plearn_comm= true;
    if(instance!=0)
        PLERROR("An instance of PLearnServer already exists");
    instance = this;
}
PLearn::PLearnServer::~PLearnServer ( ) [virtual]

Definition at line 73 of file PLearnServer.cc.

References instance, io, and PLearn::PStream::remote_plearn_comm.

{
    io.remote_plearn_comm= false;
    instance = 0;
}

Member Function Documentation

void PLearn::PLearnServer::ascii ( ) [static]

change the mode of the io of the PLearnServer instance to plearn_ascii

Definition at line 95 of file PLearnServer.cc.

References getInstance(), io, PLearn::PStream::plearn_ascii, and PLearn::PStream::setMode().

{
    getInstance()->io.setMode(PStream::plearn_ascii);
}

Here is the call graph for this function:

void PLearn::PLearnServer::binary ( ) [static]

change the mode of the io of the PLearnServer instance to plearn_binary

Definition at line 90 of file PLearnServer.cc.

References getInstance(), io, PLearn::PStream::plearn_binary, and PLearn::PStream::setMode().

{
    getInstance()->io.setMode(PStream::plearn_binary);
}

Here is the call graph for this function:

END_DECLARE_REMOTE_FUNCTIONS void PLearn::PLearnServer::callFunction ( const string &  name,
int  nargs 
) [private]

Definition at line 144 of file PLearnServer.cc.

References PLearn::chdir(), DBG_LOG, PLearn::endl(), PLearn::PStream::implicit_storage, io, PLearn::pl_repository_revision(), PLearn::PStream::plearn_ascii, PLearn::PStream::plearn_binary, PLearn::Object::prepareToSendResults(), and PLearn::PStream::setMode().

Referenced by run().

{
    DBG_LOG << "PLearnServer FUNCTION CALL name=" << name << " nargs=" << nargs << endl;
    if(name=="cd")
    {
        string path;
        io >> path;
        DBG_LOG << "  Arg0 = " << name << endl;        
        chdir(path);
        Object::prepareToSendResults(io,0);
    }
    else if(name=="binary")
    {
        io.setMode(PStream::plearn_binary);
        Object::prepareToSendResults(io,0);
    }
    else if(name=="ascii")
    {
        io.setMode(PStream::plearn_ascii);
        Object::prepareToSendResults(io,0);
    }
    else if(name=="implicit_storage") // Takes a single boolean parameter
    {
        io >> io.implicit_storage;
        Object::prepareToSendResults(io,0);
    }
    else if(name=="pl_repository_revision") // returns the pl_repository_revision string
    {
        string revs = pl_repository_revision();
        Object::prepareToSendResults(io,1);
        io << revs;
    }
    else
    {
        PLearn::callFunction(name, nargs, io);
    }
    io << endl;
    DBG_LOG << "-> FUNCTION CALL DONE." << endl;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void PLearn::PLearnServer::cd ( const string  path) [static]

change directory (calls chdir)

Definition at line 85 of file PLearnServer.cc.

References PLearn::chdir().

{
    chdir(path);
}

Here is the call graph for this function:

int PLearn::PLearnServer::findFreeObjID ( ) const [protected, virtual]

Definition at line 411 of file PLearnServer.cc.

References PLearn::bounded_uniform(), objmap, and PLERROR.

Referenced by run().

{
    //DUMMY method that tries to find an unused ID
    // this algorithm is not guaranteed to work... use at your own risk or modify accordingly
    int id;
    const int maxtries= 65536;
    int ntries= 0;
    do
        id= static_cast<int>(bounded_uniform(0,2000000000));
    while(objmap.find(id) != objmap.end() && ++ntries < maxtries);
    if(ntries >= maxtries)
        PLERROR("PLearnServer::findFreeObjID : can't find a suitable ID within %d tries.", maxtries);
    return id;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PLearnServer * PLearn::PLearnServer::getInstance ( ) [static]

Definition at line 79 of file PLearnServer.cc.

References instance.

Referenced by ascii(), binary(), and implicit_storage().

{ 
    return instance; 
}

Here is the caller graph for this function:

void PLearn::PLearnServer::implicit_storage ( bool  impl_stor) [static]

change the implicit_storage mode of the io of the PLearnServer instance.

Definition at line 100 of file PLearnServer.cc.

References getInstance(), PLearn::PStream::implicit_storage, and io.

{
    getInstance()->io.implicit_storage = impl_stor;
}

Here is the call graph for this function:

void PLearn::PLearnServer::loggingControl ( int  vlevel,
TVec< string >  modules 
) [static]

Set current logging level and modules to log.

Definition at line 105 of file PLearnServer.cc.

References instance.

{
    PL_Log::instance().verbosity(vlevel);
    PL_Log::instance().enableNamedLogging(modules);
}
void PLearn::PLearnServer::printHelp ( ) [private]

Definition at line 185 of file PLearnServer.cc.

References PLearn::endl(), io, and PLearn::PStream::write().

Referenced by run().

{
    io.write("Summary of commands:\n"
             "  !?                                 # print this help message \n"
             "  !F functionname nargs arg1 ...     # calls a supported function.\n"
             "  !N objid object_specification      # creates new object.\n"
             "  !L objid filepath                  # loads a new object into id from a .plearn .psave .vmat file\n"
             "  !M objid methodname nargs arg1 ... # calls method on object objid. Returns: !R <nreturn> ret1 ... \n"
             "  !D objid                   # deletes object objid. Returns: !R 0 \n"
             "  !Z                         # delete all objects. Returns: !R 0 \n"
             "  !P                         # Ping. Returns: !R 0 \n"
             "  !Q                         # Quit. Returns nothing. \n"
             "  !K                         # Kill server and quit. Returns nothing. \n"
             "\n"
             "Except for ?, Q and K, all commands upon success return: \n"
             "  !R n_return_args arg1 ... \n"
             "If an error or exception occurs, the following is returned: \n"
             "  !E \"errormsg\" \n"
             "\n"
             "Summary of currently supported functions:\n"
             "  !F cd 1 \"path\" \n\n"
             "OBSOLETE: Advanced technical note: objects with objid>=10000 are also inserted in the stream's copies_map\n"
             "so that they may be referenced as arguments to method or funtion calls, for ex as: *10001; \n"
             "\n"
        );
    io << endl;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool PLearn::PLearnServer::run ( )

Enters the server loop which listens for commands and executes them.

Returns false only if server kill command '!K' was issued Returns true in all other cases (in particular for quit command '!Q') In principle this call does not throw any exception (exceptions are caught inside the run loop and if possible transmitted to the client with a '!E' reply.)

Definition at line 214 of file PLearnServer.cc.

References c, callFunction(), clear_maps, PLearn::PStream::copies_map_in, PLearn::PStream::copies_map_out, DBG_LOG, PLearn::endl(), findFreeObjID(), PLearn::PStream::get(), PLearn::ProgressBar::getCurrentPlugin(), PLearn::PStream::good(), IMP_LOG, instance, io, PLearn::PLearnError::message(), objmap, PLearn::perr, PLearn::PStream::plearn_ascii, PLERROR, PLearn::pout, PLearn::Object::prepareToSendResults(), printHelp(), PLearn::PStream::setMode(), PLearn::ProgressBar::setPlugin(), PLearn::smartLoadObject(), PLearn::VLEVEL_NORMAL, and PLearn::PStream::write().

Referenced by PLearn::ServerCommand::run().

{
    int obj_id;
    Object* obj;
    ObjMap::iterator found;
    string method_name;
    int n_args; // number of input arguments to the method call
    string filepath;

    // forward log messages to client
    PP<PL_LogPlugin> orig_log_plugin= PL_Log::instance().getCurrentPlugin();
    PL_Log::instance().setPlugin(new PL_LogPluginServer(io));
    // forward progress messages to client, unless the pbar plugin is null
    PP<ProgressBarPlugin> orig_pb_plugin= ProgressBar::getCurrentPlugin();
    if(dynamic_cast<NullProgressBarPlugin*>(static_cast<ProgressBarPlugin*>(orig_pb_plugin)) == 0)
        ProgressBar::setPlugin(new RemoteProgressBarPlugin(io));
    // forward pout&perr to client
    PStream orig_pout= pout;
    PStream orig_perr= perr;
    pout= new ServerLogStreamBuf(io, "pout", VLEVEL_NORMAL);
    perr= new ServerLogStreamBuf(io, "perr", VLEVEL_NORMAL);

    DBG_LOG << "ENTERING PLearnServer::run()" << endl;

    for(;;)
    {
        if(clear_maps)
        {
            io.copies_map_in.clear();
            io.copies_map_out.clear();
            for (ObjMap::iterator it = objmap.begin(); it != objmap.end(); ++it)
                io.copies_map_in[it->first]= it->second;
        }
        int c = -1;
        do 
            c = io.get(); 
        while(io.good() && c!='!' && c!=EOF);
        
        if(c==EOF || !io)
            return true;
        int command = io.get();
        
        try 
        {            
            switch(command)
            {
            case '?':
                printHelp();
                break;
             
            case 'P': // ping
                Object::prepareToSendResults(io,0);
                io << endl;
                break;

            case 'F': // call function 
                io >> method_name >> n_args;
                callFunction(method_name, n_args);
                io << endl;
                break;

            case 'N': // new
                DBG_LOG << "PLearnServer NEW OBJECT" << endl;
                obj = 0;
                io >> obj_id >> obj;           // Read new object
                DBG_LOG << "  obj_id = " << obj_id << endl;
                objmap[obj_id] = obj;
                Object::prepareToSendResults(io,0);
                io << endl;  
                DBG_LOG << "-> OBJECT CREATED." << endl;
                break;

            case 'O': // new w/o id; id is returned
                DBG_LOG << "PLearnServer NEW OBJECT w/o ID" << endl;
                obj = 0;
                io >> obj;           // Read new object
                obj_id= findFreeObjID();
                DBG_LOG << "  obj_id = " << obj_id << endl;
                objmap[obj_id] = obj;
                Object::prepareToSendResults(io,1);
                io << obj_id << endl;  
                DBG_LOG << "-> OBJECT CREATED." << endl;
                break;
            
            case 'L': // load from file
                DBG_LOG << "PLearnServer LOAD OBJECT" << endl;
                obj = 0;
                io >> obj_id >> filepath;
                DBG_LOG << "  obj_id = " << obj_id << endl;
                DBG_LOG << "  filepath = " << filepath << endl;                
                // PLearn::load(filepath,obj);
                obj = smartLoadObject(filepath);
                objmap[obj_id] = obj;
                Object::prepareToSendResults(io,0);
                io << endl;  
                DBG_LOG << "-> OBJECT LOADED." << endl;
                break;

            case 'D': // delete
                DBG_LOG << "PLearnServer DELETE OBJECT" << endl;
                io >> obj_id;
                DBG_LOG << "  ojbj_id = " << obj_id << endl;
                if(objmap.erase(obj_id)==0)
                    PLERROR("Calling delete of a non-existing object");
                Object::prepareToSendResults(io,0);
                io << endl;
                DBG_LOG << "-> OBJECT DELETED." << endl;
                break;

            case 'M': // method call
                DBG_LOG << "PLearnServer METHOD CALL" << endl;
                io >> obj_id;
                DBG_LOG << "  ojbj_id = " << obj_id << endl;
                found = objmap.find(obj_id);
                DBG_LOG << "objmap= " << objmap << endl;
                DBG_LOG << "cmo= " << io.copies_map_out << endl;
                if(found == objmap.end()) // unexistant obj_id
                    PLERROR("Calling a method on a non-existing object");
                else 
                {
                    io >> method_name >> n_args;
                    DBG_LOG << "  method_name = " << method_name << endl;
                    DBG_LOG << "  n_args = " << n_args << endl;
                    // cerr << "Method: " << method_name << ' ' << n_args << endl;
                    found->second->call(method_name, n_args, io);
                    io << endl;
                    DBG_LOG << "-> METHOD CALL DONE." << endl;
                }
                break;

            case 'Z': // delete all objects
                DBG_LOG << "PLearnServer DELETE ALL OBJECTS" << endl;
                objmap.clear();
                Object::prepareToSendResults(io,0);
                io << endl;
                DBG_LOG << "-> ALL OBJECTS DELETED." << endl;
                break;

            case 'Q': // quit
                PL_Log::instance().setPlugin(orig_log_plugin);
                ProgressBar::setPlugin(orig_pb_plugin);
                pout= orig_pout;
                perr= orig_perr;
                io.setMode(PStream::plearn_ascii);
                DBG_LOG << "PLearnServer QUIT" << endl;
                // cerr << "Quitting" << endl;
                DBG_LOG << "LEAVING PLearnServer::run()" << endl;
                return true;
              
            case 'K': // kill
                DBG_LOG << "PLearnServer KILL" << endl;
                DBG_LOG << "LEAVING PLearnServer::run()" << endl;
                return false;

            default:
                PLERROR("Invalid PLearnServer command char: %c Type !? for help.",(char)command);
                return true;
            }
        }
        catch(const PLearnError& e)
        {
            // cerr << "PLearnServer caught PLearnError \"" << e.message() << '"' << endl;
            try 
            {
                io.write("!E ");
                io << e.message() << endl;
            }
            catch(const PLearnError& e2)
            {
                IMP_LOG << "PLearnServer ERROR: " << e2.message() << endl
                        << " while trying to send (to io) error: " << e.message() << endl
                        << " Probably due to peer closing before we finished sending." << endl
                        << " (If, as is likely, what we were sending were some remaining blanks" << endl
                        << " no need to worry...)." << endl;
            }
        }
        catch (...) 
        {
            try
            {
                io.write("!E ");
                io << "Unknown exception" << endl;
            }
            catch(const PLearnError& e2)
            {
                IMP_LOG << "PLearnServer ERROR: " << e2.message() << endl
                        << " while trying to send (to io) notification of unknown exception." << endl
                        << " Probably due to peer closing before we finished sending." << endl
                        << " (If, as is likely, what we were sending were some remaining blanks" << endl
                        << " no need to worry...)." << endl;
            }
        }
    }
    DBG_LOG << "LEAVING PLearnServer::run()" << endl;
    return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void PLearn::PLearnServer::setOptionLevel ( const OptionBase::OptionLevel level) [static]

Set current option level.

Definition at line 111 of file PLearnServer.cc.

References PLearn::OptionBase::setCurrentOptionLevel().

Here is the call graph for this function:


Member Data Documentation

Definition at line 69 of file PLearnServer.h.

Referenced by run().

Definition at line 60 of file PLearnServer.h.

Referenced by getInstance(), loggingControl(), PLearnServer(), run(), and ~PLearnServer().

Definition at line 70 of file PLearnServer.h.

Referenced by findFreeObjID(), and run().


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines