Skip to content
This repository has been archived by the owner on Aug 19, 2024. It is now read-only.

Commit

Permalink
Merge pull request #80 from egbertbouman/fix_health
Browse files Browse the repository at this point in the history
Fix health checks
  • Loading branch information
egbertbouman authored Jun 18, 2024
2 parents 5556fbd + 0a7da40 commit a4f213a
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 21 deletions.
4 changes: 3 additions & 1 deletion src/tribler/core/database/restapi/database_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import asyncio
import json
import typing
from binascii import unhexlify
Expand Down Expand Up @@ -187,7 +188,8 @@ async def get_torrent_health(self, request: RequestType) -> RESTResponse:
return RESTResponse({"checking": False})

infohash = unhexlify(request.match_info["infohash"])
await self.torrent_checker.check_torrent_health(infohash, timeout=timeout, scrape_now=True)
health_check_coro = self.torrent_checker.check_torrent_health(infohash, timeout=timeout, scrape_now=True)
_ = self.register_anonymous_task("health_check", asyncio.ensure_future(health_check_coro))
return RESTResponse({"checking": True})

def add_download_progress_to_metadata_list(self, contents_list: list[dict]) -> None:
Expand Down
10 changes: 2 additions & 8 deletions src/tribler/core/libtorrent/download_manager/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ def on_tracker_warning_alert(self, alert: lt.tracker_warning_alert) -> None:
self.tracker_status[alert.url] = (peers, status)

@check_handle(None)
def on_metadata_received_alert(self, alert: lt.metadata_received_alert) -> None: # noqa: C901
def on_metadata_received_alert(self, alert: lt.metadata_received_alert) -> None:
"""
Handle a metadata received alert.
"""
Expand All @@ -471,7 +471,7 @@ def on_metadata_received_alert(self, alert: lt.metadata_received_alert) -> None:
return

try:
metadata = cast(MetainfoDict, {b"info": lt.bdecode(torrent_info.metadata()), b"leechers": 0, b"seeders": 0})
metadata = cast(MetainfoDict, {b"info": lt.bdecode(torrent_info.metadata())})
except (RuntimeError, ValueError) as e:
self._logger.warning(e)
return
Expand All @@ -494,12 +494,6 @@ def on_metadata_received_alert(self, alert: lt.metadata_received_alert) -> None:
elif tracker_urls:
metadata[b"announce"] = tracker_urls[0]

for peer in self.handle.get_peer_info():
if peer.progress == 1:
metadata[b"seeders"] += 1
else:
metadata[b"leechers"] += 1

try:
self.tdef = TorrentDef.load_from_dict(metadata)
with suppress(RuntimeError):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,10 @@ async def get_metainfo(self, infohash: bytes, timeout: float = 7, hops: int | No
"tracker_info": (list(download.tdef.get_trackers()) or [""])[0]
})

seeders, leechers = download.get_state().get_num_seeds_peers()
metainfo[b"seeders"] = seeders
metainfo[b"leechers"] = leechers

if infohash in self.metainfo_requests:
self.metainfo_requests[infohash].pending -= 1
if self.metainfo_requests[infohash].pending <= 0:
Expand Down
15 changes: 8 additions & 7 deletions src/tribler/core/torrent_checker/torrent_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,28 +338,29 @@ async def check_torrent_health(self, infohash: bytes, timeout: float = 20, scrap
tracker_set = self.get_valid_trackers_of_torrent(torrent_state.infohash)
self._logger.info("Trackers for %s: %s", infohash_hex, str(tracker_set))

responses = []
coroutines = []
for tracker_url in tracker_set:
if session := self.create_session_for_request(tracker_url, timeout=timeout):
session.add_infohash(infohash)
try:
responses.append(await self.get_tracker_response(session))
except Exception as e:
responses.append(e)
coroutines.append(self.get_tracker_response(session))

session = FakeDHTSession(self.download_manager, timeout)
session.add_infohash(infohash)
self._logger.info("DHT session has been created for %s: %s", infohash_hex, str(session))
self.sessions["DHT"].append(session)
self.register_anonymous_task("FakeDHT resolve", session.connect_to_tracker)
coroutines.append(self.get_tracker_response(session))

responses = await asyncio.gather(*coroutines, return_exceptions=True)
self._logger.info("%d responses for %s have been received: %s", len(responses), infohash_hex, str(responses))
successful_responses = [response for response in responses if not isinstance(response, Exception)]
health = aggregate_responses_for_infohash(infohash, successful_responses)
health = aggregate_responses_for_infohash(infohash, cast(List[TrackerResponse], successful_responses))
if health.last_check == 0: # if not zero, was already updated in get_tracker_response
health.last_check = int(time.time())
health.self_checked = True
self.update_torrent_health(health)
else:
# We don't need to store this in the db, but we still need to notify the GUI
self.notify(health)
return health

def create_session_for_request(self, tracker_url: str, timeout: float = 20) -> TrackerSession | None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -431,16 +431,13 @@ async def test_on_metadata_received_alert(self) -> None:
tdef = TorrentDef.load_from_memory(TORRENT_WITH_DIRS_CONTENT)
download = Download(tdef, None, checkpoint_disabled=True, config=self.create_mock_download_config())
download.handle = Mock(torrent_file=Mock(return_value=download.tdef.torrent_info),
trackers=Mock(return_value=[{"url": "http://google.com"}]),
get_peer_info=Mock(return_value=[Mock(progress=1)] * 42 + [Mock(progress=0)] * 7))
trackers=Mock(return_value=[{"url": "http://google.com"}]))
download.tdef = None

download.on_metadata_received_alert(Mock())

self.assertEqual(tdef.infohash, download.tdef.infohash)
self.assertDictEqual(tdef.metainfo[b"info"], download.tdef.metainfo[b"info"])
self.assertEqual(7, download.tdef.metainfo[b"leechers"])
self.assertEqual(42, download.tdef.metainfo[b"seeders"])
self.assertEqual(b"http://google.com", download.tdef.metainfo[b"announce"])

def test_on_metadata_received_alert_unicode_error_encode(self) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,16 @@ async def test_get_metainfo_valid_metadata(self) -> None:
download = Download(TorrentDef.load_from_memory(TORRENT_WITH_DIRS_CONTENT), None,
checkpoint_disabled=True, config=DownloadConfig(ConfigObj(StringIO(SPEC_CONTENT))))
download.handle = Mock(is_valid=Mock(return_value=True))
download.get_state = Mock(return_value=Mock(get_num_seeds_peers=Mock(return_value=(42, 7))))
config = DownloadConfig(ConfigObj(StringIO(SPEC_CONTENT)))

with patch.object(self.manager, "start_download", AsyncMock(return_value=download)), \
patch.object(self.manager, "remove_download", AsyncMock()), \
patch.object(DownloadConfig, "from_defaults", Mock(return_value=config)):
self.assertEqual(download.tdef.metainfo, await self.manager.get_metainfo(download.tdef.infohash))
metainfo = await self.manager.get_metainfo(download.tdef.infohash)
self.assertEqual(7, metainfo[b"leechers"])
self.assertEqual(42, metainfo[b"seeders"])
self.assertEqual(download.tdef.metainfo, metainfo)

async def test_get_metainfo_add_fail(self) -> None:
"""
Expand Down

0 comments on commit a4f213a

Please sign in to comment.