ez-a-sync 0.22.13__py3-none-any.whl → 0.22.15__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ez-a-sync might be problematic. Click here for more details.
- a_sync/ENVIRONMENT_VARIABLES.py +4 -3
- a_sync/__init__.py +30 -12
- a_sync/_smart.py +132 -28
- a_sync/_typing.py +56 -12
- a_sync/a_sync/__init__.py +35 -10
- a_sync/a_sync/_descriptor.py +74 -26
- a_sync/a_sync/_flags.py +14 -6
- a_sync/a_sync/_helpers.py +8 -7
- a_sync/a_sync/_kwargs.py +3 -2
- a_sync/a_sync/_meta.py +120 -28
- a_sync/a_sync/abstract.py +102 -28
- a_sync/a_sync/base.py +34 -16
- a_sync/a_sync/config.py +47 -13
- a_sync/a_sync/decorator.py +239 -117
- a_sync/a_sync/function.py +416 -146
- a_sync/a_sync/method.py +197 -59
- a_sync/a_sync/modifiers/__init__.py +47 -5
- a_sync/a_sync/modifiers/cache/__init__.py +46 -17
- a_sync/a_sync/modifiers/cache/memory.py +86 -20
- a_sync/a_sync/modifiers/limiter.py +52 -22
- a_sync/a_sync/modifiers/manager.py +98 -16
- a_sync/a_sync/modifiers/semaphores.py +48 -15
- a_sync/a_sync/property.py +383 -82
- a_sync/a_sync/singleton.py +1 -0
- a_sync/aliases.py +0 -1
- a_sync/asyncio/__init__.py +4 -1
- a_sync/asyncio/as_completed.py +177 -49
- a_sync/asyncio/create_task.py +31 -17
- a_sync/asyncio/gather.py +72 -52
- a_sync/asyncio/utils.py +3 -3
- a_sync/exceptions.py +78 -23
- a_sync/executor.py +120 -71
- a_sync/future.py +575 -158
- a_sync/iter.py +110 -50
- a_sync/primitives/__init__.py +14 -2
- a_sync/primitives/_debug.py +13 -13
- a_sync/primitives/_loggable.py +5 -4
- a_sync/primitives/locks/__init__.py +5 -2
- a_sync/primitives/locks/counter.py +38 -36
- a_sync/primitives/locks/event.py +21 -7
- a_sync/primitives/locks/prio_semaphore.py +182 -62
- a_sync/primitives/locks/semaphore.py +78 -77
- a_sync/primitives/queue.py +560 -58
- a_sync/sphinx/__init__.py +0 -1
- a_sync/sphinx/ext.py +160 -50
- a_sync/task.py +262 -97
- a_sync/utils/__init__.py +12 -6
- a_sync/utils/iterators.py +127 -43
- {ez_a_sync-0.22.13.dist-info → ez_a_sync-0.22.15.dist-info}/METADATA +1 -1
- ez_a_sync-0.22.15.dist-info/RECORD +74 -0
- {ez_a_sync-0.22.13.dist-info → ez_a_sync-0.22.15.dist-info}/WHEEL +1 -1
- tests/conftest.py +1 -2
- tests/executor.py +112 -9
- tests/fixtures.py +61 -32
- tests/test_abstract.py +7 -4
- tests/test_as_completed.py +54 -21
- tests/test_base.py +66 -17
- tests/test_cache.py +31 -15
- tests/test_decorator.py +54 -28
- tests/test_executor.py +8 -13
- tests/test_future.py +45 -8
- tests/test_gather.py +8 -2
- tests/test_helpers.py +2 -0
- tests/test_iter.py +55 -13
- tests/test_limiter.py +5 -3
- tests/test_meta.py +23 -9
- tests/test_modified.py +4 -1
- tests/test_semaphore.py +15 -8
- tests/test_singleton.py +15 -10
- tests/test_task.py +126 -28
- ez_a_sync-0.22.13.dist-info/RECORD +0 -74
- {ez_a_sync-0.22.13.dist-info → ez_a_sync-0.22.15.dist-info}/LICENSE.txt +0 -0
- {ez_a_sync-0.22.13.dist-info → ez_a_sync-0.22.15.dist-info}/top_level.txt +0 -0
a_sync/a_sync/abstract.py
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides an abstract base class for defining asynchronous and synchronous behavior.
|
|
3
|
+
|
|
4
|
+
The ASyncABC class uses the ASyncMeta metaclass to automatically wrap its methods
|
|
5
|
+
with asynchronous or synchronous behavior based on flags. Subclasses must
|
|
6
|
+
implement the abstract methods to define the flag name, flag value, and
|
|
7
|
+
default mode for asynchronous or synchronous execution.
|
|
8
|
+
|
|
9
|
+
Note: It is recommended to use ASyncGenericBase for most use cases. This class
|
|
10
|
+
is intended for more custom implementations if necessary.
|
|
11
|
+
"""
|
|
1
12
|
|
|
2
13
|
import abc
|
|
3
14
|
import functools
|
|
@@ -11,70 +22,133 @@ from a_sync.exceptions import NoFlagsFound
|
|
|
11
22
|
|
|
12
23
|
logger = logging.getLogger(__name__)
|
|
13
24
|
|
|
25
|
+
|
|
14
26
|
class ASyncABC(metaclass=ASyncMeta):
|
|
27
|
+
"""Abstract Base Class for defining asynchronous and synchronous behavior.
|
|
28
|
+
|
|
29
|
+
This class uses the ASyncMeta metaclass to automatically wrap its methods
|
|
30
|
+
with asynchronous or synchronous behavior based on flags. Subclasses must
|
|
31
|
+
implement the abstract methods to define the flag name, flag value, and
|
|
32
|
+
default mode for asynchronous or synchronous execution.
|
|
33
|
+
"""
|
|
15
34
|
|
|
16
35
|
##################################
|
|
17
36
|
# Concrete Methods (overridable) #
|
|
18
37
|
##################################
|
|
19
38
|
|
|
20
39
|
def __a_sync_should_await__(self, kwargs: dict) -> bool:
|
|
21
|
-
"""
|
|
40
|
+
"""Determines if methods should be called asynchronously.
|
|
41
|
+
|
|
42
|
+
This method first checks the provided keyword arguments for flags
|
|
43
|
+
indicating the desired execution mode. If no flags are found, it
|
|
44
|
+
defaults to the instance's asynchronous flag.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
kwargs: A dictionary of keyword arguments to check for flags.
|
|
48
|
+
"""
|
|
22
49
|
try:
|
|
23
|
-
# Defer to kwargs always
|
|
24
50
|
return self.__a_sync_should_await_from_kwargs__(kwargs)
|
|
25
51
|
except exceptions.NoFlagsFound:
|
|
26
|
-
# No flag found in kwargs, check for a flag attribute.
|
|
27
52
|
return self.__a_sync_instance_should_await__
|
|
28
53
|
|
|
29
54
|
@functools.cached_property
|
|
30
55
|
def __a_sync_instance_should_await__(self) -> bool:
|
|
56
|
+
"""Indicates if the instance should default to asynchronous execution.
|
|
57
|
+
|
|
58
|
+
This property can be overridden if dynamic behavior is needed. For
|
|
59
|
+
instance, to allow hot-swapping of instance modes, redefine this as a
|
|
60
|
+
non-cached property.
|
|
31
61
|
"""
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"""
|
|
37
|
-
return _flags.negate_if_necessary(self.__a_sync_flag_name__, self.__a_sync_flag_value__)
|
|
38
|
-
|
|
62
|
+
return _flags.negate_if_necessary(
|
|
63
|
+
self.__a_sync_flag_name__, self.__a_sync_flag_value__
|
|
64
|
+
)
|
|
65
|
+
|
|
39
66
|
def __a_sync_should_await_from_kwargs__(self, kwargs: dict) -> bool:
|
|
40
|
-
"""
|
|
67
|
+
"""Determines execution mode from keyword arguments.
|
|
68
|
+
|
|
69
|
+
This method can be overridden to customize how flags are extracted
|
|
70
|
+
from keyword arguments.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
kwargs: A dictionary of keyword arguments to check for flags.
|
|
74
|
+
|
|
75
|
+
Raises:
|
|
76
|
+
NoFlagsFound: If no valid flags are found in the keyword arguments.
|
|
77
|
+
"""
|
|
41
78
|
if flag := _kwargs.get_flag_name(kwargs):
|
|
42
79
|
return _kwargs.is_sync(flag, kwargs, pop_flag=True) # type: ignore [arg-type]
|
|
43
80
|
raise NoFlagsFound("kwargs", kwargs.keys())
|
|
44
|
-
|
|
81
|
+
|
|
45
82
|
@classmethod
|
|
46
83
|
def __a_sync_instance_will_be_sync__(cls, args: tuple, kwargs: dict) -> bool:
|
|
47
|
-
"""
|
|
48
|
-
|
|
84
|
+
"""Determines if a new instance will be synchronous.
|
|
85
|
+
|
|
86
|
+
This method checks the constructor's signature against provided
|
|
87
|
+
keyword arguments to determine the execution mode for the new instance.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
args: A tuple of positional arguments for the instance.
|
|
91
|
+
kwargs: A dictionary of keyword arguments for the instance.
|
|
92
|
+
"""
|
|
93
|
+
logger.debug(
|
|
94
|
+
"checking `%s.%s.__init__` signature against provided kwargs to determine a_sync mode for the new instance",
|
|
95
|
+
cls.__module__,
|
|
96
|
+
cls.__name__,
|
|
97
|
+
)
|
|
49
98
|
if flag := _kwargs.get_flag_name(kwargs):
|
|
50
99
|
sync = _kwargs.is_sync(flag, kwargs) # type: ignore [arg-type]
|
|
51
|
-
logger.debug(
|
|
100
|
+
logger.debug(
|
|
101
|
+
"kwargs indicate the new instance created with args %s %s is %ssynchronous",
|
|
102
|
+
args,
|
|
103
|
+
kwargs,
|
|
104
|
+
"a" if sync is False else "",
|
|
105
|
+
)
|
|
52
106
|
return sync
|
|
53
|
-
logger.debug(
|
|
107
|
+
logger.debug(
|
|
108
|
+
"No valid flags found in kwargs, checking class definition for defined default"
|
|
109
|
+
)
|
|
54
110
|
return cls.__a_sync_default_mode__() # type: ignore [arg-type]
|
|
55
111
|
|
|
56
112
|
######################################
|
|
57
113
|
# Concrete Methods (non-overridable) #
|
|
58
114
|
######################################
|
|
59
|
-
|
|
115
|
+
|
|
60
116
|
@property
|
|
61
117
|
def __a_sync_modifiers__(self: "ASyncABC") -> ModifierKwargs:
|
|
62
|
-
"""
|
|
118
|
+
"""Retrieves modifiers for the instance.
|
|
119
|
+
|
|
120
|
+
This method should not be overridden. It returns the modifiers
|
|
121
|
+
associated with the instance, which are used to customize behavior.
|
|
122
|
+
"""
|
|
63
123
|
return modifiers.get_modifiers_from(self)
|
|
64
124
|
|
|
65
125
|
####################
|
|
66
126
|
# Abstract Methods #
|
|
67
127
|
####################
|
|
68
128
|
|
|
69
|
-
@
|
|
129
|
+
@property
|
|
130
|
+
@abc.abstractmethod
|
|
70
131
|
def __a_sync_flag_name__(self) -> str:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
132
|
+
"""Abstract property for the flag name.
|
|
133
|
+
|
|
134
|
+
Subclasses must implement this property to return the name of the flag
|
|
135
|
+
used to determine execution mode.
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
@abc.abstractmethod
|
|
74
140
|
def __a_sync_flag_value__(self) -> bool:
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
141
|
+
"""Abstract property for the flag value.
|
|
142
|
+
|
|
143
|
+
Subclasses must implement this property to return the value of the flag
|
|
144
|
+
indicating the default execution mode.
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
@classmethod
|
|
148
|
+
@abc.abstractmethod # type: ignore [arg-type, misc]
|
|
149
|
+
def __a_sync_default_mode__(cls) -> bool: # type: ignore [empty-body]
|
|
150
|
+
"""Abstract class method for the default execution mode.
|
|
151
|
+
|
|
152
|
+
Subclasses must implement this method to return the default execution
|
|
153
|
+
mode (synchronous or asynchronous) for instances of the class.
|
|
154
|
+
"""
|
a_sync/a_sync/base.py
CHANGED
|
@@ -11,6 +11,7 @@ from a_sync.a_sync.abstract import ASyncABC
|
|
|
11
11
|
|
|
12
12
|
logger = logging.getLogger(__name__)
|
|
13
13
|
|
|
14
|
+
|
|
14
15
|
class ASyncGenericBase(ASyncABC):
|
|
15
16
|
"""
|
|
16
17
|
Base class for creating dual-function sync/async-capable classes without writing all your code twice.
|
|
@@ -35,7 +36,7 @@ class ASyncGenericBase(ASyncABC):
|
|
|
35
36
|
@a_sync
|
|
36
37
|
async def my_method(self):
|
|
37
38
|
return await another_async_operation()
|
|
38
|
-
|
|
39
|
+
|
|
39
40
|
# Synchronous usage
|
|
40
41
|
obj = MyClass(sync=True)
|
|
41
42
|
sync_result = obj.my_property
|
|
@@ -56,8 +57,10 @@ class ASyncGenericBase(ASyncABC):
|
|
|
56
57
|
def __init__(self):
|
|
57
58
|
if type(self) is ASyncGenericBase:
|
|
58
59
|
cls_name = type(self).__name__
|
|
59
|
-
raise NotImplementedError(
|
|
60
|
-
|
|
60
|
+
raise NotImplementedError(
|
|
61
|
+
f"You should not create instances of `{cls_name}` directly, you should subclass `ASyncGenericBase` instead."
|
|
62
|
+
)
|
|
63
|
+
|
|
61
64
|
@functools.cached_property
|
|
62
65
|
def __a_sync_flag_name__(self) -> str:
|
|
63
66
|
logger.debug("checking a_sync flag for %s", self)
|
|
@@ -67,8 +70,14 @@ class ASyncGenericBase(ASyncABC):
|
|
|
67
70
|
# We can't get the flag name from the __init__ signature,
|
|
68
71
|
# but maybe the implementation sets the flag somewhere else.
|
|
69
72
|
# Let's check the instance's atributes
|
|
70
|
-
logger.debug(
|
|
71
|
-
|
|
73
|
+
logger.debug(
|
|
74
|
+
"unable to find flag name using `%s.__init__` signature, checking for flag attributes defined on %s",
|
|
75
|
+
self.__class__.__name__,
|
|
76
|
+
self,
|
|
77
|
+
)
|
|
78
|
+
present_flags = [
|
|
79
|
+
flag for flag in _flags.VIABLE_FLAGS if hasattr(self, flag)
|
|
80
|
+
]
|
|
72
81
|
if not present_flags:
|
|
73
82
|
raise exceptions.NoFlagsFound(self) from None
|
|
74
83
|
if len(present_flags) > 1:
|
|
@@ -77,7 +86,7 @@ class ASyncGenericBase(ASyncABC):
|
|
|
77
86
|
if not isinstance(flag, str):
|
|
78
87
|
raise exceptions.InvalidFlag(flag)
|
|
79
88
|
return flag
|
|
80
|
-
|
|
89
|
+
|
|
81
90
|
@functools.cached_property
|
|
82
91
|
def __a_sync_flag_value__(self) -> bool:
|
|
83
92
|
"""If you wish to be able to hotswap default modes, just duplicate this def as a non-cached property."""
|
|
@@ -85,7 +94,7 @@ class ASyncGenericBase(ASyncABC):
|
|
|
85
94
|
flag_value = getattr(self, flag)
|
|
86
95
|
if not isinstance(flag_value, bool):
|
|
87
96
|
raise exceptions.InvalidFlagValue(flag, flag_value)
|
|
88
|
-
logger.debug(
|
|
97
|
+
logger.debug("`%s.%s` is currently %s", self, flag, flag_value)
|
|
89
98
|
return flag_value
|
|
90
99
|
|
|
91
100
|
@classmethod # type: ignore [misc]
|
|
@@ -97,14 +106,21 @@ class ASyncGenericBase(ASyncABC):
|
|
|
97
106
|
flag = cls.__get_a_sync_flag_name_from_class_def()
|
|
98
107
|
flag_value = cls.__get_a_sync_flag_value_from_class_def(flag)
|
|
99
108
|
sync = _flags.negate_if_necessary(flag, flag_value) # type: ignore [arg-type]
|
|
100
|
-
logger.debug(
|
|
109
|
+
logger.debug(
|
|
110
|
+
"`%s.%s` indicates default mode is %ssynchronous",
|
|
111
|
+
cls,
|
|
112
|
+
flag,
|
|
113
|
+
"a" if sync is False else "",
|
|
114
|
+
)
|
|
101
115
|
return sync
|
|
102
|
-
|
|
116
|
+
|
|
103
117
|
@classmethod
|
|
104
118
|
def __get_a_sync_flag_name_from_signature(cls) -> Optional[str]:
|
|
105
119
|
logger.debug("Searching for flags defined on %s.__init__", cls)
|
|
106
120
|
if cls.__name__ == "ASyncGenericBase":
|
|
107
|
-
logger.debug(
|
|
121
|
+
logger.debug(
|
|
122
|
+
"There are no flags defined on the base class, this is expected. Skipping."
|
|
123
|
+
)
|
|
108
124
|
return None
|
|
109
125
|
parameters = inspect.signature(cls.__init__).parameters
|
|
110
126
|
logger.debug("parameters: %s", parameters)
|
|
@@ -115,17 +131,19 @@ class ASyncGenericBase(ASyncABC):
|
|
|
115
131
|
logger.debug("Searching for flags defined on %s", cls)
|
|
116
132
|
try:
|
|
117
133
|
return cls.__parse_flag_name_from_list(cls.__dict__) # type: ignore [arg-type]
|
|
118
|
-
|
|
134
|
+
# idk why __dict__ doesn't type check as a dict
|
|
119
135
|
except exceptions.NoFlagsFound:
|
|
120
136
|
for base in cls.__bases__:
|
|
121
137
|
with suppress(exceptions.NoFlagsFound):
|
|
122
|
-
return cls.__parse_flag_name_from_list(base.__dict__) # type: ignore [arg-type]
|
|
123
|
-
|
|
138
|
+
return cls.__parse_flag_name_from_list(base.__dict__) # type: ignore [arg-type]
|
|
139
|
+
# idk why __dict__ doesn't type check as a dict
|
|
124
140
|
raise exceptions.NoFlagsFound(cls, list(cls.__dict__.keys()))
|
|
125
141
|
|
|
126
142
|
@classmethod # type: ignore [misc]
|
|
127
143
|
def __a_sync_flag_default_value_from_signature(cls) -> bool:
|
|
128
|
-
logger.debug(
|
|
144
|
+
logger.debug(
|
|
145
|
+
"checking `__init__` signature for default %s a_sync flag value", cls
|
|
146
|
+
)
|
|
129
147
|
signature = inspect.signature(cls.__init__)
|
|
130
148
|
flag = cls.__get_a_sync_flag_name_from_signature()
|
|
131
149
|
flag_value = signature.parameters[flag].default
|
|
@@ -133,7 +151,7 @@ class ASyncGenericBase(ASyncABC):
|
|
|
133
151
|
raise NotImplementedError(
|
|
134
152
|
"The implementation for 'cls' uses an arg to specify sync mode, instead of a kwarg. We are unable to proceed. I suppose we can extend the code to accept positional arg flags if necessary"
|
|
135
153
|
)
|
|
136
|
-
logger.debug(
|
|
154
|
+
logger.debug("%s defines %s, default value %s", cls, flag, flag_value)
|
|
137
155
|
return flag_value
|
|
138
156
|
|
|
139
157
|
@classmethod
|
|
@@ -154,4 +172,4 @@ class ASyncGenericBase(ASyncABC):
|
|
|
154
172
|
raise exceptions.TooManyFlags(cls, present_flags)
|
|
155
173
|
flag = present_flags[0]
|
|
156
174
|
logger.debug("found flag %s", flag)
|
|
157
|
-
return flag
|
|
175
|
+
return flag
|
a_sync/a_sync/config.py
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Configuration module for a_sync library.
|
|
2
|
+
Configuration module for the a_sync library.
|
|
3
3
|
|
|
4
4
|
This module provides configuration options and default settings for the a_sync library.
|
|
5
5
|
It includes functionality for setting up executors, defining default modifiers,
|
|
6
6
|
and handling environment variable configurations.
|
|
7
|
+
|
|
8
|
+
Environment Variables:
|
|
9
|
+
A_SYNC_EXECUTOR_TYPE: Specifies the type of executor to use. Valid values are
|
|
10
|
+
strings that start with 'p' for ProcessPoolExecutor (e.g., 'processes')
|
|
11
|
+
or 't' for ThreadPoolExecutor (e.g., 'threads'). Defaults to 'threads'.
|
|
12
|
+
A_SYNC_EXECUTOR_VALUE: Specifies the number of workers for the executor.
|
|
13
|
+
Defaults to 8.
|
|
14
|
+
A_SYNC_DEFAULT_MODE: Sets the default mode for a_sync functions if not specified.
|
|
15
|
+
A_SYNC_CACHE_TYPE: Sets the default cache type. If not specified, defaults to None.
|
|
16
|
+
A_SYNC_CACHE_TYPED: Boolean flag to determine if cache keys should consider types.
|
|
17
|
+
A_SYNC_RAM_CACHE_MAXSIZE: Sets the maximum size for the RAM cache. Defaults to -1.
|
|
18
|
+
A_SYNC_RAM_CACHE_TTL: Sets the time-to-live for cache entries. Defaults to None.
|
|
19
|
+
A_SYNC_RUNS_PER_MINUTE: Sets the rate limit for function execution.
|
|
20
|
+
A_SYNC_SEMAPHORE: Sets the semaphore limit for function execution.
|
|
7
21
|
"""
|
|
8
22
|
|
|
9
23
|
import functools
|
|
@@ -16,22 +30,26 @@ from a_sync._typing import *
|
|
|
16
30
|
EXECUTOR_TYPE = os.environ.get("A_SYNC_EXECUTOR_TYPE", "threads")
|
|
17
31
|
EXECUTOR_VALUE = int(os.environ.get("A_SYNC_EXECUTOR_VALUE", 8))
|
|
18
32
|
|
|
33
|
+
|
|
19
34
|
@functools.lru_cache(maxsize=1)
|
|
20
35
|
def get_default_executor() -> Executor:
|
|
21
|
-
"""
|
|
22
|
-
Get the default executor based on the :obj:`EXECUTOR_TYPE` environment variable.
|
|
36
|
+
"""Get the default executor based on the EXECUTOR_TYPE environment variable.
|
|
23
37
|
|
|
24
38
|
Returns:
|
|
25
|
-
|
|
39
|
+
An instance of either ProcessPoolExecutor or ThreadPoolExecutor.
|
|
26
40
|
|
|
27
41
|
Raises:
|
|
28
|
-
:
|
|
42
|
+
ValueError: If an invalid EXECUTOR_TYPE is specified. Valid values are
|
|
43
|
+
strings that start with 'p' for ProcessPoolExecutor or 't' for ThreadPoolExecutor.
|
|
29
44
|
"""
|
|
30
|
-
if EXECUTOR_TYPE.lower().startswith(
|
|
45
|
+
if EXECUTOR_TYPE.lower().startswith("p"): # p, P, proc, Processes, etc
|
|
31
46
|
return ProcessPoolExecutor(EXECUTOR_VALUE)
|
|
32
|
-
elif EXECUTOR_TYPE.lower().startswith(
|
|
47
|
+
elif EXECUTOR_TYPE.lower().startswith("t"): # t, T, thread, THREADS, etc
|
|
33
48
|
return ThreadPoolExecutor(EXECUTOR_VALUE)
|
|
34
|
-
raise ValueError(
|
|
49
|
+
raise ValueError(
|
|
50
|
+
"Invalid value for A_SYNC_EXECUTOR_TYPE. Please use 'threads' or 'processes'."
|
|
51
|
+
)
|
|
52
|
+
|
|
35
53
|
|
|
36
54
|
default_sync_executor = get_default_executor()
|
|
37
55
|
|
|
@@ -53,13 +71,29 @@ null_modifiers = ModifierKwargs(
|
|
|
53
71
|
# User configurable default modifiers to be applied to any a_sync decorated function if you do not specify kwarg values for each modifier.
|
|
54
72
|
|
|
55
73
|
DEFAULT_MODE: DefaultMode = os.environ.get("A_SYNC_DEFAULT_MODE") # type: ignore [assignment]
|
|
56
|
-
CACHE_TYPE: CacheType =
|
|
74
|
+
CACHE_TYPE: CacheType = (
|
|
75
|
+
typ
|
|
76
|
+
if (typ := os.environ.get("A_SYNC_CACHE_TYPE", "").lower())
|
|
77
|
+
else null_modifiers["cache_type"]
|
|
78
|
+
)
|
|
57
79
|
CACHE_TYPED = bool(os.environ.get("A_SYNC_CACHE_TYPED"))
|
|
58
|
-
RAM_CACHE_MAXSIZE = int(os.environ.get("A_SYNC_RAM_CACHE_MAXSIZE", -1))
|
|
59
|
-
RAM_CACHE_TTL =
|
|
80
|
+
RAM_CACHE_MAXSIZE = int(os.environ.get("A_SYNC_RAM_CACHE_MAXSIZE", -1))
|
|
81
|
+
RAM_CACHE_TTL = (
|
|
82
|
+
ttl
|
|
83
|
+
if (ttl := float(os.environ.get("A_SYNC_RAM_CACHE_TTL", 0)))
|
|
84
|
+
else null_modifiers["ram_cache_ttl"]
|
|
85
|
+
)
|
|
60
86
|
|
|
61
|
-
RUNS_PER_MINUTE =
|
|
62
|
-
|
|
87
|
+
RUNS_PER_MINUTE = (
|
|
88
|
+
rpm
|
|
89
|
+
if (rpm := int(os.environ.get("A_SYNC_RUNS_PER_MINUTE", 0)))
|
|
90
|
+
else null_modifiers["runs_per_minute"]
|
|
91
|
+
)
|
|
92
|
+
SEMAPHORE = (
|
|
93
|
+
rpm
|
|
94
|
+
if (rpm := int(os.environ.get("A_SYNC_SEMAPHORE", 0)))
|
|
95
|
+
else null_modifiers["semaphore"]
|
|
96
|
+
)
|
|
63
97
|
|
|
64
98
|
user_set_default_modifiers = ModifierKwargs(
|
|
65
99
|
default=DEFAULT_MODE,
|