-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
There's a lot to this and unfortunately it is in a single commit—it is a result of the exploration required to make this work. Some notable changes: * The reactor no longer has a selector. Instead, the scheduler has an event loop for managing io select across reactors. This simplifies the reactor to only dealing with routines. IO concerns are abstracted to both the event loop and the io routine. * Bridges now build on top of the above to manage the existing io routine. * The scheduler and routine now handle wakeups with a dedicated coordinator, implemented as a thread queue. This has proven to be fairly simple to work with and avoids the race conditions that conditions can have because the signal is persisted to the queue—if the coordinator is signals before the listener subscribes the listener will still receive the signal when it gets around to listening.
- Loading branch information
Showing
17 changed files
with
360 additions
and
299 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,53 @@ | ||
# frozen_string_literal: true | ||
|
||
module Goru | ||
# [public] | ||
# | ||
class Bridge | ||
def initialize(routine:, channel:) | ||
@routine = routine | ||
@channel = channel | ||
@channel.add_observer(self) | ||
update_status | ||
end | ||
|
||
# [public] | ||
# | ||
attr_reader :status | ||
|
||
# [public] | ||
# | ||
private def set_status(status) | ||
@status = status | ||
status_changed | ||
end | ||
|
||
# [public] | ||
# | ||
def update_status | ||
# noop | ||
end | ||
|
||
private def status_changed | ||
case @status | ||
when :ready | ||
@routine.bridged | ||
when :finished | ||
@channel.remove_observer(self) | ||
@routine.unbridge | ||
end | ||
end | ||
|
||
def channel_received | ||
update_status | ||
end | ||
|
||
def channel_read | ||
update_status | ||
end | ||
|
||
def channel_closed | ||
update_status | ||
end | ||
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,23 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative "../bridge" | ||
|
||
module Goru | ||
module Bridges | ||
class Readable < Bridge | ||
private def update_status | ||
status = if @routine.status == :finished | ||
:finished | ||
elsif @channel.full? | ||
:idle | ||
elsif @channel.closed? | ||
:finished | ||
else | ||
:ready | ||
end | ||
|
||
set_status(status) | ||
end | ||
end | ||
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,23 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative "../bridge" | ||
|
||
module Goru | ||
module Bridges | ||
class Writable < Bridge | ||
private def update_status | ||
status = if @routine.status == :finished | ||
:finished | ||
elsif @channel.any? | ||
:ready | ||
elsif @channel.closed? | ||
:finished | ||
else | ||
:idle | ||
end | ||
|
||
set_status(status) | ||
end | ||
end | ||
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,56 @@ | ||
# frozen_string_literal: true | ||
|
||
require "nio" | ||
|
||
module Goru | ||
# [public] | ||
# | ||
class IOEventLoop | ||
def initialize | ||
@commands = [] | ||
@selector = NIO::Selector.new | ||
@stopped = false | ||
end | ||
|
||
# [public] | ||
# | ||
def run | ||
until @stopped | ||
while (command = @commands.shift) | ||
action, routine = command | ||
|
||
case action | ||
when :register | ||
monitor = @selector.register(routine.io, routine.intent) | ||
monitor.value = routine.method(:wakeup) | ||
routine.monitor = monitor | ||
when :deregister | ||
routine.monitor = nil | ||
routine.monitor&.close | ||
end | ||
end | ||
|
||
@selector.select do |monitor| | ||
monitor.value.call | ||
end | ||
end | ||
ensure | ||
@selector.close | ||
end | ||
|
||
# [public] | ||
# | ||
def stop | ||
@stopped = true | ||
@selector.wakeup | ||
rescue IOError | ||
end | ||
|
||
# [public] | ||
# | ||
def <<(tuple) | ||
@commands << tuple | ||
@selector.wakeup | ||
end | ||
end | ||
end |
Oops, something went wrong.