From dc19606ada29a4d8afde4fcecd8ec986b47b867e Mon Sep 17 00:00:00 2001 From: Paul Barker Date: Fri, 5 Feb 2021 11:26:10 +0000 Subject: hashserv: Add get-outhash message The get-outhash message can be sent via the get_outhash client method. This works in a similar way to the get message but looks up a db entry by outhash rather than by taskhash. It is intended to be used as a read-only form of the report message. As both handle_get_outhash and handle_report use the same query string we can factor this out. Signed-off-by: Paul Barker Signed-off-by: Richard Purdie --- lib/hashserv/client.py | 6 ++++++ lib/hashserv/server.py | 46 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/lib/hashserv/client.py b/lib/hashserv/client.py index 0b7f4e42e..e05c1eb56 100644 --- a/lib/hashserv/client.py +++ b/lib/hashserv/client.py @@ -170,6 +170,12 @@ class AsyncClient(object): {"get": {"taskhash": taskhash, "method": method, "all": all_properties}} ) + async def get_outhash(self, method, outhash, taskhash): + await self._set_mode(self.MODE_NORMAL) + return await self.send_message( + {"get-outhash": {"outhash": outhash, "taskhash": taskhash, "method": method}} + ) + async def get_stats(self): await self._set_mode(self.MODE_NORMAL) return await self.send_message({"get-stats": None}) diff --git a/lib/hashserv/server.py b/lib/hashserv/server.py index 9ade988e5..a0dc0c170 100644 --- a/lib/hashserv/server.py +++ b/lib/hashserv/server.py @@ -152,6 +152,20 @@ async def copy_outhash_from_upstream(client, db, method, outhash, taskhash): class ServerClient(object): FAST_QUERY = 'SELECT taskhash, method, unihash FROM tasks_v2 WHERE method=:method AND taskhash=:taskhash ORDER BY created ASC LIMIT 1' ALL_QUERY = 'SELECT * FROM tasks_v2 WHERE method=:method AND taskhash=:taskhash ORDER BY created ASC LIMIT 1' + OUTHASH_QUERY = ''' + -- Find tasks with a matching outhash (that is, tasks that + -- are equivalent) + SELECT * FROM tasks_v2 WHERE method=:method AND outhash=:outhash + + -- If there is an exact match on the taskhash, return it. + -- Otherwise return the oldest matching outhash of any + -- taskhash + ORDER BY CASE WHEN taskhash=:taskhash THEN 1 ELSE 2 END, + created ASC + + -- Only return one row + LIMIT 1 + ''' def __init__(self, reader, writer, db, request_stats, backfill_queue, upstream, read_only): self.reader = reader @@ -164,6 +178,7 @@ class ServerClient(object): self.handlers = { 'get': self.handle_get, + 'get-outhash': self.handle_get_outhash, 'get-stream': self.handle_get_stream, 'get-stats': self.handle_get_stats, 'chunk-stream': self.handle_chunk, @@ -301,6 +316,21 @@ class ServerClient(object): self.write_message(d) + async def handle_get_outhash(self, request): + with closing(self.db.cursor()) as cursor: + cursor.execute(self.OUTHASH_QUERY, + {k: request[k] for k in ('method', 'outhash', 'taskhash')}) + + row = cursor.fetchone() + + if row is not None: + logger.debug('Found equivalent outhash %s -> %s', (row['outhash'], row['unihash'])) + d = {k: row[k] for k in row.keys()} + else: + d = None + + self.write_message(d) + async def handle_get_stream(self, request): self.write_message('ok') @@ -354,20 +384,8 @@ class ServerClient(object): async def handle_report(self, data): with closing(self.db.cursor()) as cursor: - cursor.execute(''' - -- Find tasks with a matching outhash (that is, tasks that - -- are equivalent) - SELECT taskhash, method, unihash FROM tasks_v2 WHERE method=:method AND outhash=:outhash - - -- If there is an exact match on the taskhash, return it. - -- Otherwise return the oldest matching outhash of any - -- taskhash - ORDER BY CASE WHEN taskhash=:taskhash THEN 1 ELSE 2 END, - created ASC - - -- Only return one row - LIMIT 1 - ''', {k: data[k] for k in ('method', 'outhash', 'taskhash')}) + cursor.execute(self.OUTHASH_QUERY, + {k: data[k] for k in ('method', 'outhash', 'taskhash')}) row = cursor.fetchone() -- cgit 1.2.3-korg