Don't retry after Gerrit HTTP 409s

Gerrit will return an HTTP status 409 when you try to modify changes
that are already merged or abandoned. For example if you try to vote on
a change in these closed states. In those cases we don't actually want
to retry the request as doing so is a waste of effort.

Update the gerritconnection drive to handle HTTP 409s as a special case
that should not be retried.

Change-Id: I4bd7b8e5aa512bf0ba1d1bf7dd9a39c3843e6ff6
This commit is contained in:
Clark Boylan 2020-04-27 17:45:36 -07:00
parent 9b300bc8df
commit 6f125e56c6
1 changed files with 22 additions and 3 deletions

View File

@ -48,6 +48,10 @@ from zuul.model import Ref, Tag, Branch, Project
TIMEOUT = 30 TIMEOUT = 30
class HTTPConflictException(Exception):
message = "Received response 409"
class GerritChangeData(object): class GerritChangeData(object):
"""Compatability layer for SSH/HTTP """Compatability layer for SSH/HTTP
@ -613,7 +617,9 @@ class GerritConnection(BaseConnection):
auth=self.auth, timeout=TIMEOUT, auth=self.auth, timeout=TIMEOUT,
headers={'User-Agent': self.user_agent}) headers={'User-Agent': self.user_agent})
self.iolog.debug('Received: %s %s' % (r.status_code, r.text,)) self.iolog.debug('Received: %s %s' % (r.status_code, r.text,))
if r.status_code != 200: if r.status_code == 409:
raise HTTPConflictException()
elif r.status_code != 200:
raise Exception("Received response %s" % (r.status_code,)) raise Exception("Received response %s" % (r.status_code,))
ret = None ret = None
if r.text and len(r.text) > 4: if r.text and len(r.text) > 4:
@ -637,7 +643,9 @@ class GerritConnection(BaseConnection):
headers={'Content-Type': 'application/json;charset=UTF-8', headers={'Content-Type': 'application/json;charset=UTF-8',
'User-Agent': self.user_agent}) 'User-Agent': self.user_agent})
self.iolog.debug('Received: %s %s' % (r.status_code, r.text,)) self.iolog.debug('Received: %s %s' % (r.status_code, r.text,))
if r.status_code != 200: if r.status_code == 409:
raise HTTPConflictException()
elif r.status_code != 200:
raise Exception("Received response %s" % (r.status_code,)) raise Exception("Received response %s" % (r.status_code,))
ret = None ret = None
if r.text and len(r.text) > 4: if r.text and len(r.text) > 4:
@ -1065,6 +1073,9 @@ class GerritConnection(BaseConnection):
(changeid, change.commit, uuid), (changeid, change.commit, uuid),
checkinfo) checkinfo)
break break
except HTTPConflictException:
log.exception("Conflict submitting check data to gerrit.")
break
except Exception: except Exception:
log.exception("Error submitting check data to gerrit, " log.exception("Error submitting check data to gerrit, "
"attempt %s", x) "attempt %s", x)
@ -1108,6 +1119,9 @@ class GerritConnection(BaseConnection):
(changeid, change.commit), (changeid, change.commit),
data) data)
break break
except HTTPConflictException:
log.exception("Conflict submitting data to gerrit.")
break
except Exception: except Exception:
log.exception( log.exception(
"Error submitting data to gerrit, attempt %s", x) "Error submitting data to gerrit, attempt %s", x)
@ -1117,6 +1131,9 @@ class GerritConnection(BaseConnection):
try: try:
self.post('changes/%s/submit' % (changeid,), {}) self.post('changes/%s/submit' % (changeid,), {})
break break
except HTTPConflictException:
log.exception("Conflict submitting data to gerrit.")
break
except Exception: except Exception:
log.exception( log.exception(
"Error submitting data to gerrit, attempt %s", x) "Error submitting data to gerrit, attempt %s", x)
@ -1261,7 +1278,9 @@ class GerritConnection(BaseConnection):
auth=self.auth, timeout=TIMEOUT, auth=self.auth, timeout=TIMEOUT,
headers={'User-Agent': self.user_agent}) headers={'User-Agent': self.user_agent})
self.iolog.debug('Received: %s %s' % (r.status_code, r.text,)) self.iolog.debug('Received: %s %s' % (r.status_code, r.text,))
if r.status_code != 200: if r.status_code == 409:
raise HTTPConflictException()
elif r.status_code != 200:
raise Exception("Received response %s" % (r.status_code,)) raise Exception("Received response %s" % (r.status_code,))
out = r.text[r.text.find('\n') + 5:] out = r.text[r.text.find('\n') + 5:]
else: else: