summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Reifschneider <jafo@tummy.com>2008-05-31 16:59:15 -0600
committerSean Reifschneider <jafo@tummy.com>2008-05-31 16:59:15 -0600
commit738f9742b03161414f9f236c93da23381a6848d1 (patch)
treeb8835eed57f61b0a5c81c943b9a85e487a92e7c0
parent9edc0a0b5a35fedff04770f3a8e74b479155e55e (diff)
downloadpython-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--ChangeLog13
-rw-r--r--memcache.py284
-rw-r--r--memcache.pycbin31989 -> 37510 bytes
3 files changed, 165 insertions, 132 deletions
diff --git a/ChangeLog b/ChangeLog
index 57f0702..08cce0b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index b428282..9af4638 100644
--- a/memcache.pyc
+++ b/memcache.pyc
Binary files differ