예제 #1
0
 def insert(self, **kwargs):
     # usually kwargs would be a Storage with several keys:
     # 'locked', 'client_ip','created_datetime','modified_datetime'
     # 'unique_key', 'session_data'
     # retrieve a new key
     newid = str(self.db.r_server.incr(self.serial))
     key = self.keyprefix + ':' + newid
     if self.with_lock:
         key_lock = key + ':lock'
         acquire_lock(self.db.r_server, key_lock, newid)
     with self.db.r_server.pipeline() as pipe:
         # add it to the index
         pipe.sadd(self.id_idx, key)
         # set a hash key with the Storage
         pipe.hmset(key, kwargs)
         if self.session_expiry:
             pipe.expire(key, self.session_expiry)
         pipe.execute()
     if self.with_lock:
         release_lock(self.db, key_lock, newid)
     return newid
예제 #2
0
 def insert(self, **kwargs):
     # usually kwargs would be a Storage with several keys:
     # 'locked', 'client_ip','created_datetime','modified_datetime'
     # 'unique_key', 'session_data'
     # retrieve a new key
     newid = str(self.db.r_server.incr(self.serial))
     key = self.keyprefix + ':' + newid
     if self.with_lock:
         key_lock = key + ':lock'
         acquire_lock(self.db.r_server, key_lock, newid)
     with self.db.r_server.pipeline() as pipe:
         # add it to the index
         pipe.sadd(self.id_idx, key)
         # set a hash key with the Storage
         pipe.hmset(key, kwargs)
         if self.session_expiry:
             pipe.expire(key, self.session_expiry)
         pipe.execute()
     if self.with_lock:
         release_lock(self.db, key_lock, newid)
     return newid
예제 #3
0
 def select(self):
     if self.op == 'eq' and self.field == 'id' and self.value:
         # means that someone wants to retrieve the key self.value
         key = self.keyprefix + ':' + str(self.value)
         if self.with_lock:
             acquire_lock(self.db.r_server, key + ':lock', self.value, 2)
         rtn = {
             to_native(k): v
             for k, v in self.db.r_server.hgetall(key).items()
         }
         if rtn:
             if self.unique_key:
                 # make sure the id and unique_key are correct
                 if rtn['unique_key'] == to_native(self.unique_key):
                     rtn['update_record'] = self.update  # update record support
                 else:
                     rtn = None
         return [Storage(self.db.convert_dict_string(rtn))] if rtn else []
     elif self.op in ('ge',
                      'gt') and self.field == 'id' and self.value == 0:
         # means that someone wants the complete list
         rtn = []
         id_idx = "%s:id_idx" % self.keyprefix
         # find all session keys of this app
         allkeys = self.db.r_server.smembers(id_idx)
         for sess in allkeys:
             val = self.db.r_server.hgetall(sess)
             if not val:
                 if self.session_expiry:
                     # clean up the idx, because the key expired
                     self.db.r_server.srem(id_idx, sess)
                 continue
             val = Storage(self.db.convert_dict_string(val))
             # add a delete_record method (necessary for sessions2trash.py)
             val.delete_record = RecordDeleter(self.db, sess,
                                               self.keyprefix)
             rtn.append(val)
         return rtn
     else:
         raise Exception("Operation not supported")
예제 #4
0
 def select(self):
     if self.op == 'eq' and self.field == 'id' and self.value:
         # means that someone wants to retrieve the key self.value
         key = self.keyprefix + ':' + str(self.value)
         if self.with_lock:
             acquire_lock(self.db.r_server, key + ':lock', self.value, 2)
         rtn = self.db.r_server.hgetall(key)
         if rtn:
             if self.unique_key:
                 # make sure the id and unique_key are correct
                 if rtn[b'unique_key'] == to_bytes(self.unique_key):
                     rtn[b'update_record'] = self.update  # update record support
                 else:
                     rtn = None
         return [Storage(rtn)] if rtn else []
     elif self.op == 'ge' and self.field == 'id' and self.value == 0:
         # means that someone wants the complete list
         rtn = []
         id_idx = "%s:id_idx" % self.keyprefix
         # find all session keys of this app
         allkeys = self.db.r_server.smembers(id_idx)
         for sess in allkeys:
             val = self.db.r_server.hgetall(sess)
             if not val:
                 if self.session_expiry:
                     # clean up the idx, because the key expired
                     self.db.r_server.srem(id_idx, sess)
                 continue
             val = Storage(val)
             # add a delete_record method (necessary for sessions2trash.py)
             val.delete_record = RecordDeleter(
                 self.db, sess, self.keyprefix)
             rtn.append(val)
         return rtn
     else:
         raise Exception("Operation not supported")
예제 #5
0
 def __call__(self, key, f, time_expire=300, with_lock=None):
     if with_lock is None:
         with_lock = self.with_lock
     if time_expire is None:
         time_expire = 24 * 60 * 60
     newKey = self.__keyFormat__(key)
     value = None
     ttl = 0
     try:
         if f is None:
             # delete and never look back
             self.r_server.delete(newKey)
             return None
         # is there a value
         obj = self.r_server.get(newKey)
         # what's its ttl
         if obj:
             ttl = self.r_server.ttl(newKey)
         if ttl > time_expire:
             obj = None
         if obj:
             # was cached
             if self.debug:
                 self.r_server.incr('web2py_cache_statistics:hit_total')
             value = pickle.loads(obj)
         else:
             # naive distributed locking
             if with_lock:
                 lock_key = '%s:__lock' % newKey
                 randomvalue = time.time()
                 al = acquire_lock(self.r_server, lock_key, randomvalue)
                 try:
                     # someone may have computed it
                     obj = self.r_server.get(newKey)
                     if obj is None:
                         value = self.cache_it(newKey, f, time_expire)
                     else:
                         value = pickle.loads(obj)
                 finally:
                     release_lock(self, lock_key, al)
             else:
                 # without distributed locking
                 value = self.cache_it(newKey, f, time_expire)
         return value
     except RConnectionError:
         return self.retry_call(key, f, time_expire, with_lock)
예제 #6
0
 def __call__(self, key, f, time_expire=300, with_lock=None):
     if with_lock is None:
         with_lock = self.with_lock
     if time_expire is None:
         time_expire = 24 * 60 * 60
     newKey = self.__keyFormat__(key)
     value = None
     ttl = 0
     try:
         if f is None:
             # delete and never look back
             self.r_server.delete(newKey)
             return None
         # is there a value
         obj = self.r_server.get(newKey)
         # what's its ttl
         if obj:
             ttl = self.r_server.ttl(newKey)
         if ttl > time_expire:
             obj = None
         if obj:
             # was cached
             if self.debug:
                 self.r_server.incr('web2py_cache_statistics:hit_total')
             value = pickle.loads(obj)
         else:
             # naive distributed locking
             if with_lock:
                 lock_key = '%s:__lock' % newKey
                 randomvalue = time.time()
                 al = acquire_lock(self.r_server, lock_key, randomvalue)
                 try:
                     # someone may have computed it
                     obj = self.r_server.get(newKey)
                     if obj is None:
                         value = self.cache_it(newKey, f, time_expire)
                     else:
                         value = pickle.loads(obj)
                 finally:
                     release_lock(self, lock_key, al)
             else:
                 # without distributed locking
                 value = self.cache_it(newKey, f, time_expire)
         return value
     except RConnectionError:
         return self.retry_call(key, f, time_expire, with_lock)