diff options
-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' |