'Return a cached value based on the given key.
If the value does not exist or is considered to be expired
based on its creation time, the given
creation function may or may not be used to recreate the value
and persist the newly generated value in the cache.
Whether or not the function is used depends on if the
*dogpile lock* can be acquired or not.  If it can\'t, it means
a different thread or process is already running a creation
function for this key against the cache.  When the dogpile
lock cannot be acquired, the method will block if no
previous value is available, until the lock is released and
a new value available.  If a previous value
is available, that value is returned immediately without blocking.
If the :meth:`.invalidate` method has been called, and
the retrieved value\'s timestamp is older than the invalidation
timestamp, the value is unconditionally prevented from
being returned.  The method will attempt to acquire the dogpile
lock to generate a new value, or will wait
until the lock is released to return the new value.
.. versionchanged:: 0.3.0
The value is unconditionally regenerated if the creation
time is older than the last call to :meth:`.invalidate`.
:param key: Key to be retrieved. While it\'s typical for a key to be a
string, it is ultimately passed directly down to the cache backend,
before being optionally processed by the key_mangler function, so can
be of any type recognized by the backend or by the key_mangler
function, if present.
:param creator: function which creates a new value.
:param expiration_time: optional expiration time which will overide
the expiration time already configured on this :class:`.CacheRegion`
if not None.   To set no expiration, use the value -1.
:param should_cache_fn: optional callable function which will receive
the value returned by the "creator", and will then return True or
False, indicating if the value should actually be cached or not.  If
it returns False, the value is still returned, but isn\'t cached.
E.g.::
def dont_cache_none(value):
return value is not None
value = region.get_or_create("some key",
create_value,
should_cache_fn=dont_cache_none)
Above, the function returns the value of create_value() if
the cache is invalid, however if the return value is None,
it won\'t be cached.
.. versionadded:: 0.4.3
.. seealso::
:meth:`.CacheRegion.cache_on_arguments` - applies
:meth:`.get_or_create` to any function using a decorator.
:meth:`.CacheRegion.get_or_create_multi` - multiple key/value
version'

def get_or_create(self, key, creator, expiration_time=None, should_cache_fn=None):

    orig_key = key
    if self.key_mangler:
        key = self.key_mangler(key)
    def get_value():
        value = self.backend.get(key)
        if ((value is NO_VALUE) or (value.metadata['v'] != value_version) or (self._hard_invalidated and (value.metadata['ct'] < self._hard_invalidated))):
            raise NeedRegenerationException()
        ct = value.metadata['ct']
        if self._soft_invalidated:
            if (ct < self._soft_invalidated):
                ct = ((time.time() - expiration_time) - 0.0001)
        return (value.payload, ct)
    def gen_value():
        created_value = creator()
        value = self._value(created_value)
        if ((not should_cache_fn) or should_cache_fn(created_value)):
            self.backend.set(key, value)
        return (value.payload, value.metadata['ct'])
    if (expiration_time is None):
        expiration_time = self.expiration_time
    if ((expiration_time is None) and self._soft_invalidated):
        raise exception.DogpileCacheException('Non-None    expiration    time    required    for    soft    invalidation')
    if (expiration_time == (-1)):
        expiration_time = None
    if self.async_creation_runner:
        def async_creator(mutex):
            return self.async_creation_runner(self, orig_key, creator, mutex)
    else:
        async_creator = None
    with Lock(self._mutex(key), gen_value, get_value, expiration_time, async_creator) as value:
        return value
