1
0
Fork 0

speedup of build import

This commit is contained in:
Christian Kühnel 2021-05-11 15:29:53 +02:00 committed by Mikhail Goncharov
parent b6d3986660
commit 3a8be70f79

View file

@ -13,6 +13,9 @@ BUILDBOT_URL = "https://lab.llvm.org/buildbot/api/v2/"
# TODO(kuhnel): retry on connection issues, maybe resuse # TODO(kuhnel): retry on connection issues, maybe resuse
# https://github.com/google/llvm-premerge-checks/blob/main/scripts/phabtalk/phabtalk.py#L44 # https://github.com/google/llvm-premerge-checks/blob/main/scripts/phabtalk/phabtalk.py#L44
# TODO(kuhnel): Import the step data so we can figure out in which step a build fails
# (e.g. compile vs. test)
def connect_to_db() -> psycopg2.extensions.connection: def connect_to_db() -> psycopg2.extensions.connection:
"""Connect to the database, create tables as needed.""" """Connect to the database, create tables as needed."""
@ -43,12 +46,14 @@ def create_tables(conn: psycopg2.extensions.connection):
ON buildbot_workers ON buildbot_workers
(timestamp);""" (timestamp);"""
) )
# Note: step_data is not yet populated with data!
cur.execute( cur.execute(
"""CREATE TABLE IF NOT EXISTS buildbot_builds ( """CREATE TABLE IF NOT EXISTS buildbot_builds (
build_id integer PRIMARY KEY,
builder_id integer NOT NULL, builder_id integer NOT NULL,
build_number integer NOT NULL, build_number integer NOT NULL,
build_data jsonb NOT NULL, build_data jsonb NOT NULL,
step_data jsonb NOT NULL step_data jsonb
);""" );"""
) )
cur.execute( cur.execute(
@ -117,58 +122,47 @@ def get_builders() -> List[int]:
return [builder["builderid"] for builder in response.json()["builders"]] return [builder["builderid"] for builder in response.json()["builders"]]
def get_last_build(builder_id: int, conn) -> int: def get_last_build(conn) -> int:
"""Get the latest build number for a builder. """Get the latest build number for a builder.
This is used to only get new builds.""" This is used to only get new builds."""
cur = conn.cursor() cur = conn.cursor()
cur.execute( cur.execute("SELECT MAX(build_id) FROM buildbot_builds")
"SELECT MAX(build_number) FROM buildbot_builds WHERE builder_id = %s;",
[builder_id],
)
row = cur.fetchone() row = cur.fetchone()
if row is None or row[0] is None: if row is None or row[0] is None:
return 0 return 0
return row[0] return row[0]
def add_build(builder: int, number: int, build: str, steps: str, conn): def get_build_status(conn: psycopg2.extensions.connection):
start_id = get_last_build(conn)
print("Updating build results, starting with {}...".format(start_id))
url = BUILDBOT_URL + "builds"
cur = conn.cursor() cur = conn.cursor()
cur.execute(
"""INSERT INTO buildbot_builds
(builder_id, build_number, build_data,step_data)
values (%s,%s,%s,%s);""",
(
builder,
number,
json.dumps(build, sort_keys=True),
json.dumps(steps, sort_keys=True),
),
)
for result_set in rest_request_iterator(
def update_build_status(conn: psycopg2.extensions.connection): url, "builds", "buildid", start_id=start_id
print("Updating build results...") ):
# import only builds we have not yet stores in the database args_str = b",".join(
for builder in get_builders(): cur.mogrify(
url = BUILDBOT_URL + "builders/{}/builds?number__gt={}".format( b" (%s,%s,%s,%s) ",
builder, get_last_build(builder, conn) (
build["buildid"],
build["builderid"],
build["number"],
json.dumps(build, sort_keys=True),
),
)
for build in result_set
if build["complete"]
) )
response = requests.get(url)
print(" builder {}".format(builder)) cur.execute(
# process builds in increasing order so we can resume the import process b"INSERT INTO buildbot_builds (build_id, builder_id, build_number, build_data) values "
# if anything goes wrong + args_str
for build in sorted(response.json()["builds"], key=lambda b: b["number"]): )
number = build["number"] print(" {}".format(result_set[-1]["buildid"]))
# only store completed builds. Otherwise we would have to update them conn.commit()
# after they are completed.
if not build["complete"]:
continue
steps = requests.get(
BUILDBOT_URL + "builders/{}/builds/{}/steps".format(builder, number)
).json()
add_build(builder, number, build, steps, conn)
conn.commit()
def rest_request_iterator( def rest_request_iterator(
@ -285,9 +279,9 @@ def buildbot_monitoring():
"""Main function of monitoring the phabricator server.""" """Main function of monitoring the phabricator server."""
conn = connect_to_db() conn = connect_to_db()
create_tables(conn) create_tables(conn)
# update_worker_status(conn) update_worker_status(conn)
# update_build_status(conn) get_build_status(conn)
# get_buildsets(conn) get_buildsets(conn)
get_buildrequests(conn) get_buildrequests(conn)
print("Completed, exiting...") print("Completed, exiting...")