Skip to content
Snippets Groups Projects
Commit 2594ffbb authored by Piotr Maślanka's avatar Piotr Maślanka
Browse files

add SingleStartThread

parent 7f5cc569
No related branches found
No related tags found
No related merge requests found
......@@ -2,3 +2,4 @@
* `OmniHashableMixin` will be faster now
* `OmniHashableMixin` will now allow single strings to be it's argument
* added `SingleStartThread`
......@@ -32,6 +32,12 @@ It means that if it's hanging on I/O, for example, it won't be affected.
.. autoclass:: satella.coding.concurrent.TerminableThread
:members:
SingleStartThread
=================
.. autoclass:: satella.coding.concurrent.SingleStartThread
:members:
Monitor
=======
......
__version__ = '2.9.6_a5'
__version__ = '2.9.6_a6'
......@@ -3,8 +3,8 @@ from .callablegroup import CallableGroup, CallNoOftenThan
from .locked_dataset import LockedDataset
from .locked_structure import LockedStructure
from .monitor import MonitorList, Monitor, MonitorDict, RMonitor
from .thread import TerminableThread, Condition
from .thread import TerminableThread, Condition, SingleStartThread
__all__ = ['LockedDataset', 'Monitor', 'RMonitor', 'CallableGroup', 'TerminableThread',
'MonitorDict', 'MonitorList', 'Condition', 'LockedStructure', 'AtomicNumber',
'CallNoOftenThan']
'CallNoOftenThan', 'SingleStartThread']
......@@ -59,6 +59,29 @@ class Condition(PythonCondition):
super().notify(n=n)
class SingleStartThread(threading.Thread):
"""
A thread that keeps track of whether it's .start() method was called, and does nothing
if it's called second or so time.
"""
def __init__(self, *args, **kwargs):
self.__started = False
super().__init__(*args, **kwargs)
def start(self) -> 'SingleStartThread':
"""
No-op when called second or so time. The first time it starts the thread.
:return: self
"""
if self.__started:
return
self.__started = True
super().start()
return self
class TerminableThread(threading.Thread):
"""
Class that will execute something in a loop unless terminated. Use like:
......
......@@ -82,10 +82,10 @@ class SelfCleaningDefaultDict(Monitor, tp.MutableMapping[K, V], Cleanupable):
return len(self.data)
def __init__(self, default_factory: tp.Callable[[], V], *args, **kwargs):
super().__init__() # initialize the inner Monitor
self.data = dict(*args, **kwargs)
self.default_factory = default_factory
self.default_value = default_factory()
ExpiringEntryDictThread().add_dict(self)
def __iter__(self) -> tp.Iterator[K]:
......@@ -144,6 +144,7 @@ class ExpiringEntryDict(Monitor, tp.MutableMapping[K, V], Cleanupable):
def __init__(self, expiration_timeout: float, *args,
time_getter: tp.Callable[[], float] = time.monotonic,
external_cleanup: bool = False, **kwargs):
super().__init__() # initialize the inner Monitor
self.data = dict()
self.expire_on = {}
self.time_getter = time_getter
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment