diff --git a/Redis/include/Poco/Redis/PoolableConnectionFactory.h b/Redis/include/Poco/Redis/PoolableConnectionFactory.h new file mode 100644 index 000000000..2dad8b450 --- /dev/null +++ b/Redis/include/Poco/Redis/PoolableConnectionFactory.h @@ -0,0 +1,111 @@ +// +// PoolableConnectionFactory.h +// +// $Id$ +// +// Library: Redis +// Package: Redis +// Module: PoolableConnectionFactory +// +// Definition of the PoolableConnectionFactory class. +// +// Copyright (c) 2012, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef Redis_PoolableConnectionFactory_INCLUDED +#define Redis_PoolableConnectionFactory_INCLUDED + + +#include "Poco/Redis/Client.h" +#include "Poco/ObjectPool.h" + + +namespace Poco { + + +template<> +class PoolableObjectFactory + /// PoolableObjectFactory specialisation for Client. New connections + /// are created with the given address. +{ +public: + PoolableObjectFactory(Net::SocketAddress& address) + : _address(address) + { + } + + PoolableObjectFactory(const std::string& address) + : _address(address) + { + } + + Redis::Client::Ptr createObject() + { + return new Redis::Client(_address); + } + + bool validateObject(Redis::Client::Ptr pObject) + { + return true; + } + + void activateObject(Redis::Client::Ptr pObject) + { + } + + void deactivateObject(Redis::Client::Ptr pObject) + { + } + + void destroyObject(Redis::Client::Ptr pObject) + { + } + +private: + Net::SocketAddress _address; +}; + + +namespace Redis { + + +class Redis_API PooledConnection + /// Helper class for borrowing and returning a connection automatically from a pool. +{ +public: + PooledConnection(ObjectPool& pool, long timeoutMilliseconds = 0) : _pool(pool) + { + _client = _pool.borrowObject(timeoutMilliseconds); + } + + virtual ~PooledConnection() + { + try + { + _pool.returnObject(_client); + } + catch (...) + { + poco_unexpected(); + } + } + + operator Client::Ptr () + { + return _client; + } + +private: + ObjectPool& _pool; + Client::Ptr _client; +}; + + +} // namespace Redis +} // namespace Poco + +#endif // Redis_PoolableConnectionFactory_INCLUDED diff --git a/Redis/testsuite/src/RedisTest.cpp b/Redis/testsuite/src/RedisTest.cpp index 847d55b12..e4c61b533 100644 --- a/Redis/testsuite/src/RedisTest.cpp +++ b/Redis/testsuite/src/RedisTest.cpp @@ -17,6 +17,7 @@ #include "RedisTest.h" #include "Poco/Redis/AsyncReader.h" #include "Poco/Redis/Command.h" +#include "Poco/Redis/PoolableConnectionFactory.h" #include "CppUnit/TestCaller.h" #include "CppUnit/TestSuite.h" @@ -2852,6 +2853,27 @@ void RedisTest::testRPUSH() } } +void RedisTest::testPool() +{ + Poco::Net::SocketAddress sa(_host, _port); + Poco::PoolableObjectFactory factory(sa); + Poco::ObjectPool pool(factory, 10, 15); + + delKey("mypoolkey"); + + PooledConnection pclient1(pool); + PooledConnection pclient2(pool); + assert(pool.size() == 2); + + Command set = Command::set("mypoolkey", "Hello"); + std::string result = ((Client::Ptr) pclient1)->execute(set); + assert(result.compare("OK") == 0); + + Array get; + get << "GET" << "mypoolkey"; + BulkString keyValue = ((Client::Ptr) pclient2)->execute(get); + assert(keyValue.value().compare("Hello") == 0); +} void RedisTest::delKey(const std::string& key) { @@ -2930,5 +2952,7 @@ CppUnit::Test* RedisTest::suite() CppUnit_addTest(pSuite, RedisTest, testRPOPLPUSH); CppUnit_addTest(pSuite, RedisTest, testRPUSH); + CppUnit_addTest(pSuite, RedisTest, testPool); + return pSuite; } diff --git a/Redis/testsuite/src/RedisTest.h b/Redis/testsuite/src/RedisTest.h index 54c5db9ba..9f55ed389 100644 --- a/Redis/testsuite/src/RedisTest.h +++ b/Redis/testsuite/src/RedisTest.h @@ -84,6 +84,8 @@ public: void testRPOPLPUSH(); void testRPUSH(); + void testPool(); + void setUp(); void tearDown();