Skip to main content

Resource management classes and functions.

Latest release 20220918:

  • MultiOpenMixin.close: report caller of underflow close.
  • RunState: new optional handle_signal parameter to override the default method.
  • New openif() context manager to open/close an object if it has a .open method.
  • MultiOpenMixin.startup_shutdown: be silent for missing (obsolete) .startup, require .shutdown if .startup.

Class ClosedError(builtins.Exception, builtins.BaseException)

Exception for operations invalid when something is closed.

Class MultiOpen(MultiOpenMixin, cs.context.ContextManagerMixin)

Context manager class that manages a single open/close object using a MultiOpenMixin.

Method MultiOpen.__init__(self, openable, finalise_later=False): Initialise: save the openable and call the MultiOpenMixin initialiser.

Class MultiOpenMixin(cs.context.ContextManagerMixin)

A multithread safe mixin to count open and close calls, and to call .startup on the first .open and to call .shutdown on the last .close.

If used as a context manager this mixin calls open()/close() from __enter__() and __exit__().

It is recommended subclass implementations do as little as possible during __init__, and do almost all setup during startup so that the class may perform multiple startup/shutdown iterations.

Classes using this mixin need to:

  • either define a context manager method .startup_shutdown which does the startup actions before yeilding and then does the shutdown actions
  • or define separate .startup and .shutdown methods.

Example:

class DatabaseThing(MultiOpenMixin):
    @contextmanager
    def startup_shutdown(self):
        self._db = open_the_database()
        yield
        self._db.close()
...
with DatabaseThing(...) as db_thing:
    ... use db_thing ...

Why not a plain context manager? Because in multithreaded code one wants to keep the instance "open" while any thread is still using it. This mixin lets threads use an instance in overlapping fashion:

db_thing = DatabaseThing(...)
with db_thing:
    ... kick off threads with access to the db ...
...
thread 1:
with db_thing:
   ... use db_thing ...
thread 2:
with db_thing:
   ... use db_thing ...

TODO:

  • subopens: if true (default false) then .open will return a proxy object with its own .closed attribute set by the proxy's .close.

Function not_closed(func)

Decorator to wrap methods of objects with a .closed property which should raise when self.closed.

Function openif(obj)

Context manager to open obj if it has a .open method and also to close it via its .close method. This yields obj.open() if defined, or obj otherwise.

Class Pool

A generic pool of objects on the premise that reuse is cheaper than recreation.

All the pool objects must be suitable for use, so the new_object callable will typically be a closure. For example, here is the init for a per-thread AWS Bucket using a distinct Session:

def __init__(self, bucket_name):
    Pool.__init__(self, lambda: boto3.session.Session().resource('s3').Bucket(bucket_name)

Method Pool.__init__(self, new_object, max_size=None, lock=None): Initialise the Pool with creator new_object and maximum size max_size.

Parameters:

  • new_object is a callable which returns a new object for the Pool.
  • max_size: The maximum size of the pool of available objects saved for reuse. If omitted or None, defaults to 4. If 0, no upper limit is applied.
  • lock: optional shared Lock; if omitted or None a new Lock is allocated

Class RunState(cs.context.ContextManagerMixin)

A class to track a running task whose cancellation may be requested.

Its purpose is twofold, to provide easily queriable state around tasks which can start and stop, and to provide control methods to pronounce that a task has started (.start), should stop (.cancel) and has stopped (.stop).

A RunState can be used as a context manager, with the enter and exit methods calling .start and .stop respectively. Note that if the suite raises an exception then the exit method also calls .cancel before the call to .stop.

Monitor or daemon processes can poll the RunState to see when they should terminate, and may also manage the overall state easily using a context manager. Example:

def monitor(self):
    with self.runstate:
        while not self.runstate.cancelled:
            ... main loop body here ...

A RunState has three main methods:

  • .start(): set .running and clear .cancelled
  • .cancel(): set .cancelled
  • .stop(): clear .running

A RunState has the following properties:

  • cancelled: true if .cancel has been called.
  • running: true if the task is running. Further, assigning a true value to it sets .start_time to now. Assigning a false value to it sets .stop_time to now.
  • start_time: the time .running was last set to true.
  • stop_time: the time .running was last set to false.
  • run_time: max(0,.stop_time-.start_time)
  • stopped: true if the task is not running.
  • stopping: true if the task is running but has been cancelled.
  • notify_start: a set of callables called with the RunState instance to be called whenever .running becomes true.
  • notify_end: a set of callables called with the RunState instance to be called whenever .running becomes false.
  • notify_cancel: a set of callables called with the RunState instance to be called whenever .cancel is called.

Class RunStateMixin

Mixin to provide convenient access to a RunState.

Provides: .runstate, .cancelled, .running, .stopping, .stopped.

Method RunStateMixin.__init__(self, runstate=None): Initialise the RunStateMixin; sets the .runstate attribute.

Parameters:

  • runstate: optional RunState instance or name. If a str, a new RunState with that name is allocated.

Release Log

Release 20220918:

  • MultiOpenMixin.close: report caller of underflow close.
  • RunState: new optional handle_signal parameter to override the default method.
  • New openif() context manager to open/close an object if it has a .open method.
  • MultiOpenMixin.startup_shutdown: be silent for missing (obsolete) .startup, require .shutdown if .startup.

Release 20220429: RunState: new catch_signal(sig,verbose=False) context manager method to cancel the RunState on receipt of a signal.

Release 20211208:

  • MultiOpenMixin.startup_shutdown: since this is the fallback for obsolete uses of MultiOpenMixin, warn if there is no .startup/.shutdown method.
  • MultiOpenMixin.startup_shutdown: fix up shutdown logic, was not using a finally clause.
  • MultiOpenMixin: use ContextManagerMixin enter_exit generator method instead of enter and exit.

Release 20210906: MultiOpenMixin: make startup and shutdown optional.

Release 20210731: RunState: tune the sanity checks around whether the state is "running".

Release 20210420: MultiOpenMixin: run startup/shutdown entirely via the new default method @contextmanager(startup_shutdown), paving the way for subclasses to just define their own startup_shutdown context manager methods instead of distinct startup/shutdown methods.

Release 20201025: MultiOpenMixin.__mo_getstate: dereference self.dict because using AttributeError was pulling a state object from another instance, utterly weird.

Release 20200718: MultiOpenMixin: as a hack to avoid having an init, move state into an on demand object accesses by a private method.

Release 20200521: Sweeping removal of cs.obj.O, universally supplanted by types.SimpleNamespace.

Release 20190812:

  • MultiOpenMixin: no longer subclass cs.obj.O.
  • MultiOpenMixin: remove lock param support, the mixin has its own lock.
  • MultiOpen: drop lock param support, no longer used by MultiOpenMixin.
  • MultiOpenMixin: do finalise inside the lock for the same reason as shutdown (competition with open/startup).
  • MultiOpenMixin.close: new unopened_ok=False parameter intended for callback closes which might fire even if the initial open does not occur.

Release 20190617: RunState.exit: if an exception was raised call .canel() before calling .stop().

Release 20190103:

  • Bugfixes for context managers.
  • MultiOpenMixin fixes and changes.
  • RunState improvements.

Release 20171024:

  • bugfix MultiOpenMixin finalise logic and other small logic fixes and checs
  • new class RunState for tracking or controlling a running task

Release 20160828: Use "install_requires" instead of "requires" in DISTINFO.

Release 20160827:

  • BREAKING CHANGE: rename NestingOpenCloseMixin to MultiOpenMixin.
  • New Pool class for generic object reuse.
  • Assorted minor improvements.

Release 20150115: First PyPI release.

Release files for cs-resources 20220918

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cs-resources 20220918
File Size Uploaded
cs.resources-20220918.tar.gz 13.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cs-resources 20220918
File Interpreter ABI Platform
cs.resources-20220918-py3-none-any.whl Python 3 none any Details

Total release size: 25.0 kB

Release files / cs.resources-20220918.tar.gz

Download URL cs.resources-20220918.tar.gz
Size 13.3 kB
Tags Source
SHA-256 checksum
How to use checksums
e9e2497799bea5b8d0a06efb18b0d6653b593622b14c871a98c9b955ffefe598
BLAKE2b-256 checksum
How to use checksums
e4db3639431e44ee694fdebb40deaec41b1b57b8dec5dda15d51f7e069f5b478
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / cs.resources-20220918-py3-none-any.whl

Download URL cs.resources-20220918-py3-none-any.whl
Size 11.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ad6b1d52962a521234f61f1dd6e45ddd894c06e2594356b1f2f09d0a4f670b95
BLAKE2b-256 checksum
How to use checksums
1b64594294891981836ede714f67ce14a0565ac4380cb7f8ef9cac850c5416ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release history Release notifications | RSS feed

This release

20220918 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page