Package: concurrency-limit
concurrency-limitconcurrency-limitis a library that implements a distributed concurrency limiting mechanism using Redis as a
backend. The library allows to limit the number of concurrent executions of code sections, either by waiting until
the currently running execution threads go below the limit, or by raising an exception if there are currently too many
execution threads.InstallationWith acorrectly configuredpipenvtoolchain:pipenvinstallconcurrency-limitYou may also use classicpipto install the package:pipinstallconcurrency-limitGetting startedHow it worksA limit of concurrently running scopes of a concurrency group can be defined using thelimitdecorator. A
concurrency group is defined by thekeyattribute of theLimitConfigurationinstance.If the count of concurrently running scopes of a concurrency group is below the configured limit, the scope is
executed immediately.If the count of concurrently running scopes of a concurrency group exceeds the configured limit, the context manager
wait unit it goes below the configured limit.If the count of concurrently running scopes of a concurrency group does not go below the configured limit with the
configured timeout, aConcurrencyLimitExceededExceptionexception is raised.UsageExample 1Limit the concurrency group"example-1"to100concurrently running scopes. If there are already100running
scopes, wait until the count of concurrently running scopes go below100. Fail if this does not happen within10seconds by raising aConcurrencyLimitExceededExceptionexception.importconcurrency_limitredis_configuration=concurrency_limit.RedisConfiguration(host='127.0.0.1',port=6379,)limit_configuration=concurrency_limit.LimitConfiguration(key='example-1',limit=100,limit_timeout=10,)withconcurrency_limit.limit(redis_configuration,limit_configuration):do_something_magic()Example 2Limit the concurrency group"example-1"to100concurrently running scopes. If there are already100running
scopes, wait until the count of concurrently running scopes go below100. Fail if this does not happen within10seconds by raising aConcurrencyLimitExceededExceptionexception. Check if the concurrently running scopes
are below the limit every1second.importconcurrency_limitredis_configuration=concurrency_limit.RedisConfiguration(host='127.0.0.1',port=6379,)limit_configuration=concurrency_limit.LimitConfiguration(key='example-2',limit=100,limit_timeout=0,limit_interval=1.0,)withconcurrency_limit.limit(redis_configuration,limit_configuration):do_something_magic()Example 3Limit the concurrency group"example-3"to100concurrently running scopes. If there are already100running
scopes, fail immediately by raising aConcurrencyLimitExceededExceptionexception.importconcurrency_limitredis_configuration=concurrency_limit.RedisConfiguration(host='127.0.0.1',port=6379,)limit_configuration=concurrency_limit.LimitConfiguration(key='example-3',limit=100,limit_timeout=0,)withconcurrency_limit.limit(redis_configuration,limit_configuration):do_something_magic()Example 4Limit the concurrency group"example-4"to100concurrently running scopes. The implementation of the
concurrency group needs to now the number of the concurrently running scope.importconcurrency_limitredis_configuration=concurrency_limit.RedisConfiguration(host='127.0.0.1',port=6379,)limit_configuration=concurrency_limit.LimitConfiguration(key='example-4',limit=100,)withconcurrency_limit.limit(redis_configuration,limit_configuration)asgroup_number:do_something_magic(group_number)Example 5Limit the concurrency group"example-5"to100concurrently running scopes. There is already an existing connection
pool to Redis within your application, thatconcurrency_limitshould use.importconcurrency_limitredis_configuration=concurrency_limit.RedisConfiguration(connection_pool=my_redis_connection_pool,)limit_configuration=concurrency_limit.LimitConfiguration(key='example-5',limit=100,)withconcurrency_limit.limit(redis_configuration,limit_configuration):do_something_magic()Example 6Limit the concurrency group"example-6"to100concurrently running scopes. A redis URL will be used instead of
separately specifying host and port for the redis connection.importconcurrency_limitredis_configuration=concurrency_limit.RedisConfiguration.from_url('redis://127.0.0.1:6379/0')limit_configuration=concurrency_limit.LimitConfiguration(key='example-6',limit=100,)withconcurrency_limit.limit(redis_configuration,limit_configuration):do_something_magic()Configuration optionsRedisConfigurationhost: strDefault:NoneThe hostname or IP of the Redis server.port: intDefault:6379The Redis server port.path: strDefault:NoneThe socket path used ifunix_socketis set.db: intDefault:0The Redis database to use.username: strDefault:NoneThe authentication username.password: strDefault:NoneThe authentication password.max_connections: intDefault:10The maximum connections on the connection pool for each process.timeout: intDefault:10The Redis server connection timeout.secure: boolDefault:FalseUse secure connection to Redis server.unix_socket: boolDefault:FalseUse UNIX socket connection to Redis server. Will ignoresecure, if set as there is no SSL mode with sockets.connection_class: typing.Type[redis.Connection]Default:NoneRedis connection class to use instead ofsecureandunix_socketfields, if set.connection_pool: redis.ConnectionPoolDefault:NoneUse this connection pool instance instead of the other fields, if set. All other fields of the configuration
instance are ignored in this case.LimitConfigurationkey: strThe concurrency limit group identifier. Use the same key for different scopes that should use the same concurrency
counter. You may use different limit configurations for scopes that use the same key.limit: intThe concurrency limit for the limited concurrency group (defined by thekey). If there are more concurrent executions
than this limit allows, the execution may wait for the concurrency count to go below the limit, or may
fail by raising aConcurrencyLimitExceededExceptionexception.limit_timeout: intDefault:10The timeout that defines how long to wait for the concurrency count to go below the configured limit. The timeout
is configured in seconds. Set to0if you want to raise aConcurrencyLimitExceededExceptionexception immediately
if there are too many concurrent executions.limit_interval: floatDefault:0.1If there are too many concurrent executions of a scope, and alimit_timeoutis set to a value greater than0, this
configuration defines the interval to re-check the current concurrency count. As soon as the concurrency count is
below the configured limit, the execution of the scope starts.limit_expire: intDefault:60The expiry time of the concurrency count key, configured in seconds. If a concurrency count is untouched for the
configured time, it will be deleted.Supported versionsSupportedPython 3.9✓Python 3.10✓Python 3.11✓Python 3.12✓List of developersAndreas StockerAStocker@anexia.com, Lead DeveloperPatrick TaibelPTaibel@anexia.com, Developer