-
Notifications
You must be signed in to change notification settings - Fork 328
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Debounce jobs to broadcast page refresh signals
A page refresh stream signals the need to reload the page. It's a global action that makes sense to aggregate when multiple signals are generated in a short period of time for a given streamable. This implementation is based on creating a thread-level debouncer associated to the set of streamables. The debouncer is implemented using concurrent-ruby's scheduled tasks.
- Loading branch information
1 parent
a669409
commit 8fcc54b
Showing
7 changed files
with
115 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
class Turbo::Debouncer | ||
attr_reader :delay, :scheduled_task | ||
|
||
DEFAULT_DELAY = 0.5 | ||
|
||
def initialize(delay: DEFAULT_DELAY) | ||
@delay = delay | ||
@scheduled_task = nil | ||
end | ||
|
||
def debounce(&block) | ||
scheduled_task&.cancel unless scheduled_task&.complete? | ||
@scheduled_task = Concurrent::ScheduledTask.execute(delay, &block) | ||
end | ||
|
||
def wait | ||
scheduled_task.wait(wait_timeout) | ||
end | ||
|
||
private | ||
def wait_timeout | ||
delay + 1 | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# A decorated debouncer that will store instances in the current thread clearing them | ||
# after the debounced logic triggers. | ||
class Turbo::ThreadDebouncer | ||
delegate :wait, to: :debouncer | ||
|
||
def self.for(key, delay: Turbo::Debouncer::DEFAULT_DELAY) | ||
Thread.current[key] ||= new(key, Thread.current, delay: delay) | ||
end | ||
|
||
private_class_method :new | ||
|
||
def initialize(key, thread, delay: ) | ||
@key = key | ||
@debouncer = Turbo::Debouncer.new(delay: delay) | ||
@thread = thread | ||
end | ||
|
||
def debounce | ||
debouncer.debounce do | ||
yield.tap do | ||
thread[key] = nil | ||
end | ||
end | ||
end | ||
|
||
private | ||
attr_reader :key, :debouncer, :thread | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters