debouncer 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9f9e8547ac8f499bf83f7ea0a798cbc0296d8e33
4
- data.tar.gz: e585350713f4323b67f7c94c66b52c13929aa165
3
+ metadata.gz: 86b793306f411516a270b9eaa5ec1703dc0d068e
4
+ data.tar.gz: ffc85284be2c0847d21044fc33b9a97195f97e0e
5
5
  SHA512:
6
- metadata.gz: 706f48631fa33382c9d219f6f64b1cd7416ef4bbc5d1bcc103a58318022c16e772395b31ca32ea338d273c2a1c9f8e82bf9047ad20f52c61542c699318dd5231
7
- data.tar.gz: 665deabc223212af9b616d8509080908617d1490aaa34974b2fc9ce71f1cc99dbd49fde52b8890744b3aa25009dfd538c397fbb5654347ea03c18a7e5f6cf33f
6
+ metadata.gz: 525ea5eb59f3237090122124f7cfeb554801b0865bda50abe6d475e5fb0ccea345a6eb0486fbb240793e3ba7f09861313ec01624b1783043accc55d9297a5231
7
+ data.tar.gz: f947a3836cb89cafed1609639137c11cda52720f0c5828d92f075bc98f2be6e38a899510fa34004d01a3a0390298a90731dcc3ad807c7504145f6aa2333b83d7
data/README.md CHANGED
@@ -114,6 +114,8 @@ def combine_messages(memo, messages)
114
114
  end
115
115
  ```
116
116
 
117
+ If you're using grouping, calling `flush_send_warning` followed by `join_send_warning` won't have the effect you'd expect. When a group begins execution, the group's queue is cleared and a new queue is created, so joining that queue won't join the already-running thread. Instead, `flush_and_join_send_message` serves this purpose.
118
+
117
119
  Finally, you can also debounce class/module methods using the `mdebounce` method. If you want to combine calls on various instances of a class, a sound pattern is to debounce a class method and have instances call it. For example, consider broadcasting data changes to browsers, where you want to group changes to the same model together into single broadcasts:
118
120
 
119
121
  ```ruby
@@ -193,6 +195,16 @@ d.group(:messages).join
193
195
  d.join
194
196
  ```
195
197
 
198
+ As mentioned in the previous section, calling `flush` followed by `join` on a group won't join the thread that started executing when you called `flush`.
199
+
200
+ ```ruby
201
+ # This flushes and then joins an empty queue, returning instantly:
202
+ d.group(:messages).flush.join
203
+
204
+ # This flushes and waits for messages to be sent:
205
+ d.group(:messages).flush!
206
+ ```
207
+
196
208
  ## Development
197
209
 
198
210
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -51,7 +51,7 @@ class Debouncer
51
51
 
52
52
  def call_with_id(id, *args, &block)
53
53
  args << block if block
54
- thread = nil
54
+ run_thread = nil
55
55
  exclusively do
56
56
  thread = @timeouts[id] ||= new_thread { begin_delay id, args }
57
57
  @flush = [id]
@@ -68,37 +68,44 @@ class Debouncer
68
68
  else
69
69
  args.empty? ? old_args : args
70
70
  end
71
- if @flush == true
71
+ if @flush.is_a? Array
72
+ thread[:run_at] = Time.now + @delay
73
+ else
72
74
  thread.kill
73
75
  @timeouts.delete id
74
76
  @threads.delete thread
77
+ run_thread = new_thread { run_block thread }
78
+ run_thread = nil unless @flush
75
79
  @flush = false
76
- else
77
- thread[:run_at] = Time.now + @delay
78
80
  end
79
- end or
80
- run_block thread
81
+ end
82
+ run_thread.join if run_thread
81
83
  self
82
84
  end
83
85
 
84
- def flush(id = EMPTY)
86
+ def flush(id = EMPTY, and_join: false)
85
87
  if @lock.owned?
86
88
  raise ArgumentError, 'You cannot flush other groups from inside a reducer' unless id == EMPTY || [id] == @flush
87
- @flush = true
89
+ @flush = and_join
88
90
  elsif id == EMPTY
89
91
  flush @timeouts.keys.first while @timeouts.any?
90
92
  else
91
- dead = exclusively do
92
- if (thread = @timeouts.delete(id))
93
- thread.kill
94
- @threads.delete thread
93
+ thread = exclusively do
94
+ if (old_thread = @timeouts.delete(id))
95
+ old_thread.kill
96
+ @threads.delete old_thread
97
+ new_thread { run_block old_thread }
95
98
  end
96
99
  end
97
- run_block dead if dead
100
+ thread.join if thread
98
101
  end
99
102
  self
100
103
  end
101
104
 
105
+ def flush!(*args)
106
+ flush *args, and_join: true
107
+ end
108
+
102
109
  def join(id = EMPTY, kill_first: false)
103
110
  if id == EMPTY
104
111
  while (thread = exclusively { @threads.find &:alive? })
@@ -15,8 +15,14 @@ class Debouncer
15
15
  debouncer = "@#{base_name}#{SUFFIXES[suffix]}_debouncer"
16
16
  extras = ''
17
17
  if reduce_with
18
+ arity = __send__(class_method ? :method : :instance_method, reduce_with).arity
19
+ expected = grouped ? 2..3 : 2
20
+ unless arity < 0 || expected === arity
21
+ raise ArgumentError, 'Expected %s%s%s to accept %s arguments, but it accepts %s.' %
22
+ [self.name, class_method ? '.' : '#', reduce_with, expected, arity]
23
+ end
18
24
  if grouped
19
- extras << ".reducer { |old, new| [new.first, *self.#{reduce_with}(old[1..-1] || [], new[1..-1], new.first)] }"
25
+ extras << ".reducer { |old, new| [new.first, *self.#{reduce_with}(old[1..-1] || [], new[1..-1]#{', new.first' unless arity == 2})] }"
20
26
  else
21
27
  extras << ".reducer { |old, new| self.#{reduce_with} old, new }"
22
28
  end
@@ -37,6 +43,10 @@ class Debouncer
37
43
  #{debouncer}.flush *args if #{debouncer}
38
44
  end
39
45
 
46
+ def flush_and_join_#{name}(*args)
47
+ #{debouncer}.flush! *args if #{debouncer}
48
+ end
49
+
40
50
  def join_#{name}(*args)
41
51
  #{debouncer}.join *args if #{debouncer}
42
52
  end
@@ -11,6 +11,7 @@ class Debouncer
11
11
 
12
12
  def call(*args, &block)
13
13
  @debouncer.call_with_id @id, *args, &block
14
+ self
14
15
  end
15
16
 
16
17
  def to_proc
@@ -19,14 +20,22 @@ class Debouncer
19
20
 
20
21
  def flush
21
22
  @debouncer.flush @id
23
+ self
24
+ end
25
+
26
+ def flush!
27
+ @debouncer.flush! @id
28
+ self
22
29
  end
23
30
 
24
31
  def join
25
32
  @debouncer.join @id
33
+ self
26
34
  end
27
35
 
28
36
  def kill
29
37
  @debouncer.kill @id
38
+ self
30
39
  end
31
40
 
32
41
  def inspect_params
@@ -1,3 +1,3 @@
1
1
  class Debouncer
2
- VERSION = '0.2.1'
2
+ VERSION = '0.2.2'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: debouncer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neil E. Pearson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-02-27 00:00:00.000000000 Z
11
+ date: 2017-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler