Esempio n. 1
0
def would_block(function):
    """
    Run the specified function in a nested transaction, abort the nested
    transaction to avoid any side effects being persisted, then return True if
    the function attempted to retry.
    """
    try:
        # Create a function to pass to or_else that runs the function, then
        # raises an exception to abort the nested transaction.
        def run_and_raise():
            function()
            # We need to abort this nested transaction to avoid the function's
            # side effects being persisted, and we don't differentiate between
            # a function that runs successfully and a function that raises an
            # exception (neither would retry), so just raise Exception here.
            raise Exception()
        # The call to stm.atomically isn't strictly necessary right now, but
        # I'm considering changing or_else to not revert the effects of a
        # function that ends up throwing an exception, in which case it would
        # be necessary.
        stm.atomically(lambda: stm.or_else(run_and_raise, lambda: None))
        # Function tried to retry
        return True
    except Exception:
        # Function didn't retry (either it threw an exception itself or it
        # succeeded, in which case we threw the exception for it)
        return False
Esempio n. 2
0
def with_timeout(stop_time, function):
    """
    A variant of with_delay that accepts its timeout as a number of seconds
    since the epoch at which the transaction should raise Timeout. 
    """
    var = make_timeout(stop_time)
    return stm.atomically(lambda: stm.or_else(function, lambda: wait_then_raise(var)))