diff options
| author | Joshua Watt <JPEWhacker@gmail.com> | 2023-10-06 09:36:44 -0600 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2023-10-09 15:48:44 +0100 |
| commit | b026e816f710170138fa23c9cbc8aa8c1a882647 (patch) | |
| tree | 1e0ad22d1d94e6c01e2168471e72dc466bd7e807 | |
| parent | cc218dd1080b4df151e90c6e4a0c3d664e1aeee2 (diff) | |
| download | poky-b026e816f710170138fa23c9cbc8aa8c1a882647.tar.gz | |
bitbake: hashserv: Add API to clean unused entries
Adds an API to remove unused entries in the outhash database based on
age and if they are referenced by any unihash
(Bitbake rev: a169ac523d166c6cbba918b152a76782176c3e88)
Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
| -rw-r--r-- | bitbake/lib/hashserv/client.py | 5 | ||||
| -rw-r--r-- | bitbake/lib/hashserv/server.py | 20 | ||||
| -rw-r--r-- | bitbake/lib/hashserv/tests.py | 19 |
3 files changed, 43 insertions, 1 deletions
diff --git a/bitbake/lib/hashserv/client.py b/bitbake/lib/hashserv/client.py index eeafeabda0..f676d267fa 100644 --- a/bitbake/lib/hashserv/client.py +++ b/bitbake/lib/hashserv/client.py | |||
| @@ -105,6 +105,10 @@ class AsyncClient(bb.asyncrpc.AsyncClient): | |||
| 105 | await self._set_mode(self.MODE_NORMAL) | 105 | await self._set_mode(self.MODE_NORMAL) |
| 106 | return await self.send_message({"remove": {"where": where}}) | 106 | return await self.send_message({"remove": {"where": where}}) |
| 107 | 107 | ||
| 108 | async def clean_unused(self, max_age): | ||
| 109 | await self._set_mode(self.MODE_NORMAL) | ||
| 110 | return await self.send_message({"clean-unused": {"max_age_seconds": max_age}}) | ||
| 111 | |||
| 108 | 112 | ||
| 109 | class Client(bb.asyncrpc.Client): | 113 | class Client(bb.asyncrpc.Client): |
| 110 | def __init__(self): | 114 | def __init__(self): |
| @@ -120,6 +124,7 @@ class Client(bb.asyncrpc.Client): | |||
| 120 | "reset_stats", | 124 | "reset_stats", |
| 121 | "backfill_wait", | 125 | "backfill_wait", |
| 122 | "remove", | 126 | "remove", |
| 127 | "clean_unused", | ||
| 123 | ) | 128 | ) |
| 124 | 129 | ||
| 125 | def _get_async_client(self): | 130 | def _get_async_client(self): |
diff --git a/bitbake/lib/hashserv/server.py b/bitbake/lib/hashserv/server.py index d52e1d46df..45bf476bfe 100644 --- a/bitbake/lib/hashserv/server.py +++ b/bitbake/lib/hashserv/server.py | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | # | 4 | # |
| 5 | 5 | ||
| 6 | from contextlib import closing, contextmanager | 6 | from contextlib import closing, contextmanager |
| 7 | from datetime import datetime | 7 | from datetime import datetime, timedelta |
| 8 | import enum | 8 | import enum |
| 9 | import asyncio | 9 | import asyncio |
| 10 | import logging | 10 | import logging |
| @@ -187,6 +187,7 @@ class ServerClient(bb.asyncrpc.AsyncServerConnection): | |||
| 187 | 'reset-stats': self.handle_reset_stats, | 187 | 'reset-stats': self.handle_reset_stats, |
| 188 | 'backfill-wait': self.handle_backfill_wait, | 188 | 'backfill-wait': self.handle_backfill_wait, |
| 189 | 'remove': self.handle_remove, | 189 | 'remove': self.handle_remove, |
| 190 | 'clean-unused': self.handle_clean_unused, | ||
| 190 | }) | 191 | }) |
| 191 | 192 | ||
| 192 | def validate_proto_version(self): | 193 | def validate_proto_version(self): |
| @@ -542,6 +543,23 @@ class ServerClient(bb.asyncrpc.AsyncServerConnection): | |||
| 542 | 543 | ||
| 543 | self.write_message({"count": count}) | 544 | self.write_message({"count": count}) |
| 544 | 545 | ||
| 546 | async def handle_clean_unused(self, request): | ||
| 547 | max_age = request["max_age_seconds"] | ||
| 548 | with closing(self.db.cursor()) as cursor: | ||
| 549 | cursor.execute( | ||
| 550 | """ | ||
| 551 | DELETE FROM outhashes_v2 WHERE created<:oldest AND NOT EXISTS ( | ||
| 552 | SELECT unihashes_v2.id FROM unihashes_v2 WHERE unihashes_v2.method=outhashes_v2.method AND unihashes_v2.taskhash=outhashes_v2.taskhash LIMIT 1 | ||
| 553 | ) | ||
| 554 | """, | ||
| 555 | { | ||
| 556 | "oldest": datetime.now() - timedelta(seconds=-max_age) | ||
| 557 | } | ||
| 558 | ) | ||
| 559 | count = cursor.rowcount | ||
| 560 | |||
| 561 | self.write_message({"count": count}) | ||
| 562 | |||
| 545 | def query_equivalent(self, cursor, method, taskhash): | 563 | def query_equivalent(self, cursor, method, taskhash): |
| 546 | # This is part of the inner loop and must be as fast as possible | 564 | # This is part of the inner loop and must be as fast as possible |
| 547 | cursor.execute( | 565 | cursor.execute( |
diff --git a/bitbake/lib/hashserv/tests.py b/bitbake/lib/hashserv/tests.py index a3e066406e..f343c586b5 100644 --- a/bitbake/lib/hashserv/tests.py +++ b/bitbake/lib/hashserv/tests.py | |||
| @@ -158,6 +158,25 @@ class HashEquivalenceCommonTests(object): | |||
| 158 | result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash) | 158 | result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash) |
| 159 | self.assertIsNone(result_outhash) | 159 | self.assertIsNone(result_outhash) |
| 160 | 160 | ||
| 161 | def test_clean_unused(self): | ||
| 162 | taskhash, outhash, unihash = self.test_create_hash() | ||
| 163 | |||
| 164 | # Clean the database, which should not remove anything because all hashes an in-use | ||
| 165 | result = self.client.clean_unused(0) | ||
| 166 | self.assertEqual(result["count"], 0) | ||
| 167 | self.assertClientGetHash(self.client, taskhash, unihash) | ||
| 168 | |||
| 169 | # Remove the unihash. The row in the outhash table should still be present | ||
| 170 | self.client.remove({"unihash": unihash}) | ||
| 171 | result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash, False) | ||
| 172 | self.assertIsNotNone(result_outhash) | ||
| 173 | |||
| 174 | # Now clean with no minimum age which will remove the outhash | ||
| 175 | result = self.client.clean_unused(0) | ||
| 176 | self.assertEqual(result["count"], 1) | ||
| 177 | result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash, False) | ||
| 178 | self.assertIsNone(result_outhash) | ||
| 179 | |||
| 161 | def test_huge_message(self): | 180 | def test_huge_message(self): |
| 162 | # Simple test that hashes can be created | 181 | # Simple test that hashes can be created |
| 163 | taskhash = 'c665584ee6817aa99edfc77a44dd853828279370' | 182 | taskhash = 'c665584ee6817aa99edfc77a44dd853828279370' |
