]> granicus.if.org Git - php/commitdiff
Added persistent connections, and automattic reconnect on
authorMark L. Woodward <mlwmohawk@php.net>
Tue, 4 Jun 2002 13:59:46 +0000 (13:59 +0000)
committerMark L. Woodward <mlwmohawk@php.net>
Tue, 4 Jun 2002 13:59:46 +0000 (13:59 +0000)
lost connections. Requires Phoenix 1.0

ext/msession/msession.c
ext/msession/reqclient.h

index fd7043fa0bad2e1a849c732cc34f5420eb5f44a0..e06018034ae6d786690d14365973fe247fbce1ae 100644 (file)
    |    Portions copyright the PHP group.                                 |
    +----------------------------------------------------------------------+
  */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "php.h"
 #include "php_ini.h"
 #include "php_msession.h"
@@ -23,6 +27,7 @@
 #include "ext/standard/info.h"
 #include "ext/session/php_session.h"
 
+
 /* Macros and such */
 #ifndef TRUE
 #define TRUE 1
 /* Uncomment to get debugging messages */
 /* #define ERR_DEBUG */
 
+/* Uncomment for conections which are persistent for a process 
+ * This will be faster but allocates a thread in the msession 
+ * daemon. 
+ * Pros: No reconnect overhead.
+ * cons: Msession maintains a thread per connection.
+ */
+/* #define PERSISTENT_CONN */
 
 #ifdef ERR_DEBUG
 #define ELOG( str )    php_log_err( str )
 #define IFCONNECT_ENDVAL(V)    } else { php_error(E_WARNING, s_szNoInit); return V; }
 #define IFCONNECT_END          } else { php_error(E_WARNING, s_szNoInit); RETURN_FALSE; }
 
+#ifndef HAVE_PHP_SESSION
+#error HAVE_PHP_SESSION not defined
+#endif
+
 /* Test if session module contains custom sesson ID patch */
 #ifdef PHP_SESSION_API
 #if (PHP_SESSION_API >= 20020330)
@@ -60,7 +76,6 @@
 /* This sets the PHP API version used in the file. */
 /* If this module does not compile on the version of PHP you are using, look for */
 /* this value in Zend/zend_modules.h, and set appropriately */
-
 #if (ZEND_MODULE_API_NO <=  20001222)
 #define PHP_4_0
 #define TSRMLS_CC
@@ -183,6 +198,7 @@ PHP_RINIT_FUNCTION(msession)
 
 PHP_RSHUTDOWN_FUNCTION(msession)
 {
+#ifndef PERSISTENT_CONN
        if(s_conn)
        {
                CloseReqConn(s_conn);
@@ -194,6 +210,7 @@ PHP_RSHUTDOWN_FUNCTION(msession)
                FreeRequestBuffer(s_reqb);
                s_reqb=NULL;
        }
+#endif
        return SUCCESS;
 }
 
@@ -204,32 +221,87 @@ PHP_MINFO_FUNCTION(msession)
        php_info_print_table_end();
 }
 
+/* The PHP Version of DoRequest */
+/* Manages connections that have been disconnected */
+int PHPDoRequest(void **pconn, REQB **ppreq)
+{
+       void *conn = *pconn;
+       int stat = (*ppreq)->req.stat;
+       int param = (*ppreq)->req.param;
+
+       int result = DoRequest(conn, ppreq);
+
+       // Server closed the connection!
+       if((*ppreq)->req.stat == REQ_ERR && (result == REQE_BADCONN || result == REQE_NOSEND))
+       {
+               // In the case of a bad socket, this should be
+               // all that changs!
+               (*ppreq)->req.stat = stat;
+               (*ppreq)->req.param = param;
+               ELOG("Connection was closed by server");
+               if(ReopenReqConn(conn))
+                       result = DoRequest(*pconn, ppreq);
+       }
+#ifdef ERR_DEBUG
+       if((*ppreq)->req.stat == REQ_ERR && (result == REQE_BADCONN || result == REQE_NOSEND))
+               ELOG("Socket reports closed");
+#endif
+       return result;
+}
+
 int PHPMsessionConnect(const char *szhost, int nport)
 {
+       int fNewHost=FALSE;
 
        TSRMLS_FETCH();
        
+
        if(!s_reqb)
                s_reqb = AllocateRequestBuffer(2048);
 
        if(!s_reqb) // no buffer, it won't work!
                return 0;
-
-       if(s_conn)
-       {
-               CloseReqConn(s_conn);
-               php_log_err("Call to connect with non-null s_conn" TSRMLS_CC);
-       }
+       
        if(strcmp(s_szhost, szhost))
        {
                if(s_szhost != s_szdefhost)
                        free(s_szhost);
                s_szhost = strdup(szhost);
+               fNewHost = TRUE;
        }
-       if(nport)
+       if(nport && nport != s_port)
+       {
+               fNewHost = TRUE;
                s_port = nport;
+       }
+
+#ifndef PERSISTENT_CONN
+       ELOG("PHPMsessionConnect:old");
+       if(s_conn)
+       {
+               CloseReqConn(s_conn);
+               php_log_err("Call to connect with non-null s_conn" TSRMLS_CC);
+       }
 
        s_conn = OpenReqConn(s_szhost, s_port);
+#else
+       ELOG("PHPMsessionConnect:new");
+       if(s_conn && fNewHost)
+       {
+               ELOG("Closing old connection, opening new");
+               CloseReqConn(s_conn);
+               s_conn = NULL;
+       }
+       if(!s_conn)
+               s_conn = OpenReqConn(s_szhost, s_port);
+#ifdef ERR_DEBUG
+       else
+       {
+               ELOG("Reusing old connection");
+       }
+#endif
+#endif
+
 
 #ifdef ERR_DEBUG
 {
@@ -244,6 +316,7 @@ int PHPMsessionConnect(const char *szhost, int nport)
 
 void PHPMsessionDisconnect()
 {
+#ifndef PERSISTENT_CONN
        if(s_conn)
        {
                CloseReqConn(s_conn);
@@ -254,6 +327,7 @@ void PHPMsessionDisconnect()
                FreeRequestBuffer(s_reqb);
                s_reqb = NULL;
        }
+#endif
 }
 
 char *PHPMsessionGetData(const char *session)
@@ -263,7 +337,7 @@ char *PHPMsessionGetData(const char *session)
        IFCONNECT_BEGIN
 
        FormatRequest(&s_reqb, REQ_DATAGET, session,"","",0);
-       DoRequest(s_conn, &s_reqb);
+       PHPDoRequest(&s_conn, &s_reqb);
 
        if(s_reqb->req.stat==REQ_OK)
                ret = safe_estrdup(s_reqb->req.datum);
@@ -273,12 +347,11 @@ char *PHPMsessionGetData(const char *session)
 }
 int PHPMsessionSetData(const char *session, const char *data)
 {
-
        IFCONNECT_BEGIN
        int ret=0;
 
        FormatRequest(&s_reqb, REQ_DATASET, session,"",data,0);
-       DoRequest(s_conn,&s_reqb);
+       PHPDoRequest(&s_conn,&s_reqb);
        ret = (s_reqb->req.stat==REQ_OK);
        if(s_reqb->req.stat!=REQ_OK)
                php_error(E_WARNING, s_szErrFmt, ReqbErr(s_reqb));
@@ -287,14 +360,13 @@ int PHPMsessionSetData(const char *session, const char *data)
 
        IFCONNECT_ENDVAL(0)
 }
-
 int PHPMsessionDestroy(const char *session)
 {
        IFCONNECT_BEGIN
 
        int ret=0;
        FormatRequest(&s_reqb, REQ_DROP, session, "","",0);
-       DoRequest(s_conn,&s_reqb);
+       PHPDoRequest(&s_conn,&s_reqb);
        ret = (s_reqb->req.stat==REQ_OK);
        if(s_reqb->req.stat!=REQ_OK)
                php_error(E_WARNING, s_szErrFmt, ReqbErr(s_reqb));
@@ -353,7 +425,7 @@ PHP_FUNCTION(msession_count)
 
        int count;
        FormatRequest(&s_reqb, REQ_COUNT, "", "","",0);
-       DoRequest(s_conn,&s_reqb);
+       PHPDoRequest(&s_conn,&s_reqb);
        
        count = (s_reqb->req.stat == REQ_OK) ? s_reqb->req.param : 0;
 
@@ -379,7 +451,7 @@ PHP_FUNCTION(msession_create)
        convert_to_string_ex(session);
        szsession = Z_STRVAL_PP(session);
        FormatRequest(&s_reqb, REQ_CREATE, szsession, "","",0);
-       DoRequest(s_conn,&s_reqb);
+       PHPDoRequest(&s_conn,&s_reqb);
        if(s_reqb->req.stat==REQ_OK)
        {
                RETURN_TRUE;
@@ -426,7 +498,7 @@ PHP_FUNCTION(msession_lock)
        convert_to_string_ex(session);
        szsession = Z_STRVAL_PP(session);
        FormatRequest(&s_reqb, REQ_SLOCK, szsession, "","",0);
-       DoRequest(s_conn,&s_reqb);
+       PHPDoRequest(&s_conn,&s_reqb);
 
        if(s_reqb->req.stat==REQ_OK)
        {
@@ -496,7 +568,7 @@ PHP_FUNCTION(msession_ctl)
                }
        }
        FormatRequest(&s_reqb, REQ_CTL, szsession, "","",fn);
-       DoRequest(s_conn,&s_reqb);
+       PHPDoRequest(&s_conn,&s_reqb);
 
        if(s_reqb->req.stat==REQ_OK)
        {
@@ -534,7 +606,7 @@ PHP_FUNCTION(msession_unlock)
        convert_to_long_ex(key);
        lkey = Z_LVAL_PP(key);
        FormatRequest(&s_reqb, REQ_SUNLOCK, szsession, "","",lkey);
-       DoRequest(s_conn,&s_reqb);
+       PHPDoRequest(&s_conn,&s_reqb);
 
        if(s_reqb->req.stat==REQ_OK)
        {
@@ -575,7 +647,7 @@ PHP_FUNCTION(msession_set)
        szvalue = Z_STRVAL_PP(value);
 
        FormatRequest(&s_reqb, REQ_SETVAL, szsession, szname, szvalue, 0);
-       DoRequest(s_conn,&s_reqb);
+       PHPDoRequest(&s_conn,&s_reqb);
 
        if(s_reqb->req.stat==REQ_OK)
        {
@@ -614,7 +686,7 @@ PHP_FUNCTION(msession_get)
        szvalue = Z_STRVAL_PP(value);
 
        FormatRequest(&s_reqb, REQ_GETVAL, szsession, szname, szvalue,0);
-       DoRequest(s_conn, &s_reqb);
+       PHPDoRequest(&s_conn, &s_reqb);
 
        if(s_reqb->req.stat==REQ_OK)
        {
@@ -647,7 +719,7 @@ PHP_FUNCTION(msession_uniq)
        val = Z_LVAL_PP(param);
 
        FormatRequest(&s_reqb, REQ_UNIQ,"", "", "",val);
-       DoRequest(s_conn, &s_reqb);
+       PHPDoRequest(&s_conn, &s_reqb);
 
        if(s_reqb->req.stat==REQ_OK)
        {
@@ -680,7 +752,7 @@ PHP_FUNCTION(msession_randstr)
        val = Z_LVAL_PP(param);
 
        FormatRequest(&s_reqb, REQ_RANDSTR,"", "", "",val);
-       DoRequest(s_conn, &s_reqb);
+       PHPDoRequest(&s_conn, &s_reqb);
 
        if(s_reqb->req.stat==REQ_OK)
        {
@@ -717,7 +789,7 @@ PHP_FUNCTION(msession_find)
        szvalue = Z_STRVAL_PP(value);
 
        FormatRequest(&s_reqb, REQ_FIND, "", szname, szvalue,0);
-       DoRequest(s_conn,&s_reqb);
+       PHPDoRequest(&s_conn,&s_reqb);
 
        if(s_reqb->req.stat==REQ_OK && s_reqb->req.param)
        {
@@ -748,7 +820,7 @@ PHP_FUNCTION(msession_list)
 {
        IFCONNECT_BEGIN
        FormatRequest(&s_reqb, REQ_LIST, "", "", "",0);
-       DoRequest(s_conn,&s_reqb);
+       PHPDoRequest(&s_conn,&s_reqb);
 
        if(s_reqb->req.stat==REQ_OK && s_reqb->req.param)
        {
@@ -789,7 +861,7 @@ PHP_FUNCTION(msession_get_array)
        convert_to_string_ex(session);
        szsession = Z_STRVAL_PP(session);
        FormatRequest(&s_reqb, REQ_GETALL, szsession, "", "",0);
-       DoRequest(s_conn,&s_reqb);
+       PHPDoRequest(&s_conn,&s_reqb);
 
        array_init(return_value);
 
@@ -902,7 +974,7 @@ PHP_FUNCTION(msession_set_array)
 
        ELOG("FormatMulti");
        FormatRequestMulti(&s_reqb, REQ_SETVAL, Z_STRVAL_PP(session), countpair, pairs,0);
-       DoRequest(s_conn,&s_reqb);
+       PHPDoRequest(&s_conn,&s_reqb);
 
        if(s_reqb->req.stat != REQ_OK)
                php_error(E_WARNING, s_szErrFmt, ReqbErr(s_reqb));
@@ -923,7 +995,7 @@ PHP_FUNCTION(msession_listvar)
        }
        convert_to_string_ex(name);
        FormatRequest(&s_reqb, REQ_LISTVAR, "", Z_STRVAL_PP(name), "",0);
-       DoRequest(s_conn,&s_reqb);
+       PHPDoRequest(&s_conn,&s_reqb);
 
        array_init(return_value);
 
@@ -985,7 +1057,7 @@ PHP_FUNCTION(msession_timeout)
        }
        convert_to_string_ex(session);
        FormatRequest(&s_reqb, REQ_TIMEOUT, Z_STRVAL_PP(session), "","",timeout);
-       DoRequest(s_conn,&s_reqb);
+       PHPDoRequest(&s_conn,&s_reqb);
 
        if(s_reqb->req.stat == REQ_OK)
        {
@@ -1017,7 +1089,7 @@ PHP_FUNCTION(msession_inc)
        convert_to_string_ex(name);
 
        FormatRequest(&s_reqb, REQ_INC, Z_STRVAL_PP(session), Z_STRVAL_PP(name),0,0);
-       DoRequest(s_conn, &s_reqb);
+       PHPDoRequest(&s_conn, &s_reqb);
 
        if(s_reqb->req.stat==REQ_OK)
        {
@@ -1122,7 +1194,7 @@ PHP_FUNCTION(msession_plugin)
        ret = atoi(Z_STRVAL_PP(val));
 
        FormatRequest(&s_reqb, REQ_PLUGIN, Z_STRVAL_PP(session), Z_STRVAL_PP(val), param ? Z_STRVAL_PP(param) : "",ret);
-       DoRequest(s_conn, &s_reqb);
+       PHPDoRequest(&s_conn, &s_reqb);
 
        if(s_reqb->req.stat==REQ_OK && s_reqb->req.len)
        {
@@ -1172,7 +1244,7 @@ PHP_FUNCTION(msession_call)
        }
 
        FormatRequestStrings(&s_reqb, REQ_CALL, NULL , n, strings);
-       DoRequest(s_conn, &s_reqb);
+       PHPDoRequest(&s_conn, &s_reqb);
 
        if(s_reqb->req.stat==REQ_OK && s_reqb->req.len)
        {
@@ -1192,9 +1264,28 @@ PHP_FUNCTION(msession_call)
 
 PS_OPEN_FUNC(msession)
 {
+       int port;
+       int len = strlen(save_path)+1;
+       char * path = alloca(len);
+       char * szport;
+
+       strcpy(path, save_path);
+
+       szport = strchr(path, ':');
+
+       if(szport)
+       {
+               *szport++=0;
+               port = atoi(szport);
+       }
+       else
+       {
+               port = s_port;
+       }
+       
        ELOG( "ps_open_msession");
        PS_SET_MOD_DATA((void *)1); // session.c needs a non-zero here!
-       return PHPMsessionConnect(save_path, 8086) ? SUCCESS : FAILURE;
+       return PHPMsessionConnect(path, port) ? SUCCESS : FAILURE;
 }
 
 PS_CLOSE_FUNC(msession)
@@ -1246,7 +1337,7 @@ PS_CREATE_SID_FUNC(msession)
        {
                ELOG("Should create a new session");
                FormatRequest(&s_reqb, REQ_UNIQ,"", "", "",SID_LEN);
-               DoRequest(s_conn, &s_reqb);
+               PHPDoRequest(&s_conn, &s_reqb);
 
                if(s_reqb->req.stat==REQ_OK)
                {
index f8b2695d1efba961b633e1c7367d0d49dae12bdb..3384b3d6c7c7bf6a974ba8b59b4d4f2a26fbf00f 100644 (file)
@@ -58,9 +58,6 @@ enum REQ_TYPES
        REQ_SERIALIZE,
        REQ_LAST,
        REQ_INTERNAL_BEGIN=1023,
-       REQ_POPEN,
-       REQ_PCLOSE,
-       REQ_LOADDLL,
        REQ_INTERNALLAST,
 };
 enum REQ_ERRORS
@@ -83,6 +80,10 @@ enum REQ_ERRORS
        REQE_UNKNOWN
 };
 
+#define REQ_POPEN               1024
+#define REQ_PCLOSE              1025
+#define REQ_PING                1026
+
 typedef struct _requestPacket
 {
        int     version;
@@ -136,6 +137,8 @@ int FormatRequestStrings(REQB **ppreq, int stat, char *session, int n, char **st
 int DoSingleRequest(char *hostname, int port, REQB **preq);
 void *OpenReqConn(char *hostname, int port);
 void CloseReqConn(void *conn);
+void DeleteReqConn(void *conn);
+unsigned char ReopenReqConn(void *conn);
 int DoRequest(void *conn, REQB **preq);
 char *ReqbErr(REQB *reqb);