diff options
author | Sean Reifschneider <jafo@tummy.com> | 2008-05-31 16:59:15 -0600 |
---|---|---|
committer | Sean Reifschneider <jafo@tummy.com> | 2008-05-31 16:59:15 -0600 |
commit | 738f9742b03161414f9f236c93da23381a6848d1 (patch) | |
tree | b8835eed57f61b0a5c81c943b9a85e487a92e7c0 | |
parent | 9edc0a0b5a35fedff04770f3a8e74b479155e55e (diff) | |
download | python-memcached-738f9742b03161414f9f236c93da23381a6848d1.tar.gz |
* Patch from Peter Wilkinson to support using unix domain sockets.
He reports that tests succeed with with memcached daemons running,
the normal and a domain socket started via
"memcached -s memcached.socket". I massaged it quite a bit.
To use domain sockets, use a connect string of "unix:/path/to/socket"
Note however that if you are using a host name of "unix", it will now
detect "unix:11211" as being a domain socket with the name "11211".
In this case, please use "inet:unix:11211".
Because of this, it is now preferred to use a connect string prefix
of "inet:" or "unix:".
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | memcache.py | 284 | ||||
-rw-r--r-- | memcache.pyc | bin | 31989 -> 37510 bytes |
3 files changed, 165 insertions, 132 deletions
@@ -18,6 +18,19 @@ Sat, 31 May 2008 02:09:17 -0600 Sean Reifschneider <jafo@tummy.com> * Fix from Steve Schwarz delete_multi() argument "seconds" not being correctly handled. Changed it to "time" to match all other calls. + * Patch from Peter Wilkinson to support using unix domain sockets. + He reports that tests succeed with with memcached daemons running, + the normal and a domain socket started via + "memcached -s memcached.socket". I massaged it quite a bit. + + To use domain sockets, use a connect string of "unix:/path/to/socket" + Note however that if you are using a host name of "unix", it will now + detect "unix:11211" as being a domain socket with the name "11211". + In this case, please use "inet:unix:11211". + + Because of this, it is now preferred to use a connect string prefix + of "inet:" or "unix:". + Tue, 29 Apr 2008 21:03:53 -0600 Sean Reifschneider <jafo@tummy.com> * Version 1.41 diff --git a/memcache.py b/memcache.py index 8e0dd89..b9e07af 100644 --- a/memcache.py +++ b/memcache.py @@ -46,6 +46,8 @@ More detailed documentation is available in the L{Client} class. import sys import socket import time +import os +import re import types try: import cPickle as pickle @@ -797,11 +799,24 @@ class _Host: else: self.weight = 1 - if host.find(":") > 0: - self.ip, self.port = host.split(":") - self.port = int(self.port) + # parse the connection string + m = re.match(r'^(?P<proto>unix):(?P<path>.*)$', host) + if not m: + m = re.match(r'^(?P<proto>inet):' + r'(?P<host>[^:]+)(:(?P<port>[0-9]+))?$', host) + if not m: m = re.match(r'^(?P<host>[^:]+):(?P<port>[0-9]+)$', host) + if not m: + raise ValueError('Unable to parse connection string: "%s"' % host) + + hostData = m.groupdict() + if hostData.get('proto') == 'unix': + self.family = socket.AF_UNIX + self.address = hostData['path'] else: - self.ip, self.port = host, 11211 + self.family = socket.AF_INET + self.ip = hostData['host'] + self.port = int(hostData.get('port', 11211)) + self.address = ( self.ip, self.port ) if not debugfunc: debugfunc = lambda x: x @@ -833,10 +848,10 @@ class _Host: return None if self.socket: return self.socket - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s = socket.socket(self.family, socket.SOCK_STREAM) if hasattr(s, 'settimeout'): s.settimeout(self._SOCKET_TIMEOUT) try: - s.connect((self.ip, self.port)) + s.connect(self.address) except socket.timeout, msg: self.mark_dead("connect: %s" % msg) return None @@ -902,7 +917,11 @@ class _Host: d = '' if self.deaduntil: d = " (dead until %d)" % self.deaduntil - return "%s:%d%s" % (self.ip, self.port, d) + + if self.family == socket.AF_INET: + return "inet:%s:%d%s" % (self.address[0], self.address[1], d) + else: + return "unix:%s%s" % (self.address, d) def check_key(key, key_extra_len=0): """Checks sanity of key. Fails if: @@ -936,142 +955,143 @@ if __name__ == "__main__": _doctest() print "Running tests:" print - #servers = ["127.0.0.1:11211", "127.0.0.1:11212"] - servers = ["127.0.0.1:11211"] - mc = Client(servers, debug=1) + serverList = [["127.0.0.1:11211"]] + if '--do-unix' in sys.argv: + serverList.append([os.path.join(os.getcwd(), 'memcached.socket')]) + + for servers in serverList: + mc = Client(servers, debug=1) + + def to_s(val): + if not isinstance(val, types.StringTypes): + return "%s (%s)" % (val, type(val)) + return "%s" % val + def test_setget(key, val): + print "Testing set/get {'%s': %s} ..." % (to_s(key), to_s(val)), + mc.set(key, val) + newval = mc.get(key) + if newval == val: + print "OK" + return 1 + else: + print "FAIL" + return 0 + + + class FooStruct: + def __init__(self): + self.bar = "baz" + def __str__(self): + return "A FooStruct" + def __eq__(self, other): + if isinstance(other, FooStruct): + return self.bar == other.bar + return 0 + + test_setget("a_string", "some random string") + test_setget("an_integer", 42) + if test_setget("long", long(1<<30)): + print "Testing delete ...", + if mc.delete("long"): + print "OK" + else: + print "FAIL" + print "Testing get_multi ...", + print mc.get_multi(["a_string", "an_integer"]) - def to_s(val): - if not isinstance(val, types.StringTypes): - return "%s (%s)" % (val, type(val)) - return "%s" % val - def test_setget(key, val): - print "Testing set/get {'%s': %s} ..." % (to_s(key), to_s(val)), - mc.set(key, val) - newval = mc.get(key) - if newval == val: + print "Testing get(unknown value) ...", + print to_s(mc.get("unknown_value")) + + f = FooStruct() + test_setget("foostruct", f) + + print "Testing incr ...", + x = mc.incr("an_integer", 1) + if x == 43: print "OK" - return 1 else: print "FAIL" - return 0 + print "Testing decr ...", + x = mc.decr("an_integer", 1) + if x == 42: + print "OK" + else: + print "FAIL" - class FooStruct: - def __init__(self): - self.bar = "baz" - def __str__(self): - return "A FooStruct" - def __eq__(self, other): - if isinstance(other, FooStruct): - return self.bar == other.bar - return 0 + # sanity tests + print "Testing sending spaces...", + try: + x = mc.set("this has spaces", 1) + except Client.MemcachedKeyCharacterError, msg: + print "OK" + else: + print "FAIL" - test_setget("a_string", "some random string") - test_setget("an_integer", 42) - if test_setget("long", long(1<<30)): - print "Testing delete ...", - if mc.delete("long"): + print "Testing sending control characters...", + try: + x = mc.set("this\x10has\x11control characters\x02", 1) + except Client.MemcachedKeyCharacterError, msg: + print "OK" + else: + print "FAIL" + + print "Testing using insanely long key...", + try: + x = mc.set('a'*SERVER_MAX_KEY_LENGTH + 'aaaa', 1) + except Client.MemcachedKeyLengthError, msg: + print "OK" + else: + print "FAIL" + + print "Testing sending a unicode-string key...", + try: + x = mc.set(u'keyhere', 1) + except Client.MemcachedStringEncodingError, msg: + print "OK", + else: + print "FAIL", + try: + x = mc.set((u'a'*SERVER_MAX_KEY_LENGTH).encode('utf-8'), 1) + except: + print "FAIL", + else: + print "OK", + import pickle + s = pickle.loads('V\\u4f1a\np0\n.') + try: + x = mc.set((s*SERVER_MAX_KEY_LENGTH).encode('utf-8'), 1) + except Client.MemcachedKeyLengthError: print "OK" else: print "FAIL" - print "Testing get_multi ...", - print mc.get_multi(["a_string", "an_integer"]) - - print "Testing get(unknown value) ...", - print to_s(mc.get("unknown_value")) - - f = FooStruct() - test_setget("foostruct", f) - - print "Testing incr ...", - x = mc.incr("an_integer", 1) - if x == 43: - print "OK" - else: - print "FAIL" - - print "Testing decr ...", - x = mc.decr("an_integer", 1) - if x == 42: - print "OK" - else: - print "FAIL" - - # sanity tests - print "Testing sending spaces...", - try: - x = mc.set("this has spaces", 1) - except Client.MemcachedKeyCharacterError, msg: - print "OK" - else: - print "FAIL" - - print "Testing sending control characters...", - try: - x = mc.set("this\x10has\x11control characters\x02", 1) - except Client.MemcachedKeyCharacterError, msg: - print "OK" - else: - print "FAIL" - - print "Testing using insanely long key...", - try: - x = mc.set('a'*SERVER_MAX_KEY_LENGTH + 'aaaa', 1) - except Client.MemcachedKeyLengthError, msg: - print "OK" - else: - print "FAIL" - - print "Testing sending a unicode-string key...", - try: - x = mc.set(u'keyhere', 1) - except Client.MemcachedStringEncodingError, msg: - print "OK", - else: - print "FAIL", - try: - x = mc.set((u'a'*SERVER_MAX_KEY_LENGTH).encode('utf-8'), 1) - except: - print "FAIL", - else: - print "OK", - import pickle - s = pickle.loads('V\\u4f1a\np0\n.') - try: - x = mc.set((s*SERVER_MAX_KEY_LENGTH).encode('utf-8'), 1) - except Client.MemcachedKeyLengthError: - print "OK" - else: - print "FAIL" - - print "Testing using a value larger than the memcached value limit...", - x = mc.set('keyhere', 'a'*SERVER_MAX_VALUE_LENGTH) - if mc.get('keyhere') == None: - print "OK", - else: - print "FAIL", - x = mc.set('keyhere', 'a'*SERVER_MAX_VALUE_LENGTH + 'aaa') - if mc.get('keyhere') == None: - print "OK" - else: - print "FAIL" - - print "Testing set_multi() with no memcacheds running", - mc.disconnect_all() - errors = mc.set_multi({'keyhere' : 'a', 'keythere' : 'b'}) - if errors != []: - print "FAIL" - else: - print "OK" - - print "Testing delete_multi() with no memcacheds running", - mc.disconnect_all() - ret = mc.delete_multi({'keyhere' : 'a', 'keythere' : 'b'}) - if ret != 1: - print "FAIL" - else: - print "OK" + print "Testing using a value larger than the memcached value limit...", + x = mc.set('keyhere', 'a'*SERVER_MAX_VALUE_LENGTH) + if mc.get('keyhere') == None: + print "OK", + else: + print "FAIL", + x = mc.set('keyhere', 'a'*SERVER_MAX_VALUE_LENGTH + 'aaa') + if mc.get('keyhere') == None: + print "OK" + else: + print "FAIL" + print "Testing set_multi() with no memcacheds running", + mc.disconnect_all() + errors = mc.set_multi({'keyhere' : 'a', 'keythere' : 'b'}) + if errors != []: + print "FAIL" + else: + print "OK" + + print "Testing delete_multi() with no memcacheds running", + mc.disconnect_all() + ret = mc.delete_multi({'keyhere' : 'a', 'keythere' : 'b'}) + if ret != 1: + print "FAIL" + else: + print "OK" # vim: ts=4 sw=4 et : diff --git a/memcache.pyc b/memcache.pyc Binary files differindex b428282..9af4638 100644 --- a/memcache.pyc +++ b/memcache.pyc |