[config] Implements "Exclusive" context processor allowing to ask for an exclusive usage of a service while in a transformation.
This commit is contained in:
@ -1,5 +1,3 @@
|
||||
import warnings
|
||||
|
||||
from bonobo.structs import Bag, Graph, Token
|
||||
from bonobo.nodes import CsvReader, CsvWriter, FileReader, FileWriter, Filter, JsonReader, JsonWriter, Limit, \
|
||||
PrettyPrint, Tee, count, identity, noop, pprint
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
from bonobo.config.configurables import Configurable
|
||||
from bonobo.config.options import Option, Method
|
||||
from bonobo.config.processors import ContextProcessor
|
||||
from bonobo.config.services import Container, Service
|
||||
from bonobo.config.services import Container, Service, Exclusive
|
||||
|
||||
# bonobo.config public programming interface
|
||||
__all__ = [
|
||||
'Configurable',
|
||||
'Container',
|
||||
'ContextProcessor',
|
||||
'Option',
|
||||
'Exclusive',
|
||||
'Method',
|
||||
'Option',
|
||||
'Service',
|
||||
]
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import re
|
||||
import threading
|
||||
import types
|
||||
from contextlib import ContextDecorator
|
||||
|
||||
from bonobo.config.options import Option
|
||||
from bonobo.errors import MissingServiceImplementationError
|
||||
@ -87,3 +89,40 @@ class Container(dict):
|
||||
if isinstance(value, types.LambdaType):
|
||||
value = value(self)
|
||||
return value
|
||||
|
||||
|
||||
class Exclusive(ContextDecorator):
|
||||
"""
|
||||
Decorator and context manager used to require exclusive usage of an object, most probably a service. It's usefull
|
||||
for example if call order matters on a service implementation (think of an http api that requires a nonce or version
|
||||
parameter ...).
|
||||
|
||||
Usage:
|
||||
|
||||
>>> def handler(some_service):
|
||||
... with Exclusive(some_service):
|
||||
... some_service.call_1()
|
||||
... some_service.call_2()
|
||||
... some_service.call_3()
|
||||
|
||||
This will ensure that nobody else is using the same service while in the "with" block, using a lock primitive to
|
||||
ensure that.
|
||||
|
||||
"""
|
||||
_locks = {}
|
||||
|
||||
def __init__(self, wrapped):
|
||||
self._wrapped = wrapped
|
||||
|
||||
def get_lock(self):
|
||||
_id = id(self._wrapped)
|
||||
if not _id in Exclusive._locks:
|
||||
Exclusive._locks[_id] = threading.RLock()
|
||||
return Exclusive._locks[_id]
|
||||
|
||||
def __enter__(self):
|
||||
self.get_lock().acquire()
|
||||
return self._wrapped
|
||||
|
||||
def __exit__(self, *exc):
|
||||
self.get_lock().release()
|
||||
|
||||
Reference in New Issue
Block a user