[LNT] r308410 - api: When removing a machine, delete runs in chunks.

Matthias Braun via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 18 19:41:29 PDT 2017


Author: matze
Date: Tue Jul 18 19:41:29 2017
New Revision: 308410

URL: http://llvm.org/viewvc/llvm-project?rev=308410&view=rev
Log:
api: When removing a machine, delete runs in chunks.

For machines with hundreds of runs we run into timeouts and OOM
situations when sqlalchemy tries to delete everything in a single atomic
operation.

Change the code to delete the runs of the machine in chunks and report
status updates back to avoid timeout and give a sense of progress to the
user.

Modified:
    lnt/trunk/lnt/server/ui/api.py
    lnt/trunk/tests/server/ui/test_api_modify.py

Modified: lnt/trunk/lnt/server/ui/api.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/api.py?rev=308410&r1=308409&r2=308410&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/api.py (original)
+++ lnt/trunk/lnt/server/ui/api.py Tue Jul 18 19:41:29 2017
@@ -1,6 +1,6 @@
 import lnt.util.ImportData
 import sqlalchemy
-from flask import current_app, g, Response
+from flask import current_app, g, Response, stream_with_context
 from flask import jsonify
 from flask import request
 from flask_restful import Resource, abort
@@ -153,8 +153,31 @@ class Machine(Resource):
     def delete(machine_id):
         ts = request.get_testsuite()
         machine = Machine._get_machine(machine_id)
-        ts.session.delete(machine)
-        ts.commit()
+
+        # Just saying ts.session.delete(machine) takes a long time and risks
+        # running into OOM or timeout situations for machines with a hundreds
+        # of runs. So instead remove machine runs in chunks.
+        def perform_delete(ts, machine):
+            while True:
+                runs = ts.query(ts.Run) \
+                    .filter(ts.Run.machine_id == machine.id) \
+                    .options(joinedload(ts.Run.samples)) \
+                    .order_by(ts.Run.id).limit(10).all()
+                if len(runs) == 0:
+                    break
+                yield "Deleting runs %s\n" % \
+                    " ".join([str(run.id) for run in runs])
+                for run in runs:
+                    ts.session.delete(run)
+                ts.commit()
+
+            ts.session.delete(machine)
+            ts.commit()
+            yield "Deleted machine %s\n" % machine_id
+
+        stream = stream_with_context(perform_delete(ts, machine))
+        return Response(stream, mimetype="text/plain")
+
 
     @staticmethod
     @requires_auth_token

Modified: lnt/trunk/tests/server/ui/test_api_modify.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/tests/server/ui/test_api_modify.py?rev=308410&r1=308409&r2=308410&view=diff
==============================================================================
--- lnt/trunk/tests/server/ui/test_api_modify.py (original)
+++ lnt/trunk/tests/server/ui/test_api_modify.py Tue Jul 18 19:41:29 2017
@@ -110,6 +110,10 @@ class JSONAPIDeleteTester(unittest.TestC
         resp = client.delete('api/db_default/v4/nts/machines/2',
                              headers={'AuthToken': 'test_token'})
         self.assertEqual(resp.status_code, 200)
+        self.assertEqual(resp.get_data(),
+'''Deleting runs 3 5 6 7 8 9
+Deleted machine 2
+''')
 
         resp = client.get('api/db_default/v4/nts/machines/2')
         self.assertEqual(resp.status_code, 404)




More information about the llvm-commits mailing list