Don't update revision number if object was not modified

If there were not changes made to data in the database there is no
reason to bump revision numbers because the underlying drivers won't
change too. This saves cycles in case empty updates are incoming to the
API.

Co-Authored-By: Ihar Hrachyshka <ihar@redhat.com>

Closes-bug: #2065094
Change-Id: Ib74fdab7a8927ef9cc24ef7810e9cf2c264941eb
(cherry picked from commit 5795c192b8)
This commit is contained in:
Jakub Libosvar 2024-05-07 20:03:14 +00:00 committed by Ihar Hrachyshka
parent bfae864a95
commit ac1472c8cf
2 changed files with 7 additions and 4 deletions

View File

@ -78,14 +78,14 @@ class RevisionPlugin(service_base.ServicePluginBase):
def bump_revisions(self, session, context, instances):
self._enforce_if_match_constraints(session)
# bump revision number for updated objects in the session
modified_objs = {o for o in session.dirty if session.is_modified(o)}
self._bump_obj_revisions(
session,
self._get_objects_to_bump_revision(session.dirty))
session, self._get_objects_to_bump_revision(modified_objs))
# see if any created/updated/deleted objects bump the revision
# of another object
objects_with_related_revisions = [
o for o in session.deleted | session.dirty | session.new
o for o in modified_objs | set(session.deleted) | set(session.new)
if getattr(o, 'revises_on_change', ())
]
collected = session.info.setdefault('_related_bumped', set())

View File

@ -143,13 +143,13 @@ class TestRevisionPlugin(test_plugin.Ml2PluginV2TestCase):
# update
with self.port() as port:
rev = port['port']['revision_number']
new = {'port': {'name': 'nigiri'}}
def concurrent_increment(s):
db_api.sqla_remove(se.Session, 'before_commit',
concurrent_increment)
# slip in a concurrent update that will bump the revision
plugin = directory.get_plugin()
new = {'port': {'name': 'nigiri'}}
plugin.update_port(nctx.get_admin_context(),
port['port']['id'], new)
raise db_exc.DBDeadlock()
@ -160,13 +160,16 @@ class TestRevisionPlugin(test_plugin.Ml2PluginV2TestCase):
# transaction, the revision number is tested only once the first
# time the revision number service is executed for this session and
# object.
new = {'port': {'name': 'sushi'}}
self._update('ports', port['port']['id'], new,
headers={'If-Match': 'revision_number=%s' % rev},
expected_code=exc.HTTPOk.code)
new = {'port': {'name': 'salmon'}}
self._update('ports', port['port']['id'], new,
headers={'If-Match': 'revision_number=%s' %
str(int(rev) + 2)},
expected_code=exc.HTTPOk.code)
new = {'port': {'name': 'tea'}}
self._update('ports', port['port']['id'], new,
headers={'If-Match': 'revision_number=1'},
expected_code=exc.HTTPPreconditionFailed.code)