Skip to content

Commit ae772ea

Browse files
committed
refactor: update BrowserManagerHandle to use CommandExecutionContext
1 parent 7dfb29e commit ae772ea

1 file changed

Lines changed: 39 additions & 33 deletions

File tree

openwpm/browser_manager.py

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@
1212
import traceback
1313
from pathlib import Path
1414
from queue import Empty as EmptyQueue
15-
from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Type, Union
15+
from typing import Any, Dict, Optional, Tuple, Type, Union
1616

1717
import psutil
1818
from multiprocess import Process, Queue
1919
from selenium.common.exceptions import WebDriverException
2020
from tblib import Traceback, pickling_support
2121

22+
from .command_execution_context import CommandExecutionContext
2223
from .command_sequence import CommandSequence
2324
from .commands.browser_commands import FinalizeCommand
2425
from .commands.profile_commands import dump_profile
@@ -27,6 +28,7 @@
2728
from .config import BrowserParamsInternal, ManagerParamsInternal
2829
from .deploy_browsers import deploy_firefox
2930
from .errors import BrowserConfigError, BrowserCrashError, ProfileLoadError
31+
from .failure_tracker import CommandFailure
3032
from .socket_interface import ClientSocket
3133
from .storage.storage_providers import TableName
3234
from .types import BrowserId, VisitId
@@ -38,9 +40,6 @@
3840

3941
pickling_support.install()
4042

41-
if TYPE_CHECKING:
42-
from .task_manager import TaskManager
43-
4443

4544
class BrowserManagerHandle:
4645
"""The BrowserManagerHandle class is responsible for holding all the
@@ -342,16 +341,23 @@ def close_browser_manager(self, force: bool = False) -> None:
342341

343342
def execute_command_sequence(
344343
self,
345-
# Quoting to break cyclic import, see https://stackoverflow.com/a/39757388
346-
task_manager: "TaskManager",
344+
context: CommandExecutionContext,
347345
command_sequence: CommandSequence,
348346
) -> None:
349347
"""
350-
Sends CommandSequence to the BrowserManager one command at a time
348+
Sends CommandSequence to the BrowserManager one command at a time.
349+
350+
Parameters
351+
----------
352+
context : CommandExecutionContext
353+
Provides storage and failure tracking without requiring a
354+
direct reference to TaskManager.
355+
command_sequence : CommandSequence
356+
The sequence of commands to execute.
351357
"""
352358
assert self.browser_id is not None
353359
assert self.curr_visit_id is not None
354-
task_manager.sock.store_record(
360+
context.store_record(
355361
TableName("site_visits"),
356362
self.curr_visit_id,
357363
{
@@ -411,11 +417,9 @@ def execute_command_sequence(
411417
"process while executing command %s. Setting failure "
412418
"status." % (self.browser_id, str(command))
413419
)
414-
task_manager.failure_status = {
415-
"ErrorType": "CriticalChildException",
416-
"CommandSequence": command_sequence,
417-
"Exception": status[1],
418-
}
420+
context.failure_tracker.set_critical_failure(
421+
"CriticalChildException", command_sequence, exception=status[1]
422+
)
419423
error_text, tb = self._unpack_pickled_error(status[1])
420424
elif status[0] == "FAILED":
421425
command_status = "error"
@@ -435,7 +439,7 @@ def execute_command_sequence(
435439
else:
436440
raise ValueError("Unknown browser status message %s" % status)
437441

438-
task_manager.sock.store_record(
442+
context.store_record(
439443
TableName("crawl_history"),
440444
self.curr_visit_id,
441445
{
@@ -454,39 +458,42 @@ def execute_command_sequence(
454458
)
455459

456460
if command_status == "critical":
457-
task_manager.sock.finalize_visit_id(
458-
success=False,
461+
context.finalize_visit_id(
459462
visit_id=self.curr_visit_id,
463+
success=False,
460464
)
461465
return
462466

463467
if command_status != "ok":
464-
with task_manager.threadlock:
465-
task_manager.failure_count += 1
466-
if task_manager.failure_count > task_manager.failure_limit:
468+
over_limit = context.failure_tracker.record_failure(
469+
CommandFailure(
470+
browser_id=self.browser_id,
471+
command=repr(command),
472+
command_status=command_status,
473+
error=error_text,
474+
traceback=tb,
475+
)
476+
)
477+
if over_limit:
467478
self.logger.critical(
468479
"BROWSER %i: Command execution failure pushes failure "
469480
"count above the allowable limit. Setting "
470481
"failure_status." % self.browser_id
471482
)
472-
task_manager.failure_status = {
473-
"ErrorType": "ExceedCommandFailureLimit",
474-
"CommandSequence": command_sequence,
475-
}
483+
context.failure_tracker.set_critical_failure(
484+
"ExceedCommandFailureLimit", command_sequence
485+
)
476486
return
477487
self.restart_required = True
478488
self.logger.debug(
479489
"BROWSER %i: Browser restart required" % self.browser_id
480490
)
481491
# Reset failure_count at the end of each successful command sequence
482492
elif type(command) is FinalizeCommand:
483-
with task_manager.threadlock:
484-
task_manager.failure_count = 0
493+
context.failure_tracker.reset()
485494

486495
if self.restart_required:
487-
task_manager.sock.finalize_visit_id(
488-
success=False, visit_id=self.curr_visit_id
489-
)
496+
context.finalize_visit_id(visit_id=self.curr_visit_id, success=False)
490497
break
491498

492499
self.logger.info(
@@ -499,7 +506,7 @@ def execute_command_sequence(
499506
# internal buffers to drain. Stopgap in support of #135
500507
time.sleep(2)
501508

502-
if task_manager.closing:
509+
if context.closing:
503510
return
504511

505512
# Allow StorageWatchdog to utilize built-in browser reset functionality
@@ -519,10 +526,9 @@ def execute_command_sequence(
519526
"BROWSER %i: Exceeded the maximum allowable consecutive "
520527
"browser launch failures. Setting failure_status." % self.browser_id
521528
)
522-
task_manager.failure_status = {
523-
"ErrorType": "ExceedLaunchFailureLimit",
524-
"CommandSequence": command_sequence,
525-
}
529+
context.failure_tracker.set_critical_failure(
530+
"ExceedLaunchFailureLimit", command_sequence
531+
)
526532
return
527533
self.restart_required = False
528534

0 commit comments

Comments
 (0)