forked from ruby-amqp/bunny
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Abstracted the idea of a connection.
Added EventMachine+Fibers support.
- Loading branch information
Showing
5 changed files
with
179 additions
and
16 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module Qrack | ||
module Connection | ||
autoload :Socket, "qrack/connection/socket" | ||
autoload :FiberedEm, "qrack/connection/fibered_em" | ||
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,27 @@ | ||
module Qrack | ||
module Connection | ||
class AbstractBase | ||
|
||
def initialize(host, port) | ||
raise "implement me" | ||
end | ||
|
||
def read(len) | ||
raise "implement me" | ||
end | ||
|
||
def write(data) | ||
raise "implement me" | ||
end | ||
|
||
def close | ||
raise "implement me" | ||
end | ||
|
||
def closed? | ||
raise "implement me" | ||
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,81 @@ | ||
require "eventmachine" | ||
require "fiber" | ||
require "qrack/connection/abstract_base" | ||
|
||
module Qrack | ||
module Connection | ||
class FiberedEm < AbstractBase | ||
|
||
module EmHandler | ||
|
||
def post_init | ||
@buffer = "" | ||
@closed = false | ||
end | ||
|
||
def connection_completed | ||
fiber_resume | ||
end | ||
|
||
def receive_data(data) | ||
@buffer += data | ||
fiber_resume | ||
end | ||
|
||
def unbind | ||
@closed = true | ||
end | ||
|
||
def fiber_yield | ||
@fiber = Fiber.current | ||
Fiber.yield | ||
end | ||
|
||
def fiber_resume | ||
@fiber.tap{ @fiber = nil }.resume if @fiber | ||
end | ||
|
||
def read(len) | ||
fiber_yield while @buffer.length < len | ||
@buffer[0,len].tap{ @buffer = @buffer[len..-1] || "" } | ||
end | ||
|
||
def write(data) | ||
send_data(data) | ||
end | ||
|
||
def close | ||
close_connection | ||
@closed = true | ||
end | ||
|
||
def closed? | ||
@closed | ||
end | ||
|
||
end | ||
|
||
def initialize(host, port, options = {}) | ||
@connection = EM.connect(host, port, EmHandler) | ||
@connection.fiber_yield | ||
end | ||
|
||
def read(len) | ||
@connection.read(len) | ||
end | ||
|
||
def write(data) | ||
@connection.write(data) | ||
end | ||
|
||
def closed? | ||
@connection.closed? | ||
end | ||
|
||
def close | ||
@connection.close | ||
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,44 @@ | ||
require "socket" | ||
require "qrack/connection/abstract_base" | ||
|
||
module Qrack | ||
module Connection | ||
class Socket < AbstractBase | ||
|
||
def initialize(host, port, options = {}) | ||
Bunny::Timer::timeout(options[:connect_timeout], ConnectionTimeout) do | ||
@socket = TCPSocket.new(host, port) | ||
end | ||
|
||
if Socket.constants.include?('TCP_NODELAY') || Socket.constants.include?(:TCP_NODELAY) | ||
@socket.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 | ||
end | ||
|
||
if options[:ssl] | ||
require 'openssl' unless defined? OpenSSL::SSL | ||
@socket = OpenSSL::SSL::SSLSocket.new(@socket) | ||
@socket.sync_close = true | ||
@socket.connect | ||
@socket.post_connection_check(host) if options[:verify_ssl] | ||
end | ||
end | ||
|
||
def read(*args) | ||
@socket.read(*args) | ||
end | ||
|
||
def write(*args) | ||
@socket.write(*args) | ||
end | ||
|
||
def close | ||
@socket.close | ||
end | ||
|
||
def closed? | ||
@socket.closed? | ||
end | ||
|
||
end | ||
end | ||
end |