Skip to content

Instantly share code, notes, and snippets.

@zzzeek
Last active March 4, 2020 16:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zzzeek/ba9b7dd75749dd62a1d6536a9f199698 to your computer and use it in GitHub Desktop.
Save zzzeek/ba9b7dd75749dd62a1d6536a9f199698 to your computer and use it in GitHub Desktop.
using oslo.db enginefacade with API methods that retry full transactions on failure
"""oslo.db enginefacade with intelligent retries demonstration.
This script illustrates three API functions:
* run_api_call_always_outermost - this API call is always outside of any
transactional context. A decorator asserts that this is the case.
Database errors that occur within it will trigger
the whole function to be retried.
* run_internal_api_call - this API call is always called inside of a
transactional context. A decorator asserts that this is the case.
* run_api_call_that_also_might_be_internal - this API call may be called
inside, or outside, of a transactional context. A decorator checks to see
if one is in progress or not, and applies "retry" only if there is no
external context.
The current oslo_db.enginefacade API is used fully and also includes a new
function that can be added to oslo.db which returns true/false if there
is already an enginefacade block in progress.
"""
import logging
import random
from oslo_context import context as oslo_context
from oslo_db import api as oslo_db_api
from oslo_db.sqlalchemy import enginefacade as _enginefacade
oslo_db_api.LOG.setLevel(logging.DEBUG)
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)
logging.basicConfig()
# oslo.db's retry decorator, which seems to be popular.
_retry_db_errors = oslo_db_api.wrap_db_retry(
max_retries=10,
retry_interval=0.5,
inc_retry_interval=False, # we're in a hurry
exception_checker=lambda e: True,
jitter=True,
)
# set up enginefacade using current API patterns
_enginefacade.transaction_context_provider(oslo_context.RequestContext)
enginefacade = _enginefacade.transaction_context()
enginefacade.configure(
connection="mysql+pymysql://scott:tiger@localhost/test",
# connection_debug=50,
)
def enginefacade_context_in_transaction(context):
"""Given a context used by an enginefacade, determine if the enginefacade
has already been invoked to begin a transaction block.
This function can be added to oslo.db.
"""
return hasattr(context, "_enginefacade_context") and hasattr(
context._enginefacade_context, "current"
)
def retry_db_errors_external(fn):
"""External API retry decorator.
Apply this decorator to API methods that are guaranteed to be called
before any database context has been started.
"""
decorated = _retry_db_errors(fn)
def go(context, *arg, **kw):
assert not enginefacade_context_in_transaction(context)
log.info(
"running API method %s **ALWAYS OUTSIDE** an existing "
"transaction.",
fn.__name__,
)
return decorated(context, *arg, **kw)
return go
def retry_db_errors_maybe_external(fn):
"""External / internal API retry decorator.
Apply this decorator to API methods that may be called outside of a
database context, or might be called inside one. The "retry" feature
only takes place if it were called outside.
"""
outer_version = _retry_db_errors(fn)
inner_version = fn
def go(context, *arg, **kw):
if enginefacade_context_in_transaction(context):
log.info(
"running API method %s **INSIDE** an existing transaction. "
"If it fails, you will see the outer name, not this one, "
"retried.",
fn.__name__,
)
return inner_version(context, *arg, **kw)
else:
log.info(
"running API method %s **OUTSIDE** of an existing "
"transaction. If it fails, you will see this name retried.",
fn.__name__,
)
return outer_version(context, *arg, **kw)
return go
def assert_internal_only(fn):
"""Internal API non retry decorator.
This decorator does nothing except assert that the function is
definitely called within an existing enginefacade block.
"""
def go(context, *arg, **kw):
assert enginefacade_context_in_transaction(context)
log.info(
"running API method %s **ALWAYS INSIDE** an existing "
"transaction. It should never be retried directly",
fn.__name__,
)
return fn(context, *arg, **kw)
return go
@retry_db_errors_external
def run_api_call_always_outermost(context, seed2, seed3):
"""internal API funtion that is always invoked outside of an enginefacade
block.
"""
with enginefacade.reader.using(context):
if seed2 == 1:
return run_internal_api_call(context)
else:
return run_api_call_that_also_might_be_internal(
context, seed2, seed3
)
@assert_internal_only
def run_internal_api_call(context):
"""internal API funtion that is always invoked inside of an enginefacade
block.
This call intentionally fails half the time.
"""
with enginefacade.reader.using(context):
if random.randint(1, 3) == 1:
return context.session.execute(
"select 'internal only API call'"
).scalar()
else:
# intentionally generate a database error 2/3 times
return context.session.execute(
"select * from no_such_table"
).scalar()
@retry_db_errors_maybe_external
def run_api_call_that_also_might_be_internal(context, seed2, seed3):
"""API function that may ber called from an internal or external context."""
with enginefacade.reader.using(context):
if seed3 == 1:
# call the internal only call that might fail
return run_internal_api_call(context)
else:
return context.session.execute(
"select 'internal/external API call'"
).scalar()
def outermost_request_method(seed1, seed2, seed3):
"""The application's entrypoint that creates the context."""
context = oslo_context.RequestContext()
if seed1 == 1:
result = run_api_call_always_outermost(context, seed2, seed3)
else:
result = run_api_call_that_also_might_be_internal(
context, seed2, seed3
)
print("got result: %s" % result)
for x in range(50):
print("\n\n============================================")
print("Request: %s" % x)
seed1, seed2, seed3 = (
random.randint(1, 2),
random.randint(1, 2),
random.randint(1, 2),
)
outermost_request_method(seed1, seed2, seed3)
@zzzeek
Copy link
Author

zzzeek commented Mar 4, 2020

sample output:


============================================
Request: 0
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 1
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_that_also_might_be_internal
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 2
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
got result: internal/external API call


============================================
Request: 3
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 4
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 5
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 6
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
got result: internal/external API call


============================================
Request: 7
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
got result: internal/external API call


============================================
Request: 8
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 9
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 10
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
got result: internal/external API call


============================================
Request: 11
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 12
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 13
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
got result: internal/external API call


============================================
Request: 14
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_that_also_might_be_internal
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_that_also_might_be_internal
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 15
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 16
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 17
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
got result: internal/external API call


============================================
Request: 18
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 19
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_that_also_might_be_internal
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_that_also_might_be_internal
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 20
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
got result: internal/external API call


============================================
Request: 21
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 22
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 23
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 24
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 25
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 26
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 27
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_that_also_might_be_internal
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 28
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
got result: internal/external API call


============================================
Request: 29
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 30
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 31
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
got result: internal/external API call


============================================
Request: 32
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_that_also_might_be_internal
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_that_also_might_be_internal
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_that_also_might_be_internal
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_that_also_might_be_internal
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_that_also_might_be_internal
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_that_also_might_be_internal
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


============================================
Request: 33
INFO:__main__:running API method run_api_call_that_also_might_be_internal **OUTSIDE** of an existing transaction.  If it fails, you will see this name retried.
got result: internal/external API call


============================================
Request: 34
INFO:__main__:running API method run_api_call_always_outermost **ALWAYS OUTSIDE** an existing transaction.
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
DEBUG:oslo_db.api:Performing DB retry for function __main__.run_api_call_always_outermost
INFO:__main__:running API method run_api_call_that_also_might_be_internal **INSIDE** an existing transaction.  If it fails, you will see the outer name, not this one, retried.
INFO:__main__:running API method run_internal_api_call **ALWAYS INSIDE** an existing transaction.  It should never be retried directly
got result: internal only API call


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment