Change sample to use a pool of three memcached servers. Add a property to the memcached component to list multiple memcached servers. Replace spaces by tabs in memcached keys as spaces are not allowed in keys.

git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@980010 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
jsdelfino 2010-07-28 09:50:21 +00:00
commit 9e52793370
21 changed files with 112 additions and 49 deletions

View file

@ -33,7 +33,7 @@ namespace tuscany {
namespace memcache {
bool testMemCached() {
MemCached ch("localhost", 11211);
MemCached ch(mklist<string>("localhost:11211", "localhost:11212", "localhost:11213"));
const value k = mklist<value>("a");
assert(hasContent(post(k, string("AAA"), ch)));
@ -59,7 +59,7 @@ struct getLoop {
bool testGetPerf() {
const value k = mklist<value>("c");
MemCached ch("localhost", 11211);
MemCached ch(mklist<string>("localhost:11211", "localhost:11212", "localhost:11213"));
assert(hasContent(post(k, string("CCC"), ch)));
const lambda<bool()> gl = getLoop(k, ch);

View file

@ -27,6 +27,7 @@
<service name="memcache">
<t:binding.http uri="memcache"/>
</service>
<property name="servers">localhost,localhost:11212,localhost:11213</property>
</component>
</composite>

View file

@ -112,7 +112,8 @@ private:
*/
const failable<value> start(unused const list<value>& params) {
// Connect to memcached
memcache::MemCached& ch = *(new (gc_new<memcache::MemCached>()) memcache::MemCached("localhost", 11211));
const value servers = ((lambda<value(list<value>)>)car(params))(list<value>());
memcache::MemCached& ch = *(new (gc_new<memcache::MemCached>()) memcache::MemCached(tokenize(",", servers)));
// Return the component implementation lambda function
return value(lambda<value(const list<value>&)>(applyCache(ch)));

View file

@ -54,7 +54,13 @@ public:
MemCached(const string host, const int port) : owner(true) {
apr_pool_create(&pool, NULL);
apr_memcache_create(pool, 1, 0, &mc);
init(host, port);
addServer(host, port);
}
MemCached(const list<string>& servers) : owner(true) {
apr_pool_create(&pool, NULL);
apr_memcache_create(pool, 1, 0, &mc);
addServers(servers);
}
MemCached(const MemCached& c) : owner(false) {
@ -79,9 +85,9 @@ private:
friend const failable<bool> del(const value& key, const MemCached& cache);
/**
* Initialize the memcached context.
* Add servers to the memcached context.
*/
const failable<bool> init(const string& host, const int port) {
const failable<bool> addServer(const string& host, const int port) {
apr_memcache_server_t *server;
const apr_status_t sc = apr_memcache_server_create(pool, c_str(host), (apr_port_t)port, 0, 1, 1, 60, &server);
if (sc != APR_SUCCESS)
@ -91,8 +97,29 @@ private:
return mkfailure<bool>("Could not add server");
return true;
}
const failable<bool> addServers(const list<string>& servers) {
if (isNil(servers))
return true;
const list<string> toks = tokenize(":", car(servers));
const failable<bool> r = addServer(car(toks), isNil(cdr(toks))? 11211 : atoi(c_str(cadr(toks))));
if (!hasContent(r))
return r;
return addServers(cdr(servers));
}
};
/**
* Replace spaces by tabs (as spaces are not allowed in memcached keys).
*/
const char* nospaces(const char* s) {
char* c = const_cast<char*>(s);
for (; *c; c++)
if (*c == ' ')
*c = '\t';
return s;
}
/**
* Post a new item to the cache.
*/
@ -102,7 +129,7 @@ const failable<bool> post(const value& key, const value& val, const MemCached& c
const string ks(scheme::writeValue(key));
const string vs(scheme::writeValue(val));
const apr_status_t rc = apr_memcache_add(cache.mc, c_str(ks), const_cast<char*>(c_str(vs)), length(vs), 0, 27);
const apr_status_t rc = apr_memcache_add(cache.mc, nospaces(c_str(ks)), const_cast<char*>(c_str(vs)), length(vs), 0, 27);
if (rc != APR_SUCCESS)
return mkfailure<bool>("Could not add entry");
@ -119,7 +146,7 @@ const failable<bool> put(const value& key, const value& val, const MemCached& ca
const string ks(scheme::writeValue(key));
const string vs(scheme::writeValue(val));
const apr_status_t rc = apr_memcache_set(cache.mc, c_str(ks), const_cast<char*>(c_str(vs)), length(vs), 0, 27);
const apr_status_t rc = apr_memcache_set(cache.mc, nospaces(c_str(ks)), const_cast<char*>(c_str(vs)), length(vs), 0, 27);
if (rc != APR_SUCCESS)
return mkfailure<bool>("Could not set entry");
@ -141,7 +168,7 @@ const failable<value> get(const value& key, const MemCached& cache) {
char *data;
apr_size_t size;
const apr_status_t rc = apr_memcache_getp(cache.mc, cache.pool, c_str(ks), &data, &size, NULL);
const apr_status_t rc = apr_memcache_getp(cache.mc, cache.pool, nospaces(c_str(ks)), &data, &size, NULL);
if (rc != APR_SUCCESS) {
apr_pool_destroy(vpool);
return mkfailure<value>("Could not get entry");
@ -161,7 +188,7 @@ const failable<bool> del(const value& key, const MemCached& cache) {
debug(key, "memcache::delete::key");
const string ks(scheme::writeValue(key));
const apr_status_t rc = apr_memcache_delete(cache.mc, c_str(ks), 0);
const apr_status_t rc = apr_memcache_delete(cache.mc, nospaces(c_str(ks)), 0);
if (rc != APR_SUCCESS)
return mkfailure<bool>("Could not delete entry");

View file

@ -19,7 +19,11 @@
# Start memcached
here=`readlink -f $0`; here=`dirname $here`
port=$1
if [ "$port" = "" ]; then
port="11211"
fi
memcached_prefix=`cat $here/memcached.prefix`
$memcached_prefix/bin/memcached -d -l 127.0.0.1 -m 4 -p 11211
$memcached_prefix/bin/memcached -d -l 127.0.0.1 -m 4 -p $port

View file

@ -19,8 +19,12 @@
# Stop memcached
here=`readlink -f $0`; here=`dirname $here`
port=$1
if [ "$port" = "" ]; then
port="11211"
fi
memcached_prefix=`cat $here/memcached.prefix`
mc="$memcached_prefix/bin/memcached -d -l 127.0.0.1 -m 4 -p 11211"
mc="$memcached_prefix/bin/memcached -d -l 127.0.0.1 -m 4 -p $port"
kill `ps -ef | grep -v grep | grep "${mc}" | awk '{ print $2 }'`

View file

@ -18,7 +18,9 @@
# under the License.
# Setup
./memcached-start
./memcached-start 11211
./memcached-start 11212
./memcached-start 11213
sleep 1
# Test
@ -26,5 +28,7 @@ sleep 1
rc=$?
# Cleanup
./memcached-stop
./memcached-stop 11211
./memcached-stop 11212
./memcached-stop 11213
return $rc

View file

@ -26,7 +26,9 @@ SCAContribution `pwd`/
SCAComposite memcache.composite
EOF
./memcached-start
./memcached-start 11211
./memcached-start 11212
./memcached-start 11213
../../modules/http/httpd-start tmp
sleep 2
@ -36,6 +38,8 @@ rc=$?
# Cleanup
../../modules/http/httpd-stop tmp
./memcached-stop
./memcached-stop 11211
./memcached-stop 11212
./memcached-stop 11213
sleep 2
return $rc

View file

@ -19,21 +19,23 @@
import uuid
import sys
cartId = "1234"
# Convert a particular host and user email to a cart id
def cartid(host, email):
return ("cart", host(), email())
# Get the shopping cart from the cache
# Return an empty cart if not found
def getcart(id, cache):
cart = cache("get", (id,))
cart = cache("get", id)
if cart is None:
return ()
return cart
# Post a new item to the cart, create a new cart if necessary
def post(collection, item, cache):
def post(collection, item, cache, host, email):
id = str(uuid.uuid1())
cart = ((item[0], id, item[2]),) + getcart(cartId, cache)
cache("put", (cartId,), cart)
cart = ((item[0], id, item[2]),) + getcart(cartid(host, email), cache)
cache("put", cartid(host, email), cart)
return (id,)
@ -47,15 +49,15 @@ def find(id, cart):
return find(id, cart[1:])
# Get items from the cart
def get(id, cache):
def get(id, cache, host, email):
if id == ():
return ("Your Cart", cartId) + getcart(cartId, cache)
return find(id[0], getcart(cartId, cache))
return ("Your Cart", email()) + getcart(cartid(host, email), cache)
return find(id[0], getcart(cartid(host, email), cache))
# Delete items from the cart
def delete(id, cache):
def delete(id, cache, host, email):
if id == ():
return cache("delete", (cartId,))
return cache("delete", cartid(host, email))
return True
# Return the price of an item
@ -69,7 +71,6 @@ def sum(items):
return price(items[0]) + sum(items[1:])
# Return the total price of the items in the cart
def gettotal(cache):
cart = getcart(cartId, cache)
return sum(cart)
def gettotal(cache, host, email):
return sum(getcart(cartid(host, email), cache))

View file

@ -43,6 +43,8 @@
<component name="ShoppingCart">
<t:implementation.python script="shopping-cart.py"/>
<property name="host">localhost</property>
<property name="email">anonymous@localhost</property>
<service name="ShoppingCart">
<t:binding.atom uri="shoppingCart"/>
</service>
@ -64,6 +66,7 @@
<service name="Cache">
<t:binding.atom uri="cache"/>
</service>
<property name="servers">localhost:11211,localhost:11212,localhost:11213</property>
</component>
</composite>

View file

@ -19,21 +19,23 @@
import uuid
import sys
cartId = "1234"
# Convert a particular host and user email to a cart id
def cartid(host, email):
return ("cart", host(), email())
# Get the shopping cart from the cache
# Return an empty cart if not found
def getcart(id, cache):
cart = cache("get", (id,))
cart = cache("get", id)
if cart is None:
return ()
return cart
# Post a new item to the cart, create a new cart if necessary
def post(collection, item, cache):
def post(collection, item, cache, host, email):
id = str(uuid.uuid1())
cart = ((item[0], id, item[2]),) + getcart(cartId, cache)
cache("put", (cartId,), cart)
cart = ((item[0], id, item[2]),) + getcart(cartid(host, email), cache)
cache("put", cartid(host, email), cart)
return (id,)
@ -47,15 +49,15 @@ def find(id, cart):
return find(id, cart[1:])
# Get items from the cart
def get(id, cache):
def get(id, cache, host, email):
if id == ():
return ("Your Cart", cartId) + getcart(cartId, cache)
return find(id[0], getcart(cartId, cache))
return ("Your Cart", email()) + getcart(cartid(host, email), cache)
return find(id[0], getcart(cartid(host, email), cache))
# Delete items from the cart
def delete(id, cache):
def delete(id, cache, host, email):
if id == ():
return cache("delete", (cartId,))
return cache("delete", cartid(host, email))
return True
# Return the price of an item
@ -69,7 +71,6 @@ def sum(items):
return price(items[0]) + sum(items[1:])
# Return the total price of the items in the cart
def gettotal(cache):
cart = getcart(cartId, cache)
return sum(cart)
def gettotal(cache, host, email):
return sum(getcart(cartid(host, email), cache))

View file

@ -43,6 +43,8 @@
<component name="ShoppingCart">
<t:implementation.python script="shopping-cart.py"/>
<property name="host">localhost</property>
<property name="email">anonymous@localhost</property>
<service name="ShoppingCart">
<t:binding.atom uri="shoppingCart"/>
</service>
@ -64,6 +66,7 @@
<service name="Cache">
<t:binding.atom uri="cache"/>
</service>
<property name="servers">localhost:11211,localhost:11212,localhost:11213</property>
</component>
</composite>

View file

@ -99,9 +99,10 @@ cp `../../modules/http/ssl-ls tmp/ssl` tmp/proxy2/conf
../../modules/http/proxy-ssl-member-conf tmp/proxy2 localhost 8443
../../modules/http/httpd-start tmp/proxy2
# Start a shared memcached
# Todo change to one per server
../../components/cache/memcached-start
# Start three memcached servers
../../components/cache/memcached-start 11211
../../components/cache/memcached-start 11212
../../components/cache/memcached-start 11213
# Redirect traffic from port 80 to 8091 and use proxy1
#../../ubuntu/ip-redirect-all 80 8091

View file

@ -71,9 +71,10 @@ EOF
../../modules/http/proxy-member-conf tmp/proxy2 localhost 8103
../../modules/http/httpd-start tmp/proxy2
# Start a shared memcached
# Todo change to one per server
../../components/cache/memcached-start
# Start three memcached servers
../../components/cache/memcached-start 11211
../../components/cache/memcached-start 11212
../../components/cache/memcached-start 11213
# Redirect traffic from port 80 to 8091 and use proxy1
#../../ubuntu/ip-redirect-all 80 8091

View file

@ -22,4 +22,6 @@
../../modules/http/httpd-stop tmp/server3
../../modules/http/httpd-stop tmp/proxy1
../../modules/http/httpd-stop tmp/proxy2
../../components/cache/memcached-stop
../../components/cache/memcached-stop 11211
../../components/cache/memcached-stop 11212
../../components/cache/memcached-stop 11213

View file

@ -64,6 +64,7 @@
<service name="Cache">
<t:binding.atom uri="cache"/>
</service>
<property name="servers">localhost:11211</property>
</component>
</composite>

View file

@ -64,6 +64,7 @@
<service name="Cache">
<t:binding.atom uri="cache"/>
</service>
<property name="servers">localhost:11211</property>
</component>
</composite>

View file

@ -64,6 +64,7 @@
<service name="Cache">
<t:binding.atom uri="cache"/>
</service>
<property name="servers">localhost:11211</property>
</component>
</composite>

View file

@ -64,6 +64,7 @@
<service name="Cache">
<t:binding.atom uri="cache"/>
</service>
<property name="servers">localhost:11211</property>
</component>
</composite>

View file

@ -64,6 +64,7 @@
<service name="Cache">
<t:binding.atom uri="cache"/>
</service>
<property name="servers">localhost:11211</property>
</component>
</composite>

View file

@ -64,6 +64,7 @@
<service name="Cache">
<t:binding.atom uri="cache"/>
</service>
<property name="servers">localhost:11211</property>
</component>
</composite>