Skip to content

Commit f377d1a

Browse files
authoredOct 22, 2024
Extends ResultItem by timestamp (#8202)
2 parents 71d4d97 + 62fa9f1 commit f377d1a

File tree

8 files changed

+48
-11
lines changed

8 files changed

+48
-11
lines changed
 

‎src/tribler/core/recommender/community.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,17 @@ def create_crawl_query_info(query_id: int) -> dict:
6868
}
6969

7070

71-
def create_crawl_query_info_response(query_id: int, results: int, chosen_index: int, query: str) -> dict:
71+
def create_crawl_query_info_response(query_id: int, timestamp: int, results: int, chosen_index: int, query: str) -> dict:
7272
"""
7373
A response with the number of available results for the query with the id ``query_id``.
7474
"""
7575
return {
76-
"version": 0,
76+
"version": 1,
7777
"type": "query_info",
7878
"query_id": query_id,
7979
"results": results,
8080
"chosen_index": chosen_index,
81+
"timestamp": timestamp,
8182
"query": query
8283
}
8384

@@ -176,7 +177,8 @@ def process_query_info(self, peer: Peer, request: dict) -> None:
176177
query_id=query.rowid,
177178
results=len(unpacked["results"]),
178179
chosen_index=unpacked["chosen_index"],
179-
query=unpacked["query"]
180+
timestamp=unpacked.get("timestamp", 0),
181+
query=unpacked["query"],
180182
)), b""))
181183

182184
@lazy_wrapper(Crawl)
@@ -220,6 +222,7 @@ def __init__(self, request_cache: RequestCache, peer: Peer, response: dict) -> N
220222
self.total_results = response["results"]
221223
self.results: list[ResultItem | None] = [None] * self.total_results
222224
self.chosen_index = response["chosen_index"]
225+
self.timestamp = response.get("timestamp", 0)
223226
self.query = response["query"]
224227

225228
def get_next_range(self) -> tuple[int, int] | None:
@@ -300,14 +303,15 @@ def init_crawl_history(self) -> None:
300303
self.crawl_history[peer_mid] = (max_id, missing)
301304

302305
def finalize_query(self, peer: Peer, query_id: int, query: str, chosen_index: int,
303-
results: list[ResultItem]) -> None:
306+
timestamp: int, results: list[ResultItem]) -> None:
304307
"""
305308
Update self.crawl_history and write the results to a file.
306309
"""
307310
query_dir = os.path.join(self.crawl_directory, hexlify(peer.mid).decode())
308311
os.makedirs(query_dir, exist_ok=True)
309312
json_dict = {
310313
"query": query,
314+
"timestamp": timestamp,
311315
"chosen_index": chosen_index,
312316
"results": results
313317
}
@@ -356,7 +360,7 @@ def process_query_info_response(self, peer: Peer, response: dict) -> None:
356360

357361
if next_range is None:
358362
self.logger.info("Query %d is empty for %s.", response["query_id"], str(peer))
359-
self.finalize_query(peer, cache.query_id, cache.query, cache.chosen_index, [])
363+
self.finalize_query(peer, cache.query_id, cache.query, cache.chosen_index, cache.timestamp, [])
360364
else:
361365
self.request_cache.add(cache)
362366
self.ez_send(peer, Crawl(peer.mid, self.json_pack(create_crawl_fragment(
@@ -375,7 +379,7 @@ def process_query_fragment_response(self, peer: Peer, response: dict) -> None:
375379

376380
if next_range is None:
377381
self.logger.info("Query %d has completed for %s.", response["query_id"], str(peer))
378-
self.finalize_query(peer, cache.query_id, cache.query, cache.chosen_index,
382+
self.finalize_query(peer, cache.query_id, cache.query, cache.chosen_index, cache.timestamp,
379383
cast(list[ResultItem] , cache.results))
380384
else:
381385
self.request_cache.add(cache) # Reset the two-minute timer

‎src/tribler/core/recommender/manager.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,4 @@ def add_query(self, json_data: str) -> None:
5454
Inject data into our database.
5555
"""
5656
with db_session:
57-
self.Query(version=0, json=json_data)
57+
self.Query(version=1, json=json_data)

‎src/tribler/core/recommender/orm_query.py

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class Query(Entity, metaclass=IterQuery):
2929
"""
3030
{
3131
chosen_index: int,
32+
timestamp: int,
3233
query: str,
3334
results: [{infohash: str, seeders: int, leechers: int}]
3435
}

‎src/tribler/core/recommender/restapi/endpoint.py

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ def __init__(self, middlewares: tuple = (), client_max_size: int = MAX_REQUEST_S
5050
@json_schema(schema(ClickedRequest={
5151
"query": (String, "The query that led to the list of results"),
5252
"chosen_index": (String, "The winning result index in the results list"),
53+
"timestamp": (Integer, "The timestamp of the query"),
5354
"results": (List(Nested(schema(ClickedResult={"infohash": (String, "A displayed infohash"),
5455
"seeders": (Integer, "Its displayed number of seeders"),
5556
"leechers": (Integer, "Its displayed number of seeders")}))),
@@ -63,6 +64,7 @@ async def put_clicked(self, request: RequestType) -> RESTResponse:
6364
{
6465
query: str,
6566
chosen_index: int,
67+
timestamp: int,
6668
results: list[{
6769
infohash: str,
6870
seeders: int,

‎src/tribler/core/torrent_checker/torrentchecker_session.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ class UdpTrackerSession(TrackerSession):
283283
# A list of transaction IDs that have been used in order to avoid conflict.
284284
_active_session_dict: dict[UdpTrackerSession, int] = {}
285285

286-
def __init__(self, tracker_url: str, tracker_address: tuple[str, int], announce_page: str, # noqa: PLR0913
286+
def __init__(self, tracker_url: str, tracker_address: tuple[str, int], announce_page: str,
287287
timeout: float, proxy: tuple, socket_mgr: UdpSocketManager) -> None:
288288
"""
289289
Create a session for UDP trackers.

‎src/tribler/test_unit/core/recommender/test_community.py

+31-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def init_crawl_history(self) -> None:
3030
"""
3131

3232
def finalize_query(self, peer: Peer, query_id: int, query: str, chosen_index: int,
33-
results: list[ResultItem]) -> None:
33+
timestamp: int,results: list[ResultItem]) -> None:
3434
"""
3535
Don't write to disk.
3636
"""
@@ -122,7 +122,7 @@ async def test_crawl_table_empty(self) -> None:
122122
self.assertEqual("table_size", response["type"])
123123
self.assertEqual(0, response["total_queries"])
124124

125-
async def test_crawl_query(self) -> None:
125+
async def test_crawl_query_v0(self) -> None:
126126
"""
127127
Test if a single query can be crawled.
128128
"""
@@ -151,6 +151,35 @@ async def test_crawl_query(self) -> None:
151151
self.assertEqual(1, self.crawler_overlay().crawl_history[self.mid(0)][0], "The known size should be 1")
152152
self.assertSetEqual(set(), self.crawler_overlay().crawl_history[self.mid(0)][1], "There should be no missing")
153153

154+
async def test_crawl_query_v1(self) -> None:
155+
"""
156+
Test if a single query can be crawled.
157+
"""
158+
self.overlay(0).manager.add_query('{"query": "test query", "timestamp": 1234567890, "chosen_index": 2, "results": ['
159+
f'{{"infohash": "{"01" * 20}", "seeders": 1, "leechers": 2}}, '
160+
f'{{"infohash": "{"02" * 20}", "seeders": 3, "leechers": 4}}, '
161+
f'{{"infohash": "{"03" * 20}", "seeders": 5, "leechers": 6}}'
162+
']}')
163+
164+
with self.assertReceivedBy(1, [CrawlResponse, CrawlResponse, CrawlResponse]) as messages:
165+
self.crawler_overlay().crawl_next(self.peer(0))
166+
await self.deliver_messages()
167+
168+
response1 = json.loads(messages[0].data)
169+
response2 = json.loads(messages[1].data)
170+
response3 = json.loads(messages[2].data)
171+
self.assertEqual("table_size", response1["type"])
172+
self.assertEqual("query_info", response2["type"])
173+
self.assertEqual(1, response2["query_id"])
174+
self.assertEqual("query_fragment", response3["type"])
175+
self.assertEqual(1, response3["query_id"])
176+
self.assertListEqual(["01" * 20, "02" * 20, "03" * 20], response3["infohashes"])
177+
self.assertListEqual([1, 3, 5], response3["seeders"])
178+
self.assertListEqual([2, 4, 6], response3["leechers"])
179+
self.assertIn(self.mid(0), self.crawler_overlay().crawl_history)
180+
self.assertEqual(1, self.crawler_overlay().crawl_history[self.mid(0)][0], "The known size should be 1")
181+
self.assertSetEqual(set(), self.crawler_overlay().crawl_history[self.mid(0)][1], "There should be no missing")
182+
154183
async def test_crawl_query_done(self) -> None:
155184
"""
156185
Test if a crawl after completion leads to no further requests for data.

‎src/tribler/test_unit/core/recommender/test_manager.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def test_add_query(self) -> None:
2727

2828
self.assertEqual(1, size)
2929
self.assertEqual(1, result.rowid)
30-
self.assertEqual(0, result.version)
30+
self.assertEqual(1, result.version)
3131
self.assertEqual('{"key":"value"}', result.json)
3232

3333
def test_get_total_queries(self) -> None:

‎src/tribler/ui/src/services/tribler.service.ts

+1
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ export class TriblerService {
382382
return (await this.http.put(`/recommender/clicked`, {
383383
query: query,
384384
chosen_index: results.findIndex((e) => e.infohash == clicked.infohash),
385+
timestamp: Date.now(),
385386
results: results.map((x) => { return {
386387
infohash: x.infohash,
387388
seeders: x.num_seeders,

0 commit comments

Comments
 (0)
Please sign in to comment.