debounced 0.1.19 → 0.1.21
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.
- checksums.yaml +4 -4
- data/README.md +40 -28
- data/lib/debounced/callback.rb +21 -5
- data/lib/debounced/service_proxy.rb +1 -1
- data/lib/debounced/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '08e33800aa43c78d6be5abffcda05d1ca70e46436531f42f79193cbf1ab86059'
|
4
|
+
data.tar.gz: 455c57c30a34f260aeb6adf2e61c45c13b190d13b8e4236f324f6a703beab655
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32a872b4f22b473ec19890db74d264a11931fc810c57d83f9d14e1ce1ff18f4eb2f5403b74d45feb16fdf27cd236886e19ba18f9096d6009bcc0a6aed574ce93
|
7
|
+
data.tar.gz: fabd72e50c1b94cbb4fcf2677306c360f8eb299e9eff14b7acb380b1737722e54e2ee5ec03ea58d76cdb82427cc5dca0b36542367748a30833ec288d3c553be8
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Debounced
|
2
2
|
|
3
|
-
|
3
|
+
Efficient debouncing mechanism for Ruby events. Use it for rate limiting, deduplication, or other
|
4
|
+
scenarios where you want to wait for a certain amount of time before processing a given event.
|
4
5
|
|
5
6
|
## Installation
|
6
7
|
|
@@ -26,15 +27,7 @@ $ gem install debounced
|
|
26
27
|
|
27
28
|
This gem requires Node.js to be installed on your system, as it uses a Node.js server to handle the debouncing logic. You'll need:
|
28
29
|
|
29
|
-
- Node.js >=
|
30
|
-
- npm (to install the required node packages)
|
31
|
-
|
32
|
-
After installing the gem, run:
|
33
|
-
|
34
|
-
```bash
|
35
|
-
$ cd $(bundle show debounced)
|
36
|
-
$ npm install
|
37
|
-
```
|
30
|
+
- Node.js >= 20.0.0
|
38
31
|
|
39
32
|
## Usage
|
40
33
|
|
@@ -44,51 +37,70 @@ $ npm install
|
|
44
37
|
# config/initializers/debounced.rb
|
45
38
|
Debounced.configure do |config|
|
46
39
|
config.socket_descriptor = '/tmp/my_app.debounceEvents'
|
40
|
+
config.wait_timeout = 3 # idle timeout in seconds for a given activity descriptor
|
47
41
|
end
|
48
42
|
```
|
49
43
|
|
50
44
|
### Starting the server
|
51
45
|
|
52
|
-
|
46
|
+
Start the nodeJS debounce server with:
|
53
47
|
|
54
48
|
```bash
|
55
|
-
$ bundle exec debounced
|
49
|
+
$ bundle exec debounced:server
|
56
50
|
```
|
57
51
|
|
58
|
-
|
52
|
+
In your Ruby application code:
|
59
53
|
|
60
54
|
```ruby
|
61
55
|
require 'debounced'
|
62
56
|
|
63
|
-
# Start
|
57
|
+
# Start a background thread to receive notification that events are ready to be handled after debounce wait is complete
|
64
58
|
proxy = Debounced::ServiceProxy.new
|
65
|
-
|
59
|
+
proxy.listen
|
66
60
|
|
67
|
-
#
|
61
|
+
# Define your event class; create a helper method that will produce a Debounced::Callback object, which
|
62
|
+
# is used to notify the server that the event is ready to be handled
|
68
63
|
class MyEvent
|
69
|
-
attr_reader :
|
64
|
+
attr_reader :test_id
|
70
65
|
|
71
|
-
def initialize(
|
72
|
-
@
|
66
|
+
def initialize(test_id:)
|
67
|
+
@test_id = test_id
|
73
68
|
end
|
74
69
|
|
75
|
-
def
|
76
|
-
#
|
77
|
-
puts "Publishing event
|
70
|
+
def publish
|
71
|
+
# put logic here to publish the event after debouncing
|
72
|
+
puts "Publishing event: #{inspect}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def debounce_callback
|
76
|
+
Debounced::Callback.new(
|
77
|
+
class_name: self.class.name,
|
78
|
+
params: { test_id: },
|
79
|
+
method_name: 'publish',
|
80
|
+
method_params: []
|
81
|
+
)
|
78
82
|
end
|
79
83
|
end
|
80
84
|
|
81
|
-
event = MyEvent.new({
|
82
|
-
|
85
|
+
event = MyEvent.new({ test_id: "Hello World" })
|
86
|
+
|
87
|
+
# request the server to debounce the event, ignoring it if another event with the
|
88
|
+
# same descriptor arrives before the timeout
|
89
|
+
proxy.debounce_activity("my-event-123", 5, event.debounce_callback)
|
90
|
+
# 2 seconds later
|
91
|
+
proxy.debounce_activity("my-event-123", 5, event.debounce_callback)
|
92
|
+
# 4 seconds later
|
93
|
+
proxy.debounce_activity("my-event-123", 5, event.debounce_callback)
|
94
|
+
# 5 seconds later the event is published!
|
95
|
+
# > Publishing event: #<MyEvent:0x00007f9b1b8b3b40 @test_id="Hello World">
|
83
96
|
```
|
84
97
|
|
85
98
|
## How It Works
|
86
99
|
|
87
100
|
1. The gem creates a Unix socket for communication between Ruby and Node.js
|
88
|
-
2. When you call `
|
89
|
-
3. The Node.js server
|
90
|
-
4.
|
91
|
-
5. When the timeout expires, it sends the event back to Ruby to be published
|
101
|
+
2. When you call `debounce_activity`, it sends the event to the Node.js server
|
102
|
+
3. The Node.js server restarts a timer every time an event with a given activity_descriptor is received
|
103
|
+
4. When the timeout expires, it sends the event back to Ruby to be published
|
92
104
|
|
93
105
|
## License
|
94
106
|
|
data/lib/debounced/callback.rb
CHANGED
@@ -3,7 +3,18 @@ require 'debug'
|
|
3
3
|
module Debounced
|
4
4
|
class Callback
|
5
5
|
|
6
|
-
|
6
|
+
attr_accessor :class_name, :params, :method_name, :method_params
|
7
|
+
|
8
|
+
###
|
9
|
+
# Create a new callback object
|
10
|
+
# @param class_name [String] the name of the class to call the method on
|
11
|
+
# @param params [Hash] a hash of parameters to pass to the class initializer (optional)
|
12
|
+
# @param method_name [String] the name of the method to call.
|
13
|
+
# If the method is a class method, it should be prefixed with a "."
|
14
|
+
# If it is an instance method, it should be prefixed with a "#"
|
15
|
+
# @param method_params [Array] an array of parameters to pass to the method
|
16
|
+
# @return [Debounced::Callback]
|
17
|
+
# @note @params is ignored if the method is a class method
|
7
18
|
def initialize(class_name:, params:, method_name:, method_params:)
|
8
19
|
@class_name = class_name.to_s
|
9
20
|
@params = params || {}
|
@@ -11,7 +22,7 @@ module Debounced
|
|
11
22
|
@method_params = method_params || []
|
12
23
|
end
|
13
24
|
|
14
|
-
def self.
|
25
|
+
def self.parse(data)
|
15
26
|
new(
|
16
27
|
class_name: data['class_name'],
|
17
28
|
params: data['params'],
|
@@ -30,9 +41,14 @@ module Debounced
|
|
30
41
|
end
|
31
42
|
|
32
43
|
def call
|
33
|
-
Object.const_get(class_name)
|
34
|
-
|
35
|
-
|
44
|
+
klass = Object.const_get(class_name)
|
45
|
+
message = method_name[1..-1] # strip of method_name prefix, either "." or "#"
|
46
|
+
target = klass
|
47
|
+
if method_name[0] == '#'
|
48
|
+
target = klass.new(**params.transform_keys(&:to_sym))
|
49
|
+
end
|
50
|
+
target.send(message, *method_params)
|
36
51
|
end
|
52
|
+
|
37
53
|
end
|
38
54
|
end
|
data/lib/debounced/version.rb
CHANGED