yahoo-eng-team team mailing list archive
-
yahoo-eng-team team
-
Mailing list archive
-
Message #36348
[Bug 1480319] [NEW] Mutable args and wrap_db_retry
Public bug reported:
wrapped_db_retry may not work as expected if wrapped function modifies
it's mutable arguments during execution: in this case on the second
attempt the function will be called with modified args. Example:
def create_router(self, context, router):
r = router['router']
gw_info = r.pop(EXTERNAL_GW_INFO, None)
tenant_id = self._get_tenant_id_for_create(context, r)
with context.session.begin(subtransactions=True):
router_db = self._create_router_db(context, r, tenant_id)
if gw_info:
self._update_router_gw_info(context, router_db['id'],
gw_info, router=router_db)
dict = self._make_router_dict(router_db)
return dict
because of pop() on a second attempt the router dict will not have
gateway info so router will be created without it, silently and
surprisingly for users.
Just doing copy.deepcopy() inside wrap_db_retry will not work as
arguments might be complex objects(like plugins) which do not support
deepcopy(). So this needs a more crafty fix. Otherwise wrap_db_retry
should be used carefully, checking that wrapped function does not modify
mutable args.
Currently neutron uses wrap_db_retry at API layer which is not safe
given described issue.
** Affects: neutron
Importance: Undecided
Status: New
--
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to neutron.
https://bugs.launchpad.net/bugs/1480319
Title:
Mutable args and wrap_db_retry
Status in neutron:
New
Bug description:
wrapped_db_retry may not work as expected if wrapped function modifies
it's mutable arguments during execution: in this case on the second
attempt the function will be called with modified args. Example:
def create_router(self, context, router):
r = router['router']
gw_info = r.pop(EXTERNAL_GW_INFO, None)
tenant_id = self._get_tenant_id_for_create(context, r)
with context.session.begin(subtransactions=True):
router_db = self._create_router_db(context, r, tenant_id)
if gw_info:
self._update_router_gw_info(context, router_db['id'],
gw_info, router=router_db)
dict = self._make_router_dict(router_db)
return dict
because of pop() on a second attempt the router dict will not have
gateway info so router will be created without it, silently and
surprisingly for users.
Just doing copy.deepcopy() inside wrap_db_retry will not work as
arguments might be complex objects(like plugins) which do not support
deepcopy(). So this needs a more crafty fix. Otherwise wrap_db_retry
should be used carefully, checking that wrapped function does not
modify mutable args.
Currently neutron uses wrap_db_retry at API layer which is not safe
given described issue.
To manage notifications about this bug go to:
https://bugs.launchpad.net/neutron/+bug/1480319/+subscriptions
Follow ups