diff --git a/conf/config_sample.py b/conf/config_sample.py index fd52406..85d29d2 100644 --- a/conf/config_sample.py +++ b/conf/config_sample.py @@ -191,3 +191,11 @@ NOTIFY_EMAIL_SERVER = 'localhost' # E-Mail Sender NOTIFY_EMAIL_USERNAME = '' # E-Mail server SMTP Logon NOTIFY_EMAIL_PASSWORD = '' NOTIFY_EMAIL_USETLS = True + +#### Memcache #### +# Memcahce is a requirement. Enter the settings below +MEMCACHE_HOST = "localhost" # hostname or IP that runs memcached +MEMCACHE_PORT = 11211 # Port +MEMCACHE_TIMEOUT = 900 # Key timeout +MEMCACHE_PREFIX = "stratum_" # Prefix for keys + diff --git a/mining/Cache.py b/mining/Cache.py new file mode 100644 index 0000000..5f5219e --- /dev/null +++ b/mining/Cache.py @@ -0,0 +1,24 @@ +''' A simple wrapper for pylibmc. It can be overwritten with simple hashing if necessary ''' +import lib.settings as settings +import lib.logger +log = lib.logger.get_logger('Cache') + +import pylibmc + +class Cache(): + def __init__(self): + # Open a new connection + self.mc = pylibmc.Client([settings.MEMCACHE_HOST + ":" + str(settings.MEMCACHE_PORT)], binary=True) + log.info("Caching initialized") + + def set(self, key, value, time=settings.MEMCACHE_TIMEOUT): + return self.mc.set(settings.MEMCACHE_PREFIX + str(key), value, time) + + def get(self, key): + return self.mc.get(settings.MEMCACHE_PREFIX + str(key)) + + def delete(self, key): + return self.mc.delete(settings.MEMCACHE_PREFIX + str(key)) + + def exists(self, key): + return str(key) in self.mc.get(settings.MEMCACHE_PREFIX + str(key)) diff --git a/mining/DBInterface.py b/mining/DBInterface.py index f494713..3bf802d 100644 --- a/mining/DBInterface.py +++ b/mining/DBInterface.py @@ -3,6 +3,7 @@ import time from datetime import datetime import Queue import signal +import Cache import lib.settings as settings @@ -19,8 +20,7 @@ class DBInterface(): self.q = Queue.Queue() self.queueclock = None - self.usercache = {} - self.clearusercache() + self.cache = Cache.Cache() self.nextStatsUpdate = 0 @@ -67,11 +67,6 @@ class DBInterface(): return DB_None.DB_None() - def clearusercache(self): - log.debug("DBInterface.clearusercache called") - self.usercache = {} - self.usercacheclock = reactor.callLater(settings.DB_USERCACHE_TIME , self.clearusercache) - def scheduleImport(self): # This schedule's the Import if settings.DATABASE_DRIVER == "sqlite": @@ -163,19 +158,16 @@ class DBInterface(): # Force username and password to be strings username = str(username) password = str(password) - wid = username + ":-:" + password - - if wid in self.usercache: + if not settings.USERS_CHECK_PASSWORD and self.user_exists(username): return True - elif not settings.USERS_CHECK_PASSWORD and self.user_exists(username): - self.usercache[wid] = 1 + elif self.cache.get(username) == password: return True elif self.dbi.check_password(username, password): - self.usercache[wid] = 1 + self.cache.set(username, password) return True elif settings.USERS_AUTOADD == True: self.insert_user(username, password) - self.usercache[wid] = 1 + self.cache.set(username, password) return True log.info("Authentication for %s failed" % username) @@ -188,6 +180,8 @@ class DBInterface(): return self.dbi.get_user(id) def user_exists(self, username): + if self.cache.get(username) is not None: + return True user = self.dbi.get_user(username) return user is not None @@ -195,11 +189,13 @@ class DBInterface(): return self.dbi.insert_user(username, password) def delete_user(self, username): + self.mc.delete(username) self.usercache = {} return self.dbi.delete_user(username) def update_user(self, username, password): - self.usercache = {} + self.mc.delete(username) + self.mc.set(username, password) return self.dbi.update_user(username, password) def update_worker_diff(self, username, diff):