Merge pull request #806 from jberry-suse/splitter-delay

request_splitter: provide and utilize an aged attribute on requests.
This commit is contained in:
Jimmy Berry 2017-04-13 15:38:09 -05:00 committed by GitHub
commit 62bde2f8ba
4 changed files with 31 additions and 14 deletions

View File

@ -387,7 +387,7 @@ def do_staging(self, subcmd, opts, *args):
print('--move and --from must be used with explicit staging and request list')
return
open_requests = api.get_open_requests()
open_requests = api.get_open_requests({'withhistory': 1})
if len(open_requests) == 0:
print('No open requests to consider')
return

View File

@ -1,3 +1,5 @@
from datetime import datetime
import dateutil.parser
import hashlib
from lxml import etree as ET
@ -7,6 +9,8 @@ class RequestSplitter(object):
self.requests = requests
self.in_ring = in_ring
self.mergeable_build_percent = 80
# 55 minutes to avoid two staging bot loops of 30 minutes
self.age_threshold = 55 * 60
self.requests_ignored = self.api.get_ignored_requests()
@ -54,14 +58,14 @@ class RequestSplitter(object):
def filter_only(self):
ret = []
for request in self.requests:
self.suppliment(request)
self.supplement(request)
if self.filter_check(request):
ret.append(request)
return ret
def split(self):
for request in self.requests:
self.suppliment(request)
self.supplement(request)
if not self.filter_check(request):
continue
@ -83,12 +87,18 @@ class RequestSplitter(object):
else:
self.other.append(request)
def suppliment(self, request):
def supplement(self, request):
""" Provide additional information for grouping """
if request.get('ignored'):
# Only supliment once.
return
history = request.find('history')
if history is not None:
created = dateutil.parser.parse(request.find('history').get('when'))
delta = datetime.utcnow() - created
request.set('aged', str(delta.total_seconds() > self.age_threshold))
target = request.find('./action/target')
target_project = target.get('project')
target_package = target.get('package')
@ -107,9 +117,9 @@ class RequestSplitter(object):
if request_id in self.requests_ignored:
request.set('ignored', str(self.requests_ignored[request_id]))
else:
request.set('ignored', 'false')
request.set('ignored', 'False')
request.set('postponed', 'false')
request.set('postponed', 'False')
def ring_get(self, target_package):
if self.api.crings:
@ -259,7 +269,7 @@ class RequestSplitter(object):
return
for request in self.grouped[group]['requests']:
request.set('postponed', 'true')
request.set('postponed', 'True')
def propose_staging(self, choose_bootstrapped):
found = False
@ -347,8 +357,12 @@ class Strategy(object):
class StrategyNone(Strategy):
def apply(self, splitter):
splitter.filter_add('./action[not(@type="add_role" or @type="change_devel")]')
splitter.filter_add('@ignored="false"')
splitter.filter_add('@postponed="false"')
# All other strategies that inherit this are not restricted by age as
# the age restriction is used to allow other strategies to be observed.
if type(self) is StrategyNone:
splitter.filter_add('@aged="True"')
splitter.filter_add('@ignored="False"')
splitter.filter_add('@postponed="False"')
class StrategyRequests(Strategy):
def apply(self, splitter):

View File

@ -549,7 +549,7 @@ class StagingAPI(object):
self.save_file_content('{}:Staging'.format(self.project), 'dashboard', 'ignored_requests', ignore)
@memoize(session=True, add_invalidate=True)
def get_open_requests(self):
def get_open_requests(self, query_extra=None):
"""
Get all requests with open review for staging project
that are not yet included in any staging project
@ -559,14 +559,16 @@ class StagingAPI(object):
requests = []
# xpath query, using the -m, -r, -s options
where = "@by_group='{}'+and+@state='new'".format(self.cstaging_group)
where = "@by_group='{}' and @state='new'".format(self.cstaging_group)
projects = [format(self.project)]
if self.cnonfree:
projects.append(self.cnonfree)
targets = ["target[@project='{}']".format(p) for p in projects]
query = "match=state/@name='review'+and+review[{}]+and+({})".format(
where, '+or+'.join(targets))
query = {'match': "state/@name='review' and review[{}] and ({})".format(
where, ' or '.join(targets))}
if query_extra is not None:
query.update(query_extra)
url = self.makeurl(['search', 'request'], query)
f = http_GET(url)
root = ET.parse(f).getroot()

View File

@ -18,6 +18,7 @@ import os
import re
import string
import time
import urllib2
import urlparse
import xml.etree.cElementTree as ET
@ -720,7 +721,7 @@ class OBS(object):
@GET('/search/request')
def search_request(self, request, uri, headers):
"""Return a search result for /search/request."""
query = urlparse.urlparse(uri).query
query = urllib2.unquote(urlparse.urlparse(uri).query)
assert query in (
"match=state/@name='review'+and+review[@by_group='factory-staging'+and+@state='new']+and+(target[@project='openSUSE:Factory']+or+target[@project='openSUSE:Factory:NonFree'])",
"match=state/@name='review'+and+review[@by_user='factory-repo-checker'+and+@state='new']+and+(target[@project='openSUSE:Factory']+or+target[@project='openSUSE:Factory:NonFree'])"