async-limiter 1.5.3 → 2.0.0

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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/context/generic-limiter.md +167 -0
  4. data/context/getting-started.md +226 -0
  5. data/context/index.yaml +41 -0
  6. data/context/limited-limiter.md +184 -0
  7. data/context/queued-limiter.md +109 -0
  8. data/context/timing-strategies.md +666 -0
  9. data/context/token-usage.md +85 -0
  10. data/lib/async/limiter/generic.rb +160 -0
  11. data/lib/async/limiter/limited.rb +103 -0
  12. data/lib/async/limiter/queued.rb +85 -0
  13. data/lib/async/limiter/timing/burst.rb +153 -0
  14. data/lib/async/limiter/timing/fixed_window.rb +42 -0
  15. data/lib/async/limiter/timing/leaky_bucket.rb +146 -0
  16. data/lib/async/limiter/timing/none.rb +56 -0
  17. data/lib/async/limiter/timing/ordered.rb +58 -0
  18. data/lib/async/limiter/timing/sliding_window.rb +152 -0
  19. data/lib/async/limiter/token.rb +102 -0
  20. data/lib/async/limiter/version.rb +10 -3
  21. data/lib/async/limiter.rb +21 -7
  22. data/lib/metrics/provider/async/limiter/generic.rb +74 -0
  23. data/lib/metrics/provider/async/limiter.rb +7 -0
  24. data/lib/traces/provider/async/limiter/generic.rb +41 -0
  25. data/lib/traces/provider/async/limiter.rb +7 -0
  26. data/license.md +25 -0
  27. data/readme.md +45 -0
  28. data/releases.md +50 -0
  29. data.tar.gz.sig +0 -0
  30. metadata +70 -79
  31. metadata.gz.sig +0 -0
  32. data/lib/async/limiter/concurrent.rb +0 -101
  33. data/lib/async/limiter/constants.rb +0 -6
  34. data/lib/async/limiter/unlimited.rb +0 -53
  35. data/lib/async/limiter/window/continuous.rb +0 -21
  36. data/lib/async/limiter/window/fixed.rb +0 -21
  37. data/lib/async/limiter/window/sliding.rb +0 -21
  38. data/lib/async/limiter/window.rb +0 -296
data/license.md ADDED
@@ -0,0 +1,25 @@
1
+ # MIT License
2
+
3
+ Copyright, 2020-2021, by Bruno Sutic.
4
+ Copyright, 2025, by Francisco Mejia.
5
+ Copyright, 2025, by Shopify Inc.
6
+ Copyright, 2025, by Samuel Williams.
7
+ Copyright, 2025, by William T. Nelson.
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
data/readme.md ADDED
@@ -0,0 +1,45 @@
1
+ # Async Limiter
2
+
3
+ A Ruby gem providing flexible concurrency and rate limiting for async applications.
4
+
5
+ [![Development Status](https://github.com/socketry/async-limiter/workflows/Test/badge.svg)](https://github.com/socketry/async-limiter/actions?workflow=Test)
6
+
7
+ ## Usage
8
+
9
+ Please see the [project documentation](https://socketry.github.io/async-limiter/) for more details.
10
+
11
+ - [Getting Started](https://socketry.github.io/async-limiter/guides/getting-started/index) - This guide explains how to get started the `async-limiter` gem for controlling concurrency and rate limiting in Ruby applications.
12
+
13
+ - [Generic Limiter](https://socketry.github.io/async-limiter/guides/generic-limiter/index) - This guide explains the <code class="language-ruby">Async::Limiter::Generic</code> class, which provides unlimited concurrency by default and serves as the base implementation for all other limiters. It's ideal when you need timing constraints without concurrency limits, or when building custom limiter implementations.
14
+
15
+ - [Limited Limiter](https://socketry.github.io/async-limiter/guides/limited-limiter/index) - This guide explains the <code class="language-ruby">Async::Limiter::Limited</code> class, which provides semaphore-style concurrency control, enforcing a maximum number of concurrent operations. It's perfect for controlling concurrency when you have limited capacity or want to prevent system overload.
16
+
17
+ - [Queued Limiter](https://socketry.github.io/async-limiter/guides/queued-limiter/index) - This guide explains the <code class="language-ruby">Async::Limiter::Queued</code> class, which provides priority-based task scheduling with optional resource management. Its key feature is priority-based acquisition where higher priority tasks get access first, with optional support for distributing specific resources from a pre-populated queue.
18
+
19
+ - [Timing Strategies](https://socketry.github.io/async-limiter/guides/timing-strategies/index) - This guide explains how to use timing strategies to provide rate limiting and timing constraints that can be combined with any limiter. They control *when* operations can execute, while limiters control *how many* can execute concurrently.
20
+
21
+ - [Token Usage](https://socketry.github.io/async-limiter/guides/token-usage/index) - This guide explains how to use tokens for advanced resource management with `async-limiter`. Tokens provide sophisticated resource handling with support for re-acquisition and automatic cleanup.
22
+
23
+ ## See Also
24
+
25
+ - [falcon](https://github.com/socketry/falcon) - A high-performance web server
26
+ - [async-http](https://github.com/socketry/async-http) - Asynchronous HTTP client and server
27
+ - [async](https://github.com/socketry/async) - The core async framework
28
+
29
+ ## Contributing
30
+
31
+ We welcome contributions to this project.
32
+
33
+ 1. Fork it.
34
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
35
+ 3. Commit your changes (`git commit -am 'Add some feature'`).
36
+ 4. Push to the branch (`git push origin my-new-feature`).
37
+ 5. Create new Pull Request.
38
+
39
+ ### Developer Certificate of Origin
40
+
41
+ In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
42
+
43
+ ### Community Guidelines
44
+
45
+ This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
data/releases.md ADDED
@@ -0,0 +1,50 @@
1
+ # Releases
2
+
3
+ ## v2.0.0
4
+
5
+ The 2.0.x release should be considered somewhat unstable.
6
+
7
+ - **Breaking**: Complete API redesign. The v1.x classes (`Async::Limiter::Concurrent`, `Async::Limiter::Unlimited`, etc.) have been replaced with a new inheritance-based architecture.
8
+ - **Breaking**: Removed `blocking?` method due to inherent race conditions. Use `acquire(timeout: 0)` for non-blocking checks.
9
+ - **Breaking**: Timing strategies now use consumption-only model (no explicit `release` methods).
10
+ - **Breaking**: Window classes moved from `limiter/window/` to `limiter/timing/` with renamed classes.
11
+
12
+ ### New Architecture (replaces v1.x classes)
13
+
14
+ - **New**: `Async::Limiter::Generic` - Unlimited concurrency with timing coordination (replaces `Async::Limiter::Unlimited`).
15
+ - **New**: `Async::Limiter::Limited` - Counting semaphore with configurable limits (replaces `Async::Limiter::Concurrent`).
16
+ - **New**: `Async::Limiter::Queued` - Queue-based resource distribution with priority/timeout support (completely new functionality).
17
+
18
+ ### Advanced Timeout Features
19
+
20
+ - **New**: Unified timeout API - `acquire(timeout: 0/nil/seconds)` provides non-blocking and timed acquisition.
21
+ - **New**: Precise deadline tracking using `Async::Deadline` (requires async v2.31.0+).
22
+ - **New**: Convoy effect prevention - quick timeout operations not blocked by slow operations.
23
+ - **New**: Accurate timeout propagation - remaining time correctly passed through timing and concurrency layers.
24
+
25
+ ### Cost-Based Acquisition
26
+
27
+ - **New**: Cost-based acquisition - `acquire(cost: 1.5)` for proportional resource consumption.
28
+ - **New**: Starvation prevention - validates cost against timing strategy `maximum_cost` capacity.
29
+ - **New**: Flexible operation weighting - light operations consume fewer resources than heavy ones.
30
+
31
+ ### Enhanced Timing Strategies
32
+
33
+ - Add `Async::Limiter::Timing::LeakyBucket` for token bucket rate limiting with automatic leaking.
34
+ - Add `Async::Limiter::Timing::FixedWindow` for discrete time boundary enforcement.
35
+ - Rename `Async::Limiter::Timing::Window` to `Async::Limiter::Timing::SlidingWindow` for clarity.
36
+ - **Breaking**: Remove `release` methods from timing strategies (consumption-only model).
37
+ - **Breaking**: Remove `try_acquire` methods from timing strategies (unified timeout API).
38
+
39
+ ### Token-Based Resource Management
40
+
41
+ - **New**: `acquire_token` method returns `Token` objects for advanced resource management.
42
+ - **New**: Token re-acquisition with different options - `token.acquire(priority: 5)`.
43
+ - **New**: Automatic token cleanup with block usage.
44
+
45
+ ### Thread Safety and Performance
46
+
47
+ - **New**: Race condition elimination by moving timing coordination inside mutex.
48
+ - **New**: Fast path optimizations using `deadline.expired?` checks.
49
+ - **New**: Atomic timing coordination prevents race conditions in concurrent access.
50
+ - **Improved**: Test performance using time simulation instead of actual sleep calls.
data.tar.gz.sig ADDED
Binary file
metadata CHANGED
@@ -1,105 +1,97 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-limiter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.3
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno Sutic
8
- autorequire:
8
+ - Shopify Inc.
9
+ - Samuel Williams
10
+ - Francisco Mejia
11
+ - William
9
12
  bindir: bin
10
- cert_chain: []
11
- date: 2021-01-10 00:00:00.000000000 Z
13
+ cert_chain:
14
+ - |
15
+ -----BEGIN CERTIFICATE-----
16
+ MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11
17
+ ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK
18
+ CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz
19
+ MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd
20
+ MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj
21
+ bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
22
+ igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2
23
+ 9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW
24
+ sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE
25
+ e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN
26
+ XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss
27
+ RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn
28
+ tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM
29
+ zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW
30
+ xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
31
+ BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs
32
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs
33
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE
34
+ cBsSYwK6fYpM+hA5B5yZY2+L0Z+27jF1pWGgbhPH8/FjjBLVn+VFok3CDpRqwXCl
35
+ xCO40JEkKdznNy2avOMra6PFiQyOE74kCtv7P+Fdc+FhgqI5lMon6tt9rNeXmnW/
36
+ c1NaMRdxy999hmRGzUSFjozcCwxpy/LwabxtdXwXgSay4mQ32EDjqR1TixS1+smp
37
+ 8C/NCWgpIfzpHGJsjvmH2wAfKtTTqB9CVKLCWEnCHyCaRVuKkrKjqhYCdmMBqCws
38
+ JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP
39
+ eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt
40
+ Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
41
+ voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
42
+ -----END CERTIFICATE-----
43
+ date: 1980-01-02 00:00:00.000000000 Z
12
44
  dependencies:
13
45
  - !ruby/object:Gem::Dependency
14
46
  name: async
15
47
  requirement: !ruby/object:Gem::Requirement
16
48
  requirements:
17
- - - "~>"
49
+ - - ">="
18
50
  - !ruby/object:Gem::Version
19
- version: '1.27'
51
+ version: '2.31'
20
52
  type: :runtime
21
53
  prerelease: false
22
54
  version_requirements: !ruby/object:Gem::Requirement
23
55
  requirements:
24
- - - "~>"
56
+ - - ">="
25
57
  - !ruby/object:Gem::Version
26
- version: '1.27'
27
- - !ruby/object:Gem::Dependency
28
- name: async-rspec
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '1.15'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1.15'
41
- - !ruby/object:Gem::Dependency
42
- name: rspec
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '3.10'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '3.10'
55
- - !ruby/object:Gem::Dependency
56
- name: rubocop-rspec
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '2.0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '2.0'
69
- - !ruby/object:Gem::Dependency
70
- name: standard
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '0.9'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '0.9'
83
- description:
84
- email: code@brunosutic.com
58
+ version: '2.31'
85
59
  executables: []
86
60
  extensions: []
87
61
  extra_rdoc_files: []
88
62
  files:
63
+ - context/generic-limiter.md
64
+ - context/getting-started.md
65
+ - context/index.yaml
66
+ - context/limited-limiter.md
67
+ - context/queued-limiter.md
68
+ - context/timing-strategies.md
69
+ - context/token-usage.md
89
70
  - lib/async/limiter.rb
90
- - lib/async/limiter/concurrent.rb
91
- - lib/async/limiter/constants.rb
92
- - lib/async/limiter/unlimited.rb
71
+ - lib/async/limiter/generic.rb
72
+ - lib/async/limiter/limited.rb
73
+ - lib/async/limiter/queued.rb
74
+ - lib/async/limiter/timing/burst.rb
75
+ - lib/async/limiter/timing/fixed_window.rb
76
+ - lib/async/limiter/timing/leaky_bucket.rb
77
+ - lib/async/limiter/timing/none.rb
78
+ - lib/async/limiter/timing/ordered.rb
79
+ - lib/async/limiter/timing/sliding_window.rb
80
+ - lib/async/limiter/token.rb
93
81
  - lib/async/limiter/version.rb
94
- - lib/async/limiter/window.rb
95
- - lib/async/limiter/window/continuous.rb
96
- - lib/async/limiter/window/fixed.rb
97
- - lib/async/limiter/window/sliding.rb
82
+ - lib/metrics/provider/async/limiter.rb
83
+ - lib/metrics/provider/async/limiter/generic.rb
84
+ - lib/traces/provider/async/limiter.rb
85
+ - lib/traces/provider/async/limiter/generic.rb
86
+ - license.md
87
+ - readme.md
88
+ - releases.md
98
89
  homepage: https://github.com/bruno-/async-limiter
99
90
  licenses:
100
91
  - MIT
101
- metadata: {}
102
- post_install_message:
92
+ metadata:
93
+ documentation_uri: https://socketry.github.io/async-limiter/
94
+ source_code_uri: https://github.com/socketry/async-limiter.git
103
95
  rdoc_options: []
104
96
  require_paths:
105
97
  - lib
@@ -107,15 +99,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
107
99
  requirements:
108
100
  - - ">="
109
101
  - !ruby/object:Gem::Version
110
- version: 2.7.0
102
+ version: '3.2'
111
103
  required_rubygems_version: !ruby/object:Gem::Requirement
112
104
  requirements:
113
105
  - - ">="
114
106
  - !ruby/object:Gem::Version
115
107
  version: '0'
116
108
  requirements: []
117
- rubygems_version: 3.2.3
118
- signing_key:
109
+ rubygems_version: 3.6.9
119
110
  specification_version: 4
120
- summary: Async limiters
111
+ summary: Execution rate limiting for Async
121
112
  test_files: []
metadata.gz.sig ADDED
Binary file
@@ -1,101 +0,0 @@
1
- require "async/task"
2
- require_relative "constants"
3
-
4
- module Async
5
- module Limiter
6
- class Concurrent
7
- attr_reader :count
8
-
9
- attr_reader :limit
10
-
11
- def initialize(limit = 1, parent: nil, queue: [])
12
- @count = 0
13
- @limit = limit
14
- @waiting = queue
15
- @parent = parent
16
-
17
- validate!
18
- end
19
-
20
- def blocking?
21
- limit_blocking?
22
- end
23
-
24
- def async(*queue_args, parent: (@parent || Task.current), **options)
25
- acquire(*queue_args)
26
- parent.async(**options) do |task|
27
- yield task
28
- ensure
29
- release
30
- end
31
- end
32
-
33
- def sync(*queue_args)
34
- acquire(*queue_args) do
35
- yield(@parent || Task.current)
36
- end
37
- end
38
-
39
- def acquire(*queue_args)
40
- wait(*queue_args)
41
- @count += 1
42
-
43
- return unless block_given?
44
-
45
- begin
46
- yield
47
- ensure
48
- release
49
- end
50
- end
51
-
52
- def release
53
- @count -= 1
54
-
55
- resume_waiting
56
- end
57
-
58
- def limit=(new_limit)
59
- validate_limit!(new_limit)
60
-
61
- @limit = new_limit
62
- end
63
-
64
- private
65
-
66
- def limit_blocking?
67
- @count >= @limit
68
- end
69
-
70
- def wait(*queue_args)
71
- fiber = Fiber.current
72
-
73
- if blocking?
74
- @waiting.push(fiber, *queue_args) # queue_args used for custom queues
75
- Task.yield while blocking?
76
- end
77
- rescue Exception # rubocop:disable Lint/RescueException
78
- @waiting.delete(fiber)
79
- raise
80
- end
81
-
82
- def resume_waiting
83
- while !blocking? && (fiber = @waiting.shift)
84
- fiber.resume if fiber.alive?
85
- end
86
- end
87
-
88
- def validate!
89
- if @limit.finite? && (@limit % 1).nonzero?
90
- raise ArgumentError, "limit must be a whole number"
91
- end
92
-
93
- validate_limit!
94
- end
95
-
96
- def validate_limit!(value = @limit)
97
- raise ArgumentError, "limit must be greater than 1" if value < 1
98
- end
99
- end
100
- end
101
- end
@@ -1,6 +0,0 @@
1
- module Async
2
- module Limiter
3
- Error = Class.new(StandardError)
4
- ArgumentError = Class.new(Error)
5
- end
6
- end
@@ -1,53 +0,0 @@
1
- require "async/task"
2
-
3
- module Async
4
- module Limiter
5
- class Unlimited
6
- attr_reader :count
7
-
8
- def initialize(parent: nil)
9
- @count = 0
10
- @parent = parent
11
- end
12
-
13
- def limit
14
- Float::INFINITY
15
- end
16
-
17
- def blocking?
18
- false
19
- end
20
-
21
- def async(parent: (@parent || Task.current), **options)
22
- acquire
23
- parent.async(**options) do |task|
24
- yield task
25
- ensure
26
- release
27
- end
28
- end
29
-
30
- def sync(*queue_args)
31
- acquire(*queue_args) do
32
- yield(@parent || Task.current)
33
- end
34
- end
35
-
36
- def acquire
37
- @count += 1
38
-
39
- return unless block_given?
40
-
41
- begin
42
- yield
43
- ensure
44
- release
45
- end
46
- end
47
-
48
- def release
49
- @count -= 1
50
- end
51
- end
52
- end
53
- end
@@ -1,21 +0,0 @@
1
- require_relative "../window"
2
-
3
- module Async
4
- module Limiter
5
- class Window
6
- class Continuous < Window
7
- def initialize(limit = 1, window: 1, parent: nil, lock: true, queue: [])
8
- super(
9
- limit,
10
- type: :sliding, # type doesn't matter, but sliding is less work
11
- burstable: false,
12
- window: window,
13
- parent: parent,
14
- lock: lock,
15
- queue: queue
16
- )
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,21 +0,0 @@
1
- require_relative "../window"
2
-
3
- module Async
4
- module Limiter
5
- class Window
6
- class Fixed < Window
7
- def initialize(limit = 1, window: 1, parent: nil, lock: true, queue: [])
8
- super(
9
- limit,
10
- type: :fixed,
11
- burstable: true,
12
- window: window,
13
- parent: parent,
14
- lock: lock,
15
- queue: queue
16
- )
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,21 +0,0 @@
1
- require_relative "../window"
2
-
3
- module Async
4
- module Limiter
5
- class Window
6
- class Sliding < Window
7
- def initialize(limit = 1, window: 1, parent: nil, lock: true, queue: [])
8
- super(
9
- limit,
10
- type: :sliding,
11
- burstable: true,
12
- window: window,
13
- parent: parent,
14
- lock: lock,
15
- queue: queue
16
- )
17
- end
18
- end
19
- end
20
- end
21
- end