mirror of
https://github.com/php/php-src.git
synced 2026-04-29 03:03:26 +02:00
Added persistent connections, and automattic reconnect on
lost connections. Requires Phoenix 1.0
This commit is contained in:
+124
-33
@@ -16,6 +16,10 @@
|
||||
| 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
|
||||
@@ -37,6 +42,13 @@
|
||||
/* 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 )
|
||||
@@ -50,6 +62,10 @@
|
||||
#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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user