Skip to content

Commit f5610ea

Browse files
committed
Implement worker suspend/resume
Bump to 0.0.39
1 parent 3719e57 commit f5610ea

File tree

4 files changed

+51
-4
lines changed

4 files changed

+51
-4
lines changed

examples/example_single_editor.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
import os
33
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
44
from pyqt_code_editor import watchdog
5-
from qtpy.QtWidgets import QApplication, QVBoxLayout, QWidget
5+
from qtpy.QtWidgets import QApplication, QVBoxLayout, QWidget, QShortcut
6+
from qtpy.QtGui import QKeySequence
7+
from qtpy.QtCore import Qt
68
from pyqt_code_editor.code_editors import create_editor
79
from pyqt_code_editor.environment_manager import environment_manager
10+
from pyqt_code_editor.worker import manager
811
import logging
912
logging.basicConfig(level=logging.INFO, force=True)
1013

@@ -19,6 +22,23 @@ def __init__(self, path=None):
1922
layout.addWidget(self.editor)
2023
self.setLayout(layout)
2124

25+
# Keyboard shortcuts for suspending/resuming workers
26+
self.suspend_shortcut = QShortcut(QKeySequence("Ctrl+T"), self)
27+
self.suspend_shortcut.setContext(Qt.ApplicationShortcut)
28+
self.suspend_shortcut.activated.connect(self.suspend_workers)
29+
30+
self.resume_shortcut = QShortcut(QKeySequence("Ctrl+Y"), self)
31+
self.resume_shortcut.setContext(Qt.ApplicationShortcut)
32+
self.resume_shortcut.activated.connect(self.resume_workers)
33+
34+
def suspend_workers(self):
35+
logging.info("Suspending worker processes")
36+
manager.suspend()
37+
38+
def resume_workers(self):
39+
logging.info("Resuming worker processes")
40+
manager.resume()
41+
2242
def closeEvent(self, event):
2343
watchdog.shutdown()
2444
super().closeEvent(event)
@@ -31,4 +51,4 @@ def closeEvent(self, event):
3151
path = sys.argv[1]
3252
win = MainWindow(path)
3353
win.show()
34-
sys.exit(app.exec_())
54+
sys.exit(app.exec_())

pyqt_code_editor/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
from ._settings import settings
44

5-
__version__ = '0.0.38'
5+
__version__ = '0.0.39'

pyqt_code_editor/mixins/base.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ def send_worker_request(self, **data):
7474
so we can handle multiple concurrent requests.
7575
"""
7676
result_queue, pid = manager.send_worker_request(**data)
77+
if result_queue is None:
78+
logger.info('Request ignored')
79+
return
7780
self._active_requests[pid] = result_queue
7881
logger.info(f"Sent request to worker {pid}, now tracking {len(self._active_requests)} active requests.")
7982

pyqt_code_editor/worker/manager.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
STOP_UNUSED_INTERVAL = 10
88
_last_stop_unused_time = 0
99
_workers = {} # pid -> {"process", "request_queue", "result_queue", "is_free"}
10+
suspended = False
1011

1112

1213
def send_worker_request(**data) -> (Queue, int):
@@ -16,7 +17,11 @@ def send_worker_request(**data) -> (Queue, int):
1617
1718
The caller can poll the result_queue for responses, and once done,
1819
call mark_worker_as_free(pid) to release this worker for future use.
20+
21+
If workers are suspended, return (None, None).
1922
"""
23+
if suspended:
24+
return None, None
2025
# 1. Look for an existing free worker
2126
for pid, w in list(_workers.items()):
2227
if w["is_free"] and w["process"].is_alive():
@@ -100,7 +105,7 @@ def stop_all_workers():
100105
"""
101106
Cleanly shut down all worker processes.
102107
"""
103-
logger.info("Stopping all worker processes...")
108+
logger.info(f"Stopping {len(_workers)} worker processes...")
104109
for pid, w in list(_workers.items()):
105110
if w["process"].is_alive():
106111
logger.info(f"Stopping worker {pid}.")
@@ -116,4 +121,23 @@ def update_setting(name, value):
116121
for pid, w in _workers.items():
117122
if w["process"].is_alive():
118123
w["request_queue"].put(settings_action)
124+
125+
126+
def suspend():
127+
"""Stops all worker processes and ignores all requests until resume() is
128+
called.
129+
"""
130+
global suspended
131+
suspended = True
132+
logger.info("Suspending worker processes...")
133+
stop_all_workers()
134+
135+
136+
def resume():
137+
"""Resumes accepting requests."""
138+
global suspended
139+
suspended = False
140+
logger.info("Resuming worker processes...")
141+
142+
119143
settings.setting_changed.connect(update_setting)

0 commit comments

Comments
 (0)