Main Page Class Hierarchy Compound List File List Compound Members File Members

# mutableserverbase.h

Go to the documentation of this file.

    00001 // mutableserverbase.h: interface for the MutableServerBase class.
    00002 //
    00004
    00005 #if !defined(MUTABLESERVERBASE_H)
    00006 #define MUTABLESERVERBASE_H
    00007
    00008 #if _MSC_VER > 1000
    00009 #pragma once
    00010 #endif // _MSC_VER > 1000
    00011
    00012 // microsoft pragma to avoid warnings relating to the container
    00013 // template names being too long
    00014 #pragma warning(disable:4786)
    00015
    00016 #include "serverbase.h"
    00017 #include <mutableservermessage.h>
    00018 #include <mutableserverrequest.h>
    00019 #include <mutableserverresult.h>
    00020 #include <result_status.h>
    00021 #include <string>
    00022 #include <vector>
    00023 #include <queue>
    00024
    00025
    00026 // Descriptive strings for these are
    00027 // held in static class variable MSB_MODE_NAME[],
    00028 // defined in mutableserverbase.cpp.
    00029 //
    00030 enum MUTABLE_MODE_TYPE
    00031 {
    00032    MMT_NONE       = 0  // for validation
    00033  , MMT_STANDALONE = 1  // command from args/stdin, data access and calculations internally
    00034  , MMT_MODULE     = 2  // command from ring, data access and calculations internally [MT]
    00035  , MMT_SERVER     = 3  // command from socket, calculations internally [MT]
    00036  , MMT_CLIENT     = 4  // command from atgs/stdin, socket call to client for calculations
    00037 };
    00038
    00039
    00040 typedef struct _PROVIDER_ADDR
    00041 {
    00042    std::string  IPAddr;
    00043    std::string  Port;
    00044 } PROVIDER_ADDR;
    00045
    00046 typedef std::vector<PROVIDER_ADDR> PROVIDER_VECTOR;
    00047
    00048
    00049
    00050 #define SERVE_MAX_LOGOS  20 // maximum incoming logo ids
    00051
    00052
    00053 // sacred definitions for message types to report to heartbeat/status ring
    00054 //
    00055 //
    00056 #define  MSB_ERR_MISSMSG  0 /* message missed in transport ring   */
    00057 #define  MSB_ERR_TOOBIG   1 /* retrieved msg too large for buffer */
    00058 #define  MSB_ERR_NOTRACK  2 /* severe weirdness in the cellar     */
    00059 #define  MSB_ERR_QUEUE    3 /* error queueing message for sending */
    00060 #define  MSG_ERR_BASE    10 /* base value for derivative classes to start
    00061                             ** declaring their own error codes
    00062                             */
    00063
    00064
    00065 // ----------------------------------------------------------------------
    00066 class MutableServerBase : public WormServerBase
    00067 {
    00068 private:
    00069    int           MaxMessageLength;
    00070    char *        MessageBuffer;    // buffer for arriving messages
    00071
    00072
    00073    // - - - - - - - - - - - - - - - - - - - - - - - - -
    00074    // Client (sending to Server across socket, await response)
    00075    //
    00076    WORM_STATUS_CODE TransmitRequest( MutableServerRequest * p_request
    00077                                    , MutableServerResult  * r_result
    00078                                    );
    00079
    00080
    00081    // - - - - - - - - - - - - - - - - - - - - - - - - -
    00082    // Server (socket) or Module (ring)
    00083    //
    00084    // if p_result is NULL, this will transmit a message or the appropriate type
    00085    // with status = MSB_RESULT_ERROR (system failure)
    00086    //
    00087    WORM_STATUS_CODE TransmitResult(       MutableServerResult * p_result
    00088                                   , const SOCKET              * p_socketdescriptor = NULL
    00089                                   );
    00090
    00091 protected:
    00092
    00093    // =======================================================================
    00094    //                  from TConfigurable
    00095    // =======================================================================
    00096
    00097    /* CheckConfig() -- allows derivative classes to report the status of their
    00098    **                  the lookup values.
    00099    **
    00100    ** From within any deriving class, or further derivation, ALWAYS contain a call to
    00101    ** <super_class>::CheckConfig() in their own CheckConfig() method...
    00102    ** except that MutableServerBase::CheckConfig() should NOT call
    00103    ** WormServerBase::CheckConfig().
    00104    ** This ensures that all classes in the heirarchy get their chance to report status.
    00105    ** Furthermore, any derivative classes that need to have the Mode set before
    00106    ** doing their own CheckConfig(), should call MutableServerBase::CheckConfig()
    00107    ** at the top of theirs.
    00108    **
    00109    ** All implementations should set ConfigStatus value to WORM_STAT_BADSTATE if there
    00110    ** is a configuration problem, otherwise leave it alone.
    00111    **
    00112    */
    00113    void CheckConfig();
    00114
    00115    // =======================================================================
    00116    //                  WormServerBase
    00117    // =======================================================================
    00118
    00119    /*
    00120    ** PrepareToRun() -- sets LoggingLevel
    00121    */
    00122    virtual bool PrepareToRun() { return WormServerBase::PrepareToRun(); }
    00123
    00124
    00125    /* ClientServicer() -- method to perform the work of servicing a client
    00126    **
    00127    ** note: THREAD_RETURN is a kind of void, so just return or leave the method.
    00128    */
    00129    THREAD_RETURN ClientServicer( void * p_socketdescriptor );
    00130
    00131
    00132    // =======================================================================
    00133    //                  MutableServerBase
    00134    // =======================================================================
    00135
    00136
    00137    // Array of lookup names
    00138    //
    00139    static const char * MSB_MODE_NAME[];
    00140
    00141    // Mode is set in
    00142    //
    00143    MUTABLE_MODE_TYPE  Mode;
    00144
    00145    // - - - - - - - - - - - - - - - - - - - - - - - - -
    00146    // Server
    00147    //
    00148    // see WormServerBase()
    00149
    00150    unsigned short MaxClients;
    00151
    00152
    00153    // - - - - - - - - - - - - - - - - - - - - - - - - -
    00154    // Client
    00155    //
    00156    PROVIDER_VECTOR Providers;
    00157
    00158    // Attempt connection to providers in a round-robin
    00159    // fashion until connection achieved or until this
    00160    // number of seconds has passed
    00161    //
    00162    int             ConnectFailureSec;
    00163
    00164    // max times that each server will be queried before
    00165    // client finally throws in the towel.
    00166    int             MaxServerTryLoopCount;
    00167
    00168    // - - - - - - - - - - - - - - - - - - - - - - - - -
    00169    // Module
    00170    //
    00171    std::string  InputRingName
    00172              ,  OutputRingName
    00173              ;
    00174    WORM_RING_ID InputRingKey
    00175              ,  OutputRingKey
    00176              ;
    00177    SHM_INFO   * InputRegion      // pointer to SHM_INFO used for input
    00178           ,   * OutputRegion     // pointer to SHM_INFO used for output
    00179           ,     InputRegionStruct
    00180           ,     OutputRegionStruct
    00181           ;
    00182
    00183    MSG_LOGO               ServeLogo[SERVE_MAX_LOGOS];
    00184    short         ServeLogoCount;
    00185
    00186    char        * TransmitBuffer;
    00187    long          TransmitBufferLength;
    00188
    00189
    00190    // MessageMutex -- mutex to prevent collisions over the MessageBuffer,
    00191    //                 should be used in both Stacker()
    00192    //                 and Handler()
    00193    //
    00194    //          MessageMutex.RequestLock();
    00195    //          MessageMutex.ReleaseLock();
    00196    //
    00197    TMutex  *     MessageMutex;
    00198
    00199    std::queue<std::string> MessageQueue;
    00200
    00201    TO_THREAD_ID  StackerThreadId;
    00202    long          LastStackerPulse;
    00203
    00204    THREAD_RETURN Stacker();
    00205
    00206    TO_THREAD_ID  HandlerThreadId;
    00207    long          LastHandlerPulse;
    00208
    00209    THREAD_RETURN Handler();
    00210
    00211    MSG_LOGO      ResultMsgLogo;
    00212
    00213    // OutputMessageTypeKey() -- Returns the string used to identify
    00214    //                           result messages sent in Module mode
    00215    //                           via the ring (e.g.:  TYPE_XXXXXXX).
    00216    //                           This is intended to allow different
    00217    //                           derivative servers to emit different
    00218    //                           message types.
    00219    //
    00220    virtual const char * OutputMessageTypeKey() = 0;
    00221
    00222
    00223    // - - - - - - - - - - - - - - - - - - - - - - - - -
    00224    // Server or Module (required for Module)
    00225    //
    00226    // in WormServerBase
    00227
    00228 //   std::string  CommandRingName;
    00229 //   WORM_RING_ID CommandRingKey;
    00230 //   SHM_INFO     CommandRegion;
    00231
    00232    int           LoggingOptions;
    00233
    00234
    00235    // returns true if a processing thread died
    00236    //         false if all still okay
    00237    //
    00238    bool CheckForThreadDeath();
    00239
    00240    /*
    00241    ** Server and Module enter this to start worker threads
    00242    **                   and start main loop
    00243    **                   (sending heartbeats, checking shut
    00244    */
    00245    WORM_STATUS_CODE MainThreadActions();
    00246
    00247
    00248    /*
    00249    ** GetMaxSocketBufferSize() -- Server mode uses this to allocate
    00250    **                             a buffer of sufficient size to
    00251    **                             parse the arriving and format
    00252    **                             the outgoing message
    00253    */
    00254    virtual long GetMaxSocketBufferSize() = 0;
    00255
    00256
    00257    /*
    00258    ** GetRequestContainer() -- gets a container to hold the request
    00259    **                          (e.g. passport & event info).
    00260    **                          Since we don't know what all
    00261    **                          possible content that can be in a
    00262    **                          request for the various derivative
    00263    **                          classes of servers, the container
    00264    **                          is returned as a void pointer,
    00265    **                          This base class code does not need
    00266    **                          to know about the container, only
    00267    **                          the following virtual methods do.
    00268    **
    00269    ** RETURNS:
    00270    **      a pointer to the container
    00271    **   or NULL on failure
    00272    */
    00273    virtual MutableServerRequest * GetRequestContainer() = 0;
    00274
    00275    virtual MutableServerResult * GetResultContainer() = 0;
    00276
    00277
    00278    // - - - - - - - - - - - - - - - - - - - - - - - - -
    00279    // Standalone or Client
    00280    //
    00281    // Gets request parameters/instructions from command line args
    00282    // or stdin
    00283    //
    00284    // r_container = a pointer to the appropriate type of
    00285    //           MutableServerRequest derivative class
    00286    //           (cast to the specific type herein).
    00287    //
    00288    virtual WORM_STATUS_CODE GetRequestFromInput( int    p_argc
    00289                                                , char * p_argv[]
    00290                                                , void * r_container
    00291                                                ) = 0;
    00292
    00293    // - - - - - - - - - - - - - - - - - - - - - - - - -
    00294    // Server, Module or Standalone
    00295    //
    00296    virtual WORM_STATUS_CODE ProcessRequest( void * p_request
    00297                                           , void * r_result
    00298                                           ) = 0;
    00299
    00300
    00301    // - - - - - - - - - - - - - - - - - - - - - - - - -
    00302    // Client, Module or Standalone
    00303    //
    00304    //  p_result is a pointer to the appropriate type of
    00305    //           MutableServerResult derivative class
    00306    //           (cast to the specific type herein).
    00307    //
    00308    // MUST RETURN:
    00309    //      WORM_STAT_SUCCESS  = good results
    00310    //      WORM_STAT_BADSTATE = algorithmic, not system, failure (no results obtained)
    00311    //      WORM_STAT_FAILURE  = system failure
    00312    //
    00313    virtual WORM_STATUS_CODE HandleResult( void * p_result ) = 0;
    00314
    00315
    00316 public:
    00317
    00318    // =======================================================================
    00319    //                  from TConfigurable
    00320    // =======================================================================
    00321
    00322    /*
    00323    **  HandleConfigLine()
    00324    **
    00325    **  PARMS:
    00326    **          p_parser -- the parser being used, command string already
    00327    **                      in the current token for comparison with Its()
    00328    **
    00329    ** RETURN:
    00330    **          HANDLE_INVALID --  line invalid
    00331    **          HANDLE_UNUSED  --  line not used
    00332    **          HANDLE_USED    --  line used okay
    00333    **
    00334    **  Override for child classes to handle command lines
    00335    **  Call <super_class::HandleConfigLine() within derivative classes
    00336    **  to allow them a whack at the parameter as well.
    00337    */
    00338    HANDLE_STATUS HandleConfigLine( ConfigSource * p_parser );
    00339
    00340    // =======================================================================
    00341    //                  from ThreadableObject
    00342    // =======================================================================
    00343
    00344    /* StartThreadFunc -- used by ThreadableObject global function to reenter
    00345    **                    this class in a new thread
    00346    */
    00347    void StartThreadFunc( void * p_arg );
    00348
    00349
    00350    // =======================================================================
    00351    //                  for MutableServerBase
    00352    // =======================================================================
    00353
    00354    MutableServerBase();
    00355         ~MutableServerBase();
    00356
    00357    // Run( int argc, char* argv[] )
    00358    //
    00359    //    Not quite an override of the ServerBase:;Run() method.
    00360    //    This one must switch on the mode, and start thread or
    00361    //    call methods as appropriate.
    00362    //
    00363    // Included the parameters to enable derivative classes to
    00364    // get what they need from the command line or from stdin
    00365    // as preferred.
    00366    //
    00367    WORM_STATUS_CODE Run( int argc, char* argv[] );
    00368
    00369 };
    00370
    00371 #endif // !defined(MUTABLESERVERBASE_H)