Sync memorycache and timeutils from oslo.
Change-Id: Ibc61b07fe65d97f9a0eb60e514e29bc12b2f9f4a
This commit is contained in:
96
keystoneclient/openstack/common/memorycache.py
Normal file
96
keystoneclient/openstack/common/memorycache.py
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2010 United States Government as represented by the
|
||||||
|
# Administrator of the National Aeronautics and Space Administration.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
"""Super simple fake memcache client."""
|
||||||
|
|
||||||
|
from oslo.config import cfg
|
||||||
|
|
||||||
|
from keystoneclient.openstack.common import timeutils
|
||||||
|
|
||||||
|
memcache_opts = [
|
||||||
|
cfg.ListOpt('memcached_servers',
|
||||||
|
default=None,
|
||||||
|
help='Memcached servers or None for in process cache.'),
|
||||||
|
]
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
CONF.register_opts(memcache_opts)
|
||||||
|
|
||||||
|
|
||||||
|
def get_client(memcached_servers=None):
|
||||||
|
client_cls = Client
|
||||||
|
|
||||||
|
if not memcached_servers:
|
||||||
|
memcached_servers = CONF.memcached_servers
|
||||||
|
if memcached_servers:
|
||||||
|
try:
|
||||||
|
import memcache
|
||||||
|
client_cls = memcache.Client
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return client_cls(memcached_servers, debug=0)
|
||||||
|
|
||||||
|
|
||||||
|
class Client(object):
|
||||||
|
"""Replicates a tiny subset of memcached client interface."""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
"""Ignores the passed in args."""
|
||||||
|
self.cache = {}
|
||||||
|
|
||||||
|
def get(self, key):
|
||||||
|
"""Retrieves the value for a key or None.
|
||||||
|
|
||||||
|
this expunges expired keys during each get"""
|
||||||
|
|
||||||
|
now = timeutils.utcnow_ts()
|
||||||
|
for k in self.cache.keys():
|
||||||
|
(timeout, _value) = self.cache[k]
|
||||||
|
if timeout and now >= timeout:
|
||||||
|
del self.cache[k]
|
||||||
|
|
||||||
|
return self.cache.get(key, (0, None))[1]
|
||||||
|
|
||||||
|
def set(self, key, value, time=0, min_compress_len=0):
|
||||||
|
"""Sets the value for a key."""
|
||||||
|
timeout = 0
|
||||||
|
if time != 0:
|
||||||
|
timeout = timeutils.utcnow_ts() + time
|
||||||
|
self.cache[key] = (timeout, value)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def add(self, key, value, time=0, min_compress_len=0):
|
||||||
|
"""Sets the value for a key if it doesn't exist."""
|
||||||
|
if self.get(key) is not None:
|
||||||
|
return False
|
||||||
|
return self.set(key, value, time, min_compress_len)
|
||||||
|
|
||||||
|
def incr(self, key, delta=1):
|
||||||
|
"""Increments the value for a key."""
|
||||||
|
value = self.get(key)
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
new_value = int(value) + delta
|
||||||
|
self.cache[key] = (self.cache[key][0], str(new_value))
|
||||||
|
return new_value
|
||||||
|
|
||||||
|
def delete(self, key, time=0):
|
||||||
|
"""Deletes the value associated with a key."""
|
||||||
|
if key in self.cache:
|
||||||
|
del self.cache[key]
|
@@ -71,11 +71,15 @@ def normalize_time(timestamp):
|
|||||||
|
|
||||||
def is_older_than(before, seconds):
|
def is_older_than(before, seconds):
|
||||||
"""Return True if before is older than seconds."""
|
"""Return True if before is older than seconds."""
|
||||||
|
if isinstance(before, basestring):
|
||||||
|
before = parse_strtime(before).replace(tzinfo=None)
|
||||||
return utcnow() - before > datetime.timedelta(seconds=seconds)
|
return utcnow() - before > datetime.timedelta(seconds=seconds)
|
||||||
|
|
||||||
|
|
||||||
def is_newer_than(after, seconds):
|
def is_newer_than(after, seconds):
|
||||||
"""Return True if after is newer than seconds."""
|
"""Return True if after is newer than seconds."""
|
||||||
|
if isinstance(after, basestring):
|
||||||
|
after = parse_strtime(after).replace(tzinfo=None)
|
||||||
return after - utcnow() > datetime.timedelta(seconds=seconds)
|
return after - utcnow() > datetime.timedelta(seconds=seconds)
|
||||||
|
|
||||||
|
|
||||||
@@ -87,22 +91,37 @@ def utcnow_ts():
|
|||||||
def utcnow():
|
def utcnow():
|
||||||
"""Overridable version of utils.utcnow."""
|
"""Overridable version of utils.utcnow."""
|
||||||
if utcnow.override_time:
|
if utcnow.override_time:
|
||||||
return utcnow.override_time
|
try:
|
||||||
|
return utcnow.override_time.pop(0)
|
||||||
|
except AttributeError:
|
||||||
|
return utcnow.override_time
|
||||||
return datetime.datetime.utcnow()
|
return datetime.datetime.utcnow()
|
||||||
|
|
||||||
|
|
||||||
|
def iso8601_from_timestamp(timestamp):
|
||||||
|
"""Returns a iso8601 formated date from timestamp"""
|
||||||
|
return isotime(datetime.datetime.utcfromtimestamp(timestamp))
|
||||||
|
|
||||||
|
|
||||||
utcnow.override_time = None
|
utcnow.override_time = None
|
||||||
|
|
||||||
|
|
||||||
def set_time_override(override_time=datetime.datetime.utcnow()):
|
def set_time_override(override_time=datetime.datetime.utcnow()):
|
||||||
"""Override utils.utcnow to return a constant time."""
|
"""
|
||||||
|
Override utils.utcnow to return a constant time or a list thereof,
|
||||||
|
one at a time.
|
||||||
|
"""
|
||||||
utcnow.override_time = override_time
|
utcnow.override_time = override_time
|
||||||
|
|
||||||
|
|
||||||
def advance_time_delta(timedelta):
|
def advance_time_delta(timedelta):
|
||||||
"""Advance overridden time using a datetime.timedelta."""
|
"""Advance overridden time using a datetime.timedelta."""
|
||||||
assert(not utcnow.override_time is None)
|
assert(not utcnow.override_time is None)
|
||||||
utcnow.override_time += timedelta
|
try:
|
||||||
|
for dt in utcnow.override_time:
|
||||||
|
dt += timedelta
|
||||||
|
except TypeError:
|
||||||
|
utcnow.override_time += timedelta
|
||||||
|
|
||||||
|
|
||||||
def advance_time_seconds(seconds):
|
def advance_time_seconds(seconds):
|
||||||
@@ -135,3 +154,29 @@ def unmarshall_time(tyme):
|
|||||||
minute=tyme['minute'],
|
minute=tyme['minute'],
|
||||||
second=tyme['second'],
|
second=tyme['second'],
|
||||||
microsecond=tyme['microsecond'])
|
microsecond=tyme['microsecond'])
|
||||||
|
|
||||||
|
|
||||||
|
def delta_seconds(before, after):
|
||||||
|
"""
|
||||||
|
Compute the difference in seconds between two date, time, or
|
||||||
|
datetime objects (as a float, to microsecond resolution).
|
||||||
|
"""
|
||||||
|
delta = after - before
|
||||||
|
try:
|
||||||
|
return delta.total_seconds()
|
||||||
|
except AttributeError:
|
||||||
|
return ((delta.days * 24 * 3600) + delta.seconds +
|
||||||
|
float(delta.microseconds) / (10 ** 6))
|
||||||
|
|
||||||
|
|
||||||
|
def is_soon(dt, window):
|
||||||
|
"""
|
||||||
|
Determines if time is going to happen in the next window seconds.
|
||||||
|
|
||||||
|
:params dt: the time
|
||||||
|
:params window: minimum seconds to remain to consider the time not soon
|
||||||
|
|
||||||
|
:return: True if expiration is within the given duration
|
||||||
|
"""
|
||||||
|
soon = (utcnow() + datetime.timedelta(seconds=window))
|
||||||
|
return normalize_time(dt) <= soon
|
||||||
|
Reference in New Issue
Block a user