|
@@ -41,7 +41,6 @@ ECL_MEMCACHED_API bool getECLPluginDefinition(ECLPluginDefinitionBlock *pb)
|
|
}
|
|
}
|
|
|
|
|
|
namespace MemCachedPlugin {
|
|
namespace MemCachedPlugin {
|
|
-static const unsigned unitExpire = 86400;//1 day (secs)
|
|
|
|
|
|
|
|
enum eclDataType {
|
|
enum eclDataType {
|
|
ECL_BOOLEAN,
|
|
ECL_BOOLEAN,
|
|
@@ -89,8 +88,8 @@ public :
|
|
~MCached();
|
|
~MCached();
|
|
|
|
|
|
//set
|
|
//set
|
|
- template <class type> void set(ICodeContext * ctx, const char * partitionKey, const char * key, type value, unsigned expire, eclDataType eclType);
|
|
|
|
- template <class type> void set(ICodeContext * ctx, const char * partitionKey, const char * key, size32_t valueLength, const type * value, unsigned expire, eclDataType eclType);
|
|
|
|
|
|
+ template <class type> void set(ICodeContext * ctx, const char * partitionKey, const char * key, type value, unsigned __int64 expire, eclDataType eclType);
|
|
|
|
+ template <class type> void set(ICodeContext * ctx, const char * partitionKey, const char * key, size32_t valueLength, const type * value, unsigned __int64 expire, eclDataType eclType);
|
|
//get
|
|
//get
|
|
template <class type> void get(ICodeContext * ctx, const char * partitionKey, const char * key, type & value, eclDataType eclType);
|
|
template <class type> void get(ICodeContext * ctx, const char * partitionKey, const char * key, type & value, eclDataType eclType);
|
|
template <class type> void get(ICodeContext * ctx, const char * partitionKey, const char * key, size_t & valueLength, type * & value, eclDataType eclType);
|
|
template <class type> void get(ICodeContext * ctx, const char * partitionKey, const char * key, size_t & valueLength, type * & value, eclDataType eclType);
|
|
@@ -131,6 +130,7 @@ static const unsigned MAX_TYPEMISMATCHCOUNT = 10;
|
|
|
|
|
|
static __thread MCached * cachedConnection;
|
|
static __thread MCached * cachedConnection;
|
|
static __thread ThreadTermFunc threadHookChain;
|
|
static __thread ThreadTermFunc threadHookChain;
|
|
|
|
+static __thread bool threadHooked;
|
|
|
|
|
|
//The following class is here to ensure destruction of the cachedConnection within the main thread
|
|
//The following class is here to ensure destruction of the cachedConnection within the main thread
|
|
//as this is not handled by the thread hook mechanism.
|
|
//as this is not handled by the thread hook mechanism.
|
|
@@ -141,26 +141,37 @@ public :
|
|
~mainThreadCachedConnection()
|
|
~mainThreadCachedConnection()
|
|
{
|
|
{
|
|
if (cachedConnection)
|
|
if (cachedConnection)
|
|
|
|
+ {
|
|
cachedConnection->Release();
|
|
cachedConnection->Release();
|
|
|
|
+ cachedConnection = NULL;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
} mainThread;
|
|
} mainThread;
|
|
|
|
|
|
static void releaseContext()
|
|
static void releaseContext()
|
|
{
|
|
{
|
|
if (cachedConnection)
|
|
if (cachedConnection)
|
|
|
|
+ {
|
|
cachedConnection->Release();
|
|
cachedConnection->Release();
|
|
|
|
+ cachedConnection = NULL;
|
|
|
|
+ }
|
|
if (threadHookChain)
|
|
if (threadHookChain)
|
|
{
|
|
{
|
|
(*threadHookChain)();
|
|
(*threadHookChain)();
|
|
threadHookChain = NULL;
|
|
threadHookChain = NULL;
|
|
}
|
|
}
|
|
|
|
+ threadHooked = false;
|
|
}
|
|
}
|
|
MCached * createConnection(ICodeContext * ctx, const char * options)
|
|
MCached * createConnection(ICodeContext * ctx, const char * options)
|
|
{
|
|
{
|
|
if (!cachedConnection)
|
|
if (!cachedConnection)
|
|
{
|
|
{
|
|
cachedConnection = new MemCachedPlugin::MCached(ctx, options);
|
|
cachedConnection = new MemCachedPlugin::MCached(ctx, options);
|
|
- threadHookChain = addThreadTermFunc(releaseContext);
|
|
|
|
|
|
+ if (!threadHooked)
|
|
|
|
+ {
|
|
|
|
+ threadHookChain = addThreadTermFunc(releaseContext);
|
|
|
|
+ threadHooked = true;
|
|
|
|
+ }
|
|
return LINK(cachedConnection);
|
|
return LINK(cachedConnection);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -168,18 +179,19 @@ MCached * createConnection(ICodeContext * ctx, const char * options)
|
|
return LINK(cachedConnection);
|
|
return LINK(cachedConnection);
|
|
|
|
|
|
cachedConnection->Release();
|
|
cachedConnection->Release();
|
|
|
|
+ cachedConnection = NULL;
|
|
cachedConnection = new MemCachedPlugin::MCached(ctx, options);
|
|
cachedConnection = new MemCachedPlugin::MCached(ctx, options);
|
|
return LINK(cachedConnection);
|
|
return LINK(cachedConnection);
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------SET-----------------------------------------
|
|
//-------------------------------------------SET-----------------------------------------
|
|
-template<class type> void MSet(ICodeContext * ctx, const char * _options, const char * partitionKey, const char * key, type value, unsigned expire, eclDataType eclType)
|
|
|
|
|
|
+template<class type> void MSet(ICodeContext * ctx, const char * _options, const char * partitionKey, const char * key, type value, unsigned __int64 expire, eclDataType eclType)
|
|
{
|
|
{
|
|
OwnedMCached serverPool = createConnection(ctx, _options);
|
|
OwnedMCached serverPool = createConnection(ctx, _options);
|
|
serverPool->set(ctx, partitionKey, key, value, expire, eclType);
|
|
serverPool->set(ctx, partitionKey, key, value, expire, eclType);
|
|
}
|
|
}
|
|
//Set pointer types
|
|
//Set pointer types
|
|
-template<class type> void MSet(ICodeContext * ctx, const char * _options, const char * partitionKey, const char * key, size32_t valueLength, const type * value, unsigned expire, eclDataType eclType)
|
|
|
|
|
|
+template<class type> void MSet(ICodeContext * ctx, const char * _options, const char * partitionKey, const char * key, size32_t valueLength, const type * value, unsigned __int64 expire, eclDataType eclType)
|
|
{
|
|
{
|
|
OwnedMCached serverPool = createConnection(ctx, _options);
|
|
OwnedMCached serverPool = createConnection(ctx, _options);
|
|
serverPool->set(ctx, partitionKey, key, valueLength, value, expire, eclType);
|
|
serverPool->set(ctx, partitionKey, key, valueLength, value, expire, eclType);
|
|
@@ -202,25 +214,25 @@ void MGetVoidPtrLenPair(ICodeContext * ctx, const char * options, const char * p
|
|
}
|
|
}
|
|
|
|
|
|
//----------------------------------SET----------------------------------------
|
|
//----------------------------------SET----------------------------------------
|
|
-template<class type> void MemCachedPlugin::MCached::set(ICodeContext * ctx, const char * partitionKey, const char * key, type value, unsigned expire, eclDataType eclType)
|
|
|
|
|
|
+template<class type> void MemCachedPlugin::MCached::set(ICodeContext * ctx, const char * partitionKey, const char * key, type value, unsigned __int64 expire, eclDataType eclType)
|
|
{
|
|
{
|
|
const char * _value = reinterpret_cast<const char *>(&value);//Do this even for char * to prevent compiler complaining
|
|
const char * _value = reinterpret_cast<const char *>(&value);//Do this even for char * to prevent compiler complaining
|
|
size_t partitionKeyLength = strlen(partitionKey);
|
|
size_t partitionKeyLength = strlen(partitionKey);
|
|
const char * msg = "'Set' request failed - ";
|
|
const char * msg = "'Set' request failed - ";
|
|
if (partitionKeyLength)
|
|
if (partitionKeyLength)
|
|
- assertOnError(memcached_set_by_key(connection, partitionKey, partitionKeyLength, key, strlen(key), _value, sizeof(value), (time_t)(expire*unitExpire), (uint32_t)eclType), msg);
|
|
|
|
|
|
+ assertOnError(memcached_set_by_key(connection, partitionKey, partitionKeyLength, key, strlen(key), _value, sizeof(value), (time_t)expire, (uint32_t)eclType), msg);
|
|
else
|
|
else
|
|
- assertOnError(memcached_set(connection, key, strlen(key), _value, sizeof(value), (time_t)(expire*unitExpire), (uint32_t)eclType), msg);
|
|
|
|
|
|
+ assertOnError(memcached_set(connection, key, strlen(key), _value, sizeof(value), (time_t)expire, (uint32_t)eclType), msg);
|
|
}
|
|
}
|
|
-template<class type> void MemCachedPlugin::MCached::set(ICodeContext * ctx, const char * partitionKey, const char * key, size32_t valueLength, const type * value, unsigned expire, eclDataType eclType)
|
|
|
|
|
|
+template<class type> void MemCachedPlugin::MCached::set(ICodeContext * ctx, const char * partitionKey, const char * key, size32_t valueLength, const type * value, unsigned __int64 expire, eclDataType eclType)
|
|
{
|
|
{
|
|
const char * _value = reinterpret_cast<const char *>(value);//Do this even for char * to prevent compiler complaining
|
|
const char * _value = reinterpret_cast<const char *>(value);//Do this even for char * to prevent compiler complaining
|
|
size_t partitionKeyLength = strlen(partitionKey);
|
|
size_t partitionKeyLength = strlen(partitionKey);
|
|
const char * msg = "'Set' request failed - ";
|
|
const char * msg = "'Set' request failed - ";
|
|
if (partitionKeyLength)
|
|
if (partitionKeyLength)
|
|
- assertOnError(memcached_set_by_key(connection, partitionKey, partitionKeyLength, key, strlen(key), _value, (size_t)(valueLength), (time_t)(expire*unitExpire), (uint32_t)eclType), msg);
|
|
|
|
|
|
+ assertOnError(memcached_set_by_key(connection, partitionKey, partitionKeyLength, key, strlen(key), _value, (size_t)(valueLength), (time_t)expire, (uint32_t)eclType), msg);
|
|
else
|
|
else
|
|
- assertOnError(memcached_set(connection, key, strlen(key), _value, (size_t)(valueLength), (time_t)(expire*unitExpire), (uint32_t)eclType), msg);
|
|
|
|
|
|
+ assertOnError(memcached_set(connection, key, strlen(key), _value, (size_t)(valueLength), (time_t)expire, (uint32_t)eclType), msg);
|
|
}
|
|
}
|
|
//----------------------------------GET----------------------------------------
|
|
//----------------------------------GET----------------------------------------
|
|
template<class type> void MemCachedPlugin::MCached::get(ICodeContext * ctx, const char * partitionKey, const char * key, type & returnValue, eclDataType eclType)
|
|
template<class type> void MemCachedPlugin::MCached::get(ICodeContext * ctx, const char * partitionKey, const char * key, type & returnValue, eclDataType eclType)
|
|
@@ -563,7 +575,9 @@ void MemCachedPlugin::MCached::setPoolSettings()
|
|
assertOnError(memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, 1), msg);
|
|
assertOnError(memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, 1), msg);
|
|
#endif
|
|
#endif
|
|
assertOnError(memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_NO_BLOCK, 0), msg);
|
|
assertOnError(memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_NO_BLOCK, 0), msg);
|
|
- assertOnError(memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 100), msg);//units of ms MORE: What should I set this to or get from?
|
|
|
|
|
|
+ assertOnError(memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000), msg);//units of ms.
|
|
|
|
+ assertOnError(memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000000), msg);//units of mu-s.
|
|
|
|
+ assertOnError(memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000000), msg);//units of mu-s.
|
|
assertOnError(memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0), msg);// Buffering does not work with the ecl runtime paradigm
|
|
assertOnError(memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0), msg);// Buffering does not work with the ecl runtime paradigm
|
|
}
|
|
}
|
|
|
|
|
|
@@ -628,35 +642,35 @@ ECL_MEMCACHED_API const char * ECL_MEMCACHED_CALL MKeyType(ICodeContext * ctx, c
|
|
}
|
|
}
|
|
//-----------------------------------SET------------------------------------------
|
|
//-----------------------------------SET------------------------------------------
|
|
//NOTE: These were all overloaded by 'value' type, however; this caused problems since ecl implicitly casts and doesn't type check.
|
|
//NOTE: These were all overloaded by 'value' type, however; this caused problems since ecl implicitly casts and doesn't type check.
|
|
-ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSet(ICodeContext * ctx, const char * key, size32_t valueLength, const char * value, const char * options, const char * partitionKey, unsigned expire /* = 0 (ECL default)*/)
|
|
|
|
|
|
+ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSet(ICodeContext * ctx, const char * key, size32_t valueLength, const char * value, const char * options, const char * partitionKey, unsigned __int64 expire /* = 0 (ECL default)*/)
|
|
{
|
|
{
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, valueLength, value, expire, MemCachedPlugin::ECL_STRING);
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, valueLength, value, expire, MemCachedPlugin::ECL_STRING);
|
|
}
|
|
}
|
|
-ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSet(ICodeContext * ctx, const char * key, size32_t valueLength, const UChar * value, const char * options, const char * partitionKey, unsigned expire /* = 0 (ECL default)*/)
|
|
|
|
|
|
+ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSet(ICodeContext * ctx, const char * key, size32_t valueLength, const UChar * value, const char * options, const char * partitionKey, unsigned __int64 expire /* = 0 (ECL default)*/)
|
|
{
|
|
{
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, (valueLength)*sizeof(UChar), value, expire, MemCachedPlugin::ECL_UNICODE);
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, (valueLength)*sizeof(UChar), value, expire, MemCachedPlugin::ECL_UNICODE);
|
|
}
|
|
}
|
|
-ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSet(ICodeContext * ctx, const char * key, signed __int64 value, const char * options, const char * partitionKey, unsigned expire /* = 0 (ECL default)*/)
|
|
|
|
|
|
+ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSet(ICodeContext * ctx, const char * key, signed __int64 value, const char * options, const char * partitionKey, unsigned __int64 expire /* = 0 (ECL default)*/)
|
|
{
|
|
{
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, value, expire, MemCachedPlugin::ECL_INTEGER);
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, value, expire, MemCachedPlugin::ECL_INTEGER);
|
|
}
|
|
}
|
|
-ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSet(ICodeContext * ctx, const char * key, unsigned __int64 value, const char * options, const char * partitionKey, unsigned expire /* = 0 (ECL default)*/)
|
|
|
|
|
|
+ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSet(ICodeContext * ctx, const char * key, unsigned __int64 value, const char * options, const char * partitionKey, unsigned __int64 expire /* = 0 (ECL default)*/)
|
|
{
|
|
{
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, value, expire, MemCachedPlugin::ECL_UNSIGNED);
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, value, expire, MemCachedPlugin::ECL_UNSIGNED);
|
|
}
|
|
}
|
|
-ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSet(ICodeContext * ctx, const char * key, double value, const char * options, const char * partitionKey, unsigned expire /* = 0 (ECL default)*/)
|
|
|
|
|
|
+ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSet(ICodeContext * ctx, const char * key, double value, const char * options, const char * partitionKey, unsigned __int64 expire /* = 0 (ECL default)*/)
|
|
{
|
|
{
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, value, expire, MemCachedPlugin::ECL_REAL);
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, value, expire, MemCachedPlugin::ECL_REAL);
|
|
}
|
|
}
|
|
-ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSet(ICodeContext * ctx, const char * key, bool value, const char * options, const char * partitionKey, unsigned expire)
|
|
|
|
|
|
+ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSet(ICodeContext * ctx, const char * key, bool value, const char * options, const char * partitionKey, unsigned __int64 expire)
|
|
{
|
|
{
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, value, expire, MemCachedPlugin::ECL_BOOLEAN);
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, value, expire, MemCachedPlugin::ECL_BOOLEAN);
|
|
}
|
|
}
|
|
-ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSetData(ICodeContext * ctx, const char * key, size32_t valueLength, const void * value, const char * options, const char * partitionKey, unsigned expire)
|
|
|
|
|
|
+ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSetData(ICodeContext * ctx, const char * key, size32_t valueLength, const void * value, const char * options, const char * partitionKey, unsigned __int64 expire)
|
|
{
|
|
{
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, valueLength, value, expire, MemCachedPlugin::ECL_DATA);
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, valueLength, value, expire, MemCachedPlugin::ECL_DATA);
|
|
}
|
|
}
|
|
-ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSetUtf8(ICodeContext * ctx, const char * key, size32_t valueLength, const char * value, const char * options, const char * partitionKey, unsigned expire /* = 0 (ECL default)*/)
|
|
|
|
|
|
+ECL_MEMCACHED_API void ECL_MEMCACHED_CALL MSetUtf8(ICodeContext * ctx, const char * key, size32_t valueLength, const char * value, const char * options, const char * partitionKey, unsigned __int64 expire /* = 0 (ECL default)*/)
|
|
{
|
|
{
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, rtlUtf8Size(valueLength, value), value, expire, MemCachedPlugin::ECL_UTF8);
|
|
MemCachedPlugin::MSet(ctx, options, partitionKey, key, rtlUtf8Size(valueLength, value), value, expire, MemCachedPlugin::ECL_UTF8);
|
|
}
|
|
}
|