Synchronizations#
Instantiating and operating features in multirunnable is classified to 2 modules. Modules in subpackage multirunnable.adapter be a factories which has responsibility of generating target instance of running strategy. And for multirunnable.api, its responsibility for operating.
Factory Modules#
module multirunnable.factory
It focuses on generating instance but doesn’t care about how to operating it. It’s an factory to generate the target instance, so it would returns different instance with different RunningMode. Below are the mapping table about which instance it generates with different RunningMode:
Factory |
Running Mode |
Truly Instance |
---|---|---|
Lock |
Parallel |
multiprocessing.Lock |
Concurrent |
threading.Lock |
|
Coroutine (Green Thread) |
gevent.threading.Lock |
|
Coroutine (Asynchronous) |
asyncio.locks.Lock |
|
RLock |
Parallel |
multiprocessing.RLock |
Concurrent |
threading.RLock |
|
Coroutine (Green Thread) |
gevent.lock.RLock |
|
Coroutine (Asynchronous) |
asyncio.locks.RLock |
|
Semaphore |
Parallel |
multiprocessing.Semaphore |
Concurrent |
threading.Semaphore |
|
Coroutine (Green Thread) |
gevent.lock.Semaphore |
|
Coroutine (Asynchronous) |
asyncio.locks.Semaphore |
|
Bounded Semaphore |
Parallel |
multiprocessing.BoundedSemaphore |
Concurrent |
threading.BoundedSemaphore |
|
Coroutine (Green Thread) |
gevent.lock.BoundedSemaphore |
|
Coroutine (Asynchronous) |
asyncio.locks.BoundedSemaphore |
|
Event |
Parallel |
multiprocessing.Event |
Concurrent |
threading.Event |
|
Coroutine (Green Thread) |
gevent.event.Event |
|
Coroutine (Asynchronous) |
asyncio.Event |
|
Condition |
Parallel |
multiprocessing.Condition |
Concurrent |
threading.Condition |
|
Coroutine (Green Thread) |
(Not Support) |
|
Coroutine (Asynchronous) |
asyncio.Condition |
Lock Modules#
module multirunnable.factory.lock
The module doesn’t only response of Lock. All synchronization features which could limit the performance but DOES NOT communicate with each others like Lock, Semaphore, etc.
It was named as LockAdapter before version 0.17.0. Same as classes in it (Lock, Semaphore, etc).
LockFactory#
class multirunnable.factory.lock.LockFactory
The implement about generating Lock instance.
get_instance(**kwargs)
Instantiate the Lock instance by FeatureMode which be assigned by RunningMode.
It could pass arguments if its instantiating needs.
- Parameters:
kwargs (Dict) : A argument of the Lock object.
- Return:
An instance of Lock.
globalize_instance(obj: MRLock)
Assign the object as a global variable.
- Parameters:
obj (multirunnsble.types.MRLock) : An instance of Lock.
- Return:
None.
RLockFactory#
class multirunnable.factory.lock.RLockFactoryFactory
It’s same as multirunnable.factory.lock.LockFactory but for RLock.
SemaphoreFactory#
class multirunnable.factory.lock.SemaphoreFactoryFactory
It’s same as multirunnable.factory.lock.LockFactory but for Semaphore.
BoundedSemaphoreFactory#
class multirunnable.factory.lock.BoundedSemaphoreFactory
It’s same as multirunnable.factory.lock.LockFactory but for BoundedSemaphore.
Communication Modules#
module multirunnable.factory.communication
All synchronization features which could limit the performance AND could communicate with each others like Event, Condition.
It will be modified to naming as CommunicationFactory in version 0.17.0. Same as classes in it (Event, Condition).
EventFactory#
class multirunnable.factory.communication.EventFactory
It’s same as multirunnable.factory.lock.LockFactory but for Event.
ConditionFactory#
class multirunnable.factory.communication.ConditionFactory
It’s same as multirunnable.factory.lock.LockFactory but for Condition.
API Modules#
module multirunnable.api
All operators of MultiRunnable is the responsibility of this subpackage. Including synchronizations like Lock, Semaphore or something like this and retry mechanism. For synchronization features, multirunnable.factory focus on generating instance, multirunnable.api focus on operating something with the instance.
Operator Modules#
module multirunnable.api.operator
This module responses of some operators of synchronization-features.
LockOperator#
class multirunnable.api.operator.LockOperator()
Operators of feature Lock. This feature do the same thing as the truly instance we call. Please refer to below to get more details:
_get_feature_instance()
Return a Lock instance which be get from global variable be saved in module multirunnable.api.manage. Therefore, this return value would be the same as multirunnable.api.manage.Running_Lock.
- Return:
An instance of Lock.
acquire()
Acquire a lock to limit performance so that it’s force to run ONLY ONE runnable object at the same time.
- Return:
None.
release()
Release the lock to let other runnable objects could acquire it.
- Return:
None.
RLockOperator#
class multirunnable.api.operator.RLockOperator()
Operators of feature RLock. This feature do the same thing as the truly instance we call. Please refer to below to get more details:
Coroutine - Asynchronous does NOT support this feature
_get_feature_instance()
Same as LockOperator._get_feature_instance. It returns value would be the same as multirunnable.api.manage.Running_RLock.
- Return:
An instance of RLock.
acquire(blocking=True, timeout=None)
Acquire a lock to limit performance so that it’s force to run ONLY ONE runnable object at the same time. Different is it could acquire lock again and again in runtime. But remember, how many it acquires, how many it needs to release.
- Parameters:
blocking (bool) : It would block until RLock resource has been released if blocking is True, or it doesn’t.
timeout (int) : The most number of seconds it would block.
- Return:
None.
release()
Same as Lock.acquire. Difference is program would keep run util last one release be called.
- Return:
None.
SemaphoreOperator#
class multirunnable.api.operator.SemaphoreOperator()
Operators of feature Semaphore. This feature do the same thing as the truly instance we call. Please refer to below to get more details:
_get_feature_instance()
Same as LockOperator._get_feature_instance. It returns value would be the same as multirunnable.api.manage.Running_Semaphore.
- Return:
An instance of Semaphore.
acquire(blocking: bool = True, timeout: int = None)
It’s mostly same as Lock. It force to only one runnable object could run at the same time with Lock. For Semaphore, it permits multiple runnable objects to run simultaneously and the permitted amount is the value of option value of multirunnable.factory.lock.Semaphore.
- Parameters:
blocking (bool) : It would block until Semaphore resource has been released if blocking is True, or it doesn’t.
timeout (int) : The most number of seconds it would block.
- Return:
None.
release(n: int = 1)
The logic is same as Lock.release but be used for Semaphore.
- Parameters:
n (int) : How many semaphore it should release.
- Return:
None.
BoundedSemaphoreOperator#
class multirunnable.api.operator.BoundedSemaphoreOperator()
Operators of feature Bounded Semaphore. This feature do the same thing as the truly instance we call. Please refer to below to get more details:
_get_feature_instance()
Same as LockOperator._get_feature_instance. It returns value would be the same as multirunnable.api.manage.Running_Bounded_Semaphore.
- Return:
An instance of BoundedSemaphore.
acquire(blocking: bool = True, timeout: int = None)
This implement is same as SemaphoreOperator.acquire.
- Parameters:
blocking (bool) : It would block until BoundedSemaphore resource has been released if blocking is True, or it doesn’t.
timeout (int) : The most number of seconds it would block.
- Return:
None.
release(n: int = 1)
It’s also same as SemaphoreOperator.acquire but the only one different is it has limitation (the argument n) in every time it releases.
- Parameters:
n (int) : How many semaphore it should release.
- Return:
None.
EventOperator#
class multirunnable.api.operator.EventOperator()
Operators of feature Event. This feature do the same thing as the truly instance we call. Please refer to below to get more details:
_event_instance()
Return the Event instance.
- Return:
An instance of Event.
_get_feature_instance()
Same as LockOperator._get_feature_instance. It returns value would be the same as multirunnable.api.manage.Running_Event.
- Return:
An instance of Event.
set()
Set a flag to tell other runnable objects could run.
- Return:
None.
is_set()
Return bool type value. It’s True if flag be set or it’s False.
- Return:
A boolean value.
wait(timeout: int = None)
Let runnable object waits util flag be set by the method set.
- Parameters:
timeout (int) : The most number of seconds it would block.
- Return:
A boolean value.
clear()
Clear all flags.
- Return:
None.
ConditionOperator#
class multirunnable.api.operator.ConditionOperator()
Operators of feature Condition. This feature do the same thing as the truly instance we call. Please refer to below to get more details:
Coroutine - Green Thread does NOT support this feature
_get_feature_instance()
Same as LockOperator._get_feature_instance. It returns value would be the same as multirunnable.api.manage.Running_Condition.
- Return:
An instance of Condition.
acquire(blocking: bool = True, timeout: int = None)
Acquire a lock to limit performance. It’s same as LockOperator.acquire.
- Parameters:
blocking (bool) : It would block until Condition resource has been released if blocking is True, or it doesn’t.
timeout (int) : The most number of seconds it would block.
- Return:
A boolean value.
release()
Same as LockOperator.release.
- Return:
None.
wait(timeout: int = None)
Wait util notified or util a timeout occurs.
- Parameters:
timeout (int) : The most number of seconds it would block.
- Return:
None.
wait_for(predicate, timeout: int = None)
Wait until a condition evaluates to true.
- Parameters:
predicate (Callable) : This should be a function which return value is boolean type. It would keep running if it satisfy predicate.
timeout (int) : The most number of seconds it would block.
- Return:
A boolean value.
notify(n: int = 1)
By default, wait up one runnable object on this condition.
- Parameters:
n (int) : How many runnable objects it should wake up to run on the condition.
- Return:
None.
notify_all()
Wait up all runnable objects on this condition.
- Return:
None.
Adapter Modules#
module multirunnable.adapter
Subpackage Adapter for clear and convenient in usage. It combines the features of both 2 subpackages Factory and API.
About synchronization usage in multirunnable, it divides to 2 sections: Factory and API. The former generates instance with RunningMode; the latter provides all operators of the instance. However, it doesn’t be clear or be convenient to use sometimes. It also needs to care 2 different objects when you’re using.
Let’s demonstrate some different usage between Adapter and Factory with API:
Usage with Adapter:
from multirunnable import RunningMode, SimpleExecutor, sleep
from multirunnable.adapter import Lock
_lock = Lock(mode=RunningMode.Parallel, init=True) # Use Lock feature with Adapter object
def lock_function():
_lock.acquire()
print("This is ExampleTargetFunction.target_function.")
sleep(3)
_lock.release()
executor = SimpleExecutor(mode=RunningMode.Parallel, executors=5)
executor.run(function=lock_function)
Usage with Factory and API:
from multirunnable import RunningMode, SimpleExecutor, sleep
from multirunnable.api import LockOperator
from multirunnable.factory import LockFactory
def lock_function():
_lock_opt = LockOperator() # Use Lock feature with Operator object
_lock_opt.acquire()
print("This is ExampleTargetFunction.target_function.")
sleep(3)
_lock_opt.release()
executor = SimpleExecutor(mode=RunningMode.Parallel, executors=5)
lock = LockFactory() # Use Lock feature with Factory object
executor.run(function=lock_function, features=lock)
About second one of above demonstrations, it generates instance by object LockFactory and operates the Lock feature with object LockOperator. It must to care about what thing to do and when to call it. But it doesn’t if it uses with object Lock.
Objects in it has all the attributes of Factory and API. And the attribute’s name also the same between them. So what attributes Factory or API they have, what attributes Adapter it has.
This is new in version 0.17.0.
The modules of subpackage Adapter:
module: multirunnable.adapter.lock
- Lock
- RLock
- Semaphore
- BoundedSemaphore
- module: multirunnable.adapter.communication
- Event
- Condition