[IMP] runbot: speedup get_refs

Regarding the number of refs in odoo repo (arround 18 million at this
time), the parsing of the date was significant when filtering old refs.

Using unix time allows a direct comparaison without parsing the date,
and improved performance, going from ~7 seconds to ~1.3 seconds.
This commit is contained in:
Xavier-Do 2022-06-17 15:20:15 +02:00 committed by Christophe Monniez
parent cbfc8401a8
commit cdaae9b3ed
3 changed files with 13 additions and 13 deletions

View File

@ -6,7 +6,6 @@ import re
import subprocess import subprocess
import time import time
import dateutil
import requests import requests
from pathlib import Path from pathlib import Path
@ -358,10 +357,11 @@ class Repo(models.Model):
""" """
self.ensure_one() self.ensure_one()
get_ref_time = round(self._get_fetch_head_time(), 4) get_ref_time = round(self._get_fetch_head_time(), 4)
commit_limit = time.time() - 60*60*24*max_age
if not self.get_ref_time or get_ref_time > self.get_ref_time: if not self.get_ref_time or get_ref_time > self.get_ref_time:
try: try:
self.set_ref_time(get_ref_time) self.set_ref_time(get_ref_time)
fields = ['refname', 'objectname', 'committerdate:iso8601', 'authorname', 'authoremail', 'subject', 'committername', 'committeremail'] fields = ['refname', 'objectname', 'committerdate:unix', 'authorname', 'authoremail', 'subject', 'committername', 'committeremail']
fmt = "%00".join(["%(" + field + ")" for field in fields]) fmt = "%00".join(["%(" + field + ")" for field in fields])
cmd = ['for-each-ref', '--format', fmt, '--sort=-committerdate', 'refs/*/heads/*'] cmd = ['for-each-ref', '--format', fmt, '--sort=-committerdate', 'refs/*/heads/*']
if any(remote.fetch_pull for remote in self.remote_ids): if any(remote.fetch_pull for remote in self.remote_ids):
@ -371,7 +371,7 @@ class Repo(models.Model):
if not git_refs: if not git_refs:
return [] return []
refs = [tuple(field for field in line.split('\x00')) for line in git_refs.split('\n')] refs = [tuple(field for field in line.split('\x00')) for line in git_refs.split('\n')]
refs = [r for r in refs if dateutil.parser.parse(r[2][:19]) + datetime.timedelta(days=max_age) > datetime.datetime.now() or self.env['runbot.branch'].match_is_base(r[0].split('\n')[-1])] refs = [r for r in refs if int(r[2]) > commit_limit or self.env['runbot.branch'].match_is_base(r[0].split('\n')[-1])]
if ignore: if ignore:
refs = [r for r in refs if r[0].split('/')[-1] not in ignore] refs = [r for r in refs if r[0].split('/')[-1] not in ignore]
return refs return refs
@ -432,7 +432,7 @@ class Repo(models.Model):
'committer': committer, 'committer': committer,
'committer_email': committer_email, 'committer_email': committer_email,
'subject': subject, 'subject': subject,
'date': dateutil.parser.parse(date[:19]), 'date': datetime.datetime.fromtimestamp(int(date)),
}) })
branch.head = commit branch.head = commit
if not branch.alive: if not branch.alive:

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import datetime import datetime
import time
from odoo.tests.common import TransactionCase from odoo.tests.common import TransactionCase
from unittest.mock import patch, DEFAULT from unittest.mock import patch, DEFAULT
@ -37,7 +37,7 @@ class RunbotCase(TransactionCase):
self.commit_list[self.repo_server.id] = [( self.commit_list[self.repo_server.id] = [(
'refs/%s/heads/%s' % (remote.remote_name, branch_name), 'refs/%s/heads/%s' % (remote.remote_name, branch_name),
sha or 'd0d0caca', sha or 'd0d0caca',
tstamp or datetime.datetime.now().strftime("%Y-%m-%d, %H:%M:%S"), str(tstamp or int(time.time())),
committer, committer,
commiter_email, commiter_email,
subject, subject,

View File

@ -71,7 +71,7 @@ class TestRepo(RunbotCaseMinimalSetup):
first_commit = [( first_commit = [(
'refs/%s/heads/%s' % (self.remote_server_dev.remote_name, branch_name), 'refs/%s/heads/%s' % (self.remote_server_dev.remote_name, branch_name),
'd0d0caca', 'd0d0caca',
datetime.datetime.now().strftime("%Y-%m-%d, %H:%M:%S"), str(int(time.time())),
'Marc Bidule', 'Marc Bidule',
'<marc.bidule@somewhere.com>', '<marc.bidule@somewhere.com>',
'Server subject', 'Server subject',
@ -99,7 +99,7 @@ class TestRepo(RunbotCaseMinimalSetup):
# create a addons branch in the same bundle # create a addons branch in the same bundle
self.commit_list[self.repo_addons.id] = [('refs/%s/heads/%s' % (self.remote_addons_dev.remote_name, branch_name), self.commit_list[self.repo_addons.id] = [('refs/%s/heads/%s' % (self.remote_addons_dev.remote_name, branch_name),
'deadbeef', 'deadbeef',
datetime.datetime.now().strftime("%Y-%m-%d, %H:%M:%S"), str(int(time.time())),
'Marc Bidule', 'Marc Bidule',
'<marc.bidule@somewhere.com>', '<marc.bidule@somewhere.com>',
'Addons subject', 'Addons subject',
@ -127,7 +127,7 @@ class TestRepo(RunbotCaseMinimalSetup):
self.commit_list[self.repo_server.id] += [ self.commit_list[self.repo_server.id] += [
('refs/%s/pull/123' % self.remote_server.remote_name, ('refs/%s/pull/123' % self.remote_server.remote_name,
'd0d0caca', 'd0d0caca',
datetime.datetime.now().strftime("%Y-%m-%d, %H:%M:%S"), str(int(time.time())),
'Marc Bidule', 'Marc Bidule',
'<marc.bidule@somewhere.com>', '<marc.bidule@somewhere.com>',
'Another subject', 'Another subject',
@ -157,7 +157,7 @@ class TestRepo(RunbotCaseMinimalSetup):
( (
'refs/%s/heads/%s' % (self.remote_server_dev.remote_name, branch_name), 'refs/%s/heads/%s' % (self.remote_server_dev.remote_name, branch_name),
'b00b', 'b00b',
datetime.datetime.now().strftime("%Y-%m-%d, %H:%M:%S"), str(int(time.time())),
'Marc Bidule', 'Marc Bidule',
'<marc.bidule@somewhere.com>', '<marc.bidule@somewhere.com>',
'A new subject', 'A new subject',
@ -167,7 +167,7 @@ class TestRepo(RunbotCaseMinimalSetup):
( (
'refs/%s/pull/123' % self.remote_server.remote_name, 'refs/%s/pull/123' % self.remote_server.remote_name,
'b00b', 'b00b',
datetime.datetime.now().strftime("%Y-%m-%d, %H:%M:%S"), str(int(time.time())),
'Marc Bidule', 'Marc Bidule',
'<marc.bidule@somewhere.com>', '<marc.bidule@somewhere.com>',
'A new subject', 'A new subject',
@ -207,7 +207,7 @@ class TestRepo(RunbotCaseMinimalSetup):
self.commit_list[self.repo_server.id] = [ self.commit_list[self.repo_server.id] = [
('refs/%s/heads/%s' % (self.remote_server_dev.remote_name, branch_name), ('refs/%s/heads/%s' % (self.remote_server_dev.remote_name, branch_name),
'dead1234', 'dead1234',
datetime.datetime.now().strftime("%Y-%m-%d, %H:%M:%S"), str(int(time.time())),
'Marc Bidule', 'Marc Bidule',
'<marc.bidule@somewhere.com>', '<marc.bidule@somewhere.com>',
'A last subject', 'A last subject',
@ -262,7 +262,7 @@ class TestRepo(RunbotCaseMinimalSetup):
for i in range(20005): for i in range(20005):
self.commit_list[self.repo_server.id].append(['refs/heads/bidon-%05d' % i, self.commit_list[self.repo_server.id].append(['refs/heads/bidon-%05d' % i,
'd0d0caca %s' % i, 'd0d0caca %s' % i,
datetime.datetime.now().strftime("%Y-%m-%d, %H:%M:%S"), str(int(time.time())),
'Marc Bidule', 'Marc Bidule',
'<marc.bidule@somewhere.com>', '<marc.bidule@somewhere.com>',
'A nice subject', 'A nice subject',