debouncer 0.2.1 → 0.2.2

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 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