Skip to content

Commit 564ec1b

Browse files
author
Joel Collins
committed
Fix #152
1 parent abc732c commit 564ec1b

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

src/labthings/actions/thread.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
import uuid
77

88
from flask import request, copy_current_request_context, has_request_context
9+
from werkzeug.exceptions import BadRequest
910

1011
from ..utilities import TimeoutTracker
11-
from ..deque import Deque
12+
from ..deque import LockableDeque
1213

1314
_LOG = logging.getLogger(__name__)
1415

@@ -89,7 +90,7 @@ def __init__(
8990
# Public state properties
9091
self.progress: int = None # Percent progress of the task
9192
self.data = {} # Dictionary of custom data added during the task
92-
self.log = Deque(
93+
self._log = LockableDeque(
9394
None, log_len
9495
) # The log will hold dictionary objects with log information
9596

@@ -112,6 +113,11 @@ def output(self):
112113
"""
113114
return self._return_value
114115

116+
@property
117+
def log(self):
118+
with self._log as logdeque:
119+
return list(logdeque)
120+
115121
@property
116122
def status(self):
117123
"""
@@ -195,7 +201,7 @@ def wrapped(*args, **kwargs):
195201
nonlocal self
196202

197203
# Capture just this thread's log messages
198-
handler = ThreadLogHandler(thread=self, dest=self.log)
204+
handler = ThreadLogHandler(self, self._log)
199205
logging.getLogger().addHandler(handler)
200206

201207
self._status = "running"
@@ -336,7 +342,11 @@ def stop(self, timeout=None, exception=ActionKilledException):
336342

337343
class ThreadLogHandler(logging.Handler):
338344
def __init__(
339-
self, thread=None, dest=None, level=logging.INFO, default_log_len: int = 100
345+
self,
346+
thread: ActionThread,
347+
dest: LockableDeque,
348+
level=logging.INFO,
349+
default_log_len: int = 100,
340350
):
341351
"""Set up a log handler that appends messages to a list.
342352
@@ -358,7 +368,7 @@ def __init__(
358368
logging.Handler.__init__(self)
359369
self.setLevel(level)
360370
self.thread = thread
361-
self.dest = dest if dest is not None else Deque(None, default_log_len)
371+
self.dest = dest
362372
self.addFilter(self.check_thread)
363373

364374
def check_thread(self, record):
@@ -379,9 +389,6 @@ def emit(self, record):
379389
:param record:
380390
381391
"""
382-
self.dest.append(record)
392+
with self.dest as logdeque:
393+
logdeque.append(record)
383394
# TODO: think about whether any of the keys are security flaws
384-
385-
386-
# Backwards compatibility
387-
ActionThread = ActionThread

src/labthings/deque.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from collections import deque as _deque
2+
from threading import Lock
23

34

45
class Deque(_deque):
@@ -8,11 +9,25 @@ def __init__(self, iterable=None, maxlen=100):
89
_deque.__init__(self, iterable or [], maxlen)
910

1011

12+
class LockableDeque(Deque):
13+
def __init__(self, iterable=None, maxlen=100, timeout=-1):
14+
Deque.__init__(self, iterable, maxlen)
15+
self.lock = Lock()
16+
self.timeout = timeout
17+
18+
def __enter__(self):
19+
self.lock.acquire(blocking=True, timeout=self.timeout)
20+
return self
21+
22+
def __exit__(self, *args):
23+
self.lock.release()
24+
25+
1126
def resize_deque(iterable: _deque, newsize: int):
1227
"""
1328
14-
:param iterable: _deque:
15-
:param newsize: int:
29+
:param iterable: _deque:
30+
:param newsize: int:
1631
1732
"""
1833
return Deque(iterable, newsize)

0 commit comments

Comments
 (0)