celluloid-io 0.12.1 → 0.13.0.pre
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.
- data/.travis.yml +6 -5
- data/CHANGES.md +5 -3
- data/Gemfile +1 -1
- data/Guardfile +5 -0
- data/README.md +32 -0
- data/benchmarks/actor.rb +25 -5
- data/celluloid-io.gemspec +4 -2
- data/examples/echo_server.rb +1 -1
- data/examples/echo_unix_client.rb +28 -0
- data/examples/echo_unix_server.rb +43 -0
- data/lib/celluloid/io/common_methods.rb +13 -9
- data/lib/celluloid/io/mailbox.rb +3 -3
- data/lib/celluloid/io/reactor.rb +2 -2
- data/lib/celluloid/io/ssl_server.rb +36 -0
- data/lib/celluloid/io/ssl_socket.rb +39 -0
- data/lib/celluloid/io/tcp_server.rb +10 -3
- data/lib/celluloid/io/tcp_socket.rb +0 -2
- data/lib/celluloid/io/udp_socket.rb +1 -1
- data/lib/celluloid/io/unix_server.rb +44 -0
- data/lib/celluloid/io/unix_socket.rb +40 -0
- data/lib/celluloid/io/version.rb +1 -1
- data/lib/celluloid/io.rb +6 -1
- data/log/.gitignore +1 -0
- data/spec/celluloid/io/ssl_server_spec.rb +91 -0
- data/spec/celluloid/io/ssl_socket_spec.rb +189 -0
- data/spec/celluloid/io/tcp_server_spec.rb +1 -1
- data/spec/celluloid/io/tcp_socket_spec.rb +66 -3
- data/spec/celluloid/io/udp_socket_spec.rb +1 -1
- data/spec/celluloid/io/unix_server_spec.rb +70 -0
- data/spec/celluloid/io/unix_socket_spec.rb +140 -0
- data/spec/fixtures/client.crt +22 -0
- data/spec/fixtures/client.key +27 -0
- data/spec/fixtures/server.crt +22 -0
- data/spec/fixtures/server.key +27 -0
- data/spec/spec_helper.rb +41 -4
- metadata +106 -54
data/.travis.yml
CHANGED
@@ -3,12 +3,13 @@ rvm:
|
|
3
3
|
- 1.9.3
|
4
4
|
- ruby-head
|
5
5
|
- jruby-19mode
|
6
|
+
- rbx-19mode
|
7
|
+
- jruby-head
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
# - rbx-19mode
|
9
|
+
matrix:
|
10
|
+
allow_failures:
|
11
|
+
- rvm: ruby-head
|
12
|
+
- rvm: jruby-head
|
12
13
|
|
13
14
|
notifications:
|
14
15
|
irc: "irc.freenode.org#celluloid"
|
data/CHANGES.md
CHANGED
data/Gemfile
CHANGED
data/Guardfile
ADDED
data/README.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
=============
|
3
3
|
[](http://travis-ci.org/celluloid/celluloid-io)
|
4
4
|
[](https://gemnasium.com/celluloid/celluloid-io)
|
5
|
+
[](https://codeclimate.com/github/celluloid/celluloid-io)
|
5
6
|
|
6
7
|
You don't have to choose between threaded and evented IO! Celluloid::IO
|
7
8
|
provides an event-driven IO system for building fast, scalable network
|
@@ -35,6 +36,37 @@ and kqueue.
|
|
35
36
|
|
36
37
|
Like Celluloid::IO? [Join the Google Group](http://groups.google.com/group/celluloid-ruby)
|
37
38
|
|
39
|
+
When should I use Celluloid::IO?
|
40
|
+
--------------------------------
|
41
|
+
|
42
|
+
Unlike systems like Node.js, Celluloid does not require that all I/O be
|
43
|
+
"evented". Celluloid fully supports any libraries that support blocking I/O
|
44
|
+
and for the *overwhelming majority* of use cases blocking I/O is more than
|
45
|
+
sufficient. Using blocking I/O means that any Ruby library you want will
|
46
|
+
Just Work without resorting to any kind of theatrics.
|
47
|
+
|
48
|
+
Celluloid::IO exists for a few reasons:
|
49
|
+
|
50
|
+
* During a blocking I/O operation, Celluloid actors cannot respond to incoming
|
51
|
+
messages to their mailboxes. They will process messages as soon as the
|
52
|
+
method containing a blocking I/O operation completes, however until this
|
53
|
+
happens the entire actor is blocked. If you would like to multiplex both
|
54
|
+
message processing and I/O operations, you will want to use Celluloid::IO.
|
55
|
+
This is especially important for *indefinite* blocking operations, such as
|
56
|
+
listening for incoming TCP connections.
|
57
|
+
* Celluloid uses a native thread per actor. While native threads aren't
|
58
|
+
particularly expensive in Ruby (~20kB of RAM), you can use less RAM using
|
59
|
+
Celluloid::IO. You might consider using Celluloid::IO over an
|
60
|
+
actor-per-connection if you are dealing with 10,000 connections or more.
|
61
|
+
* The goal of Celluloid::IO is to fully integrate it into the Celluloid
|
62
|
+
ecosystem, including DCell. DCell will hopefully eventually support
|
63
|
+
serializable I/O handles that you can seamlessly transfer between nodes.
|
64
|
+
|
65
|
+
All that said, if you are just starting out with Celluloid, you probably want
|
66
|
+
to start off using blocking I/O until you understand the fundamentals of
|
67
|
+
Celluloid and have encountered one of the above reasons for switching
|
68
|
+
over to Celluloid::IO.
|
69
|
+
|
38
70
|
Supported Platforms
|
39
71
|
-------------------
|
40
72
|
|
data/benchmarks/actor.rb
CHANGED
@@ -2,12 +2,25 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'bundler/setup'
|
5
|
-
require 'celluloid
|
5
|
+
require 'celluloid'
|
6
6
|
require 'benchmark/ips'
|
7
7
|
|
8
8
|
class ExampleActor
|
9
9
|
include Celluloid::IO
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@condition = Condition.new
|
13
|
+
end
|
14
|
+
|
10
15
|
def example_method; end
|
16
|
+
|
17
|
+
def finished
|
18
|
+
@condition.signal
|
19
|
+
end
|
20
|
+
|
21
|
+
def wait_until_finished
|
22
|
+
@condition.wait
|
23
|
+
end
|
11
24
|
end
|
12
25
|
|
13
26
|
example_actor = ExampleActor.new
|
@@ -24,11 +37,18 @@ end
|
|
24
37
|
|
25
38
|
Benchmark.ips do |ips|
|
26
39
|
ips.report("spawn") { ExampleActor.new.terminate }
|
27
|
-
ips.report("calls") { example_actor.example_method }
|
28
|
-
|
29
|
-
# FIXME: deadlock?! o_O
|
30
|
-
ips.report("async calls") { example_actor.example_method! } unless RUBY_ENGINE == 'ruby'
|
31
40
|
|
41
|
+
ips.report("calls") { example_actor.example_method }
|
42
|
+
|
43
|
+
ips.report("async calls") do |n|
|
44
|
+
waiter = example_actor.future.wait_until_finished
|
45
|
+
|
46
|
+
for i in 1..n; example_actor.async.example_method; end
|
47
|
+
example_actor.async.finished
|
48
|
+
|
49
|
+
waiter.value
|
50
|
+
end
|
51
|
+
|
32
52
|
ips.report("messages") do |n|
|
33
53
|
latch_in << n
|
34
54
|
for i in 0..n; mailbox << :message; end
|
data/celluloid-io.gemspec
CHANGED
@@ -15,10 +15,12 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Celluloid::IO::VERSION
|
17
17
|
|
18
|
-
gem.add_dependency 'celluloid', '
|
18
|
+
gem.add_dependency 'celluloid', '>= 0.13.0.pre'
|
19
19
|
gem.add_dependency 'nio4r', '>= 0.4.0'
|
20
|
-
|
20
|
+
|
21
21
|
gem.add_development_dependency 'rake'
|
22
22
|
gem.add_development_dependency 'rspec'
|
23
23
|
gem.add_development_dependency 'benchmark_suite'
|
24
|
+
gem.add_development_dependency 'guard-rspec'
|
25
|
+
gem.add_development_dependency 'rb-fsevent', '~> 0.9.1' if RUBY_PLATFORM =~ /darwin/
|
24
26
|
end
|
data/examples/echo_server.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'celluloid/io'
|
3
|
+
|
4
|
+
class EchoUNIXClient
|
5
|
+
include Celluloid::IO
|
6
|
+
|
7
|
+
def initialize(socket_path)
|
8
|
+
puts "*** connecting to #{socket_path}"
|
9
|
+
@socket_path = socket_path
|
10
|
+
@socket = UNIXSocket.open(socket_path)
|
11
|
+
end
|
12
|
+
|
13
|
+
def echo(msg)
|
14
|
+
puts "*** send to server: '#{msg}'"
|
15
|
+
@socket.puts(msg)
|
16
|
+
data = @socket.readline.chomp
|
17
|
+
puts "*** server unswer '#{data}'"
|
18
|
+
data
|
19
|
+
end
|
20
|
+
|
21
|
+
def finalize
|
22
|
+
@socket.close if @socket
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
c = EchoUNIXClient.new("/tmp/sock_test")
|
28
|
+
c.echo("DATA")
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'celluloid/io'
|
3
|
+
|
4
|
+
class EchoUNIXServer
|
5
|
+
include Celluloid::IO
|
6
|
+
|
7
|
+
attr_reader :socket_path, :server
|
8
|
+
|
9
|
+
def initialize(socket_path)
|
10
|
+
puts "*** start server #{socket_path}"
|
11
|
+
@socket_path = socket_path
|
12
|
+
@server = UNIXServer.open(socket_path)
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
loop { handle_connection! @server.accept }
|
17
|
+
end
|
18
|
+
|
19
|
+
def handle_connection(socket)
|
20
|
+
loop do
|
21
|
+
data = socket.readline
|
22
|
+
puts "*** gets data #{data}"
|
23
|
+
socket.write(data)
|
24
|
+
end
|
25
|
+
|
26
|
+
rescue EOFError
|
27
|
+
puts "*** disconnected"
|
28
|
+
|
29
|
+
ensure
|
30
|
+
socket.close
|
31
|
+
end
|
32
|
+
|
33
|
+
def finalize
|
34
|
+
if @server
|
35
|
+
@server.close
|
36
|
+
File.delete(@socket_path)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
s = EchoUNIXServer.new("/tmp/sock_test")
|
43
|
+
s.run
|
@@ -4,7 +4,7 @@ module Celluloid
|
|
4
4
|
module CommonMethods
|
5
5
|
# Are we inside of a Celluloid::IO actor?
|
6
6
|
def evented?
|
7
|
-
actor = Thread.current[:
|
7
|
+
actor = Thread.current[:celluloid_actor]
|
8
8
|
actor && actor.mailbox.is_a?(Celluloid::IO::Mailbox)
|
9
9
|
end
|
10
10
|
|
@@ -29,7 +29,7 @@ module Celluloid
|
|
29
29
|
# Request exclusive control for a particular operation
|
30
30
|
# Type should be one of :r (read) or :w (write)
|
31
31
|
def acquire_ownership(type)
|
32
|
-
return unless Thread.current[:
|
32
|
+
return unless Thread.current[:celluloid_actor]
|
33
33
|
|
34
34
|
case type
|
35
35
|
when :r
|
@@ -40,14 +40,14 @@ module Celluloid
|
|
40
40
|
end
|
41
41
|
|
42
42
|
# Celluloid needs a better API here o_O
|
43
|
-
Thread.current[:
|
43
|
+
Thread.current[:celluloid_actor].wait(self) while instance_variable_defined?(ivar) && instance_variable_get(ivar)
|
44
44
|
instance_variable_set(ivar, Task.current)
|
45
45
|
end
|
46
46
|
|
47
47
|
# Release ownership for a particular operation
|
48
48
|
# Type should be one of :r (read) or :w (write)
|
49
49
|
def release_ownership(type)
|
50
|
-
return unless Thread.current[:
|
50
|
+
return unless Thread.current[:celluloid_actor]
|
51
51
|
|
52
52
|
case type
|
53
53
|
when :r
|
@@ -57,13 +57,13 @@ module Celluloid
|
|
57
57
|
else raise ArgumentError, "invalid ownership type: #{type}"
|
58
58
|
end
|
59
59
|
|
60
|
-
raise "not owner" unless instance_variable_get(ivar) == Task.current
|
60
|
+
raise "not owner" unless instance_variable_defined?(ivar) && instance_variable_get(ivar) == Task.current
|
61
61
|
instance_variable_set(ivar, nil)
|
62
|
-
Thread.current[:
|
62
|
+
Thread.current[:celluloid_actor].signal(self)
|
63
63
|
end
|
64
64
|
|
65
65
|
def read(length = nil, buffer = nil)
|
66
|
-
buffer ||= ''
|
66
|
+
buffer ||= ''.force_encoding(Encoding::ASCII_8BIT)
|
67
67
|
remaining = length
|
68
68
|
|
69
69
|
acquire_ownership :r
|
@@ -97,7 +97,7 @@ module Celluloid
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def readpartial(length, buffer = nil)
|
100
|
-
buffer ||= ''
|
100
|
+
buffer ||= ''.force_encoding(Encoding::ASCII_8BIT)
|
101
101
|
|
102
102
|
begin
|
103
103
|
read_nonblock(length, buffer)
|
@@ -136,7 +136,11 @@ module Celluloid
|
|
136
136
|
|
137
137
|
total_written
|
138
138
|
end
|
139
|
-
|
139
|
+
|
140
|
+
def <<(string)
|
141
|
+
write string
|
142
|
+
self
|
143
|
+
end
|
140
144
|
end
|
141
145
|
end
|
142
146
|
end
|
data/lib/celluloid/io/mailbox.rb
CHANGED
@@ -5,8 +5,8 @@ module Celluloid
|
|
5
5
|
attr_reader :reactor
|
6
6
|
|
7
7
|
def initialize(reactor = nil)
|
8
|
-
|
9
|
-
@
|
8
|
+
super()
|
9
|
+
# @condition won't be used in the class.
|
10
10
|
@reactor = reactor || Reactor.new
|
11
11
|
end
|
12
12
|
|
@@ -26,7 +26,7 @@ module Celluloid
|
|
26
26
|
@messages << message
|
27
27
|
end
|
28
28
|
|
29
|
-
current_actor = Thread.current[:
|
29
|
+
current_actor = Thread.current[:celluloid_actor]
|
30
30
|
@reactor.wakeup unless current_actor && current_actor.mailbox == self
|
31
31
|
rescue IOError
|
32
32
|
raise MailboxError, "dead recipient"
|
data/lib/celluloid/io/reactor.rb
CHANGED
@@ -29,14 +29,14 @@ module Celluloid
|
|
29
29
|
# Wait for the given IO operation to complete
|
30
30
|
def wait(io, set)
|
31
31
|
# zomg ugly type conversion :(
|
32
|
-
unless io.is_a?(::IO)
|
32
|
+
unless io.is_a?(::IO) or io.is_a?(OpenSSL::SSL::SSLSocket)
|
33
33
|
if io.respond_to? :to_io
|
34
34
|
io = io.to_io
|
35
35
|
elsif ::IO.respond_to? :try_convert
|
36
36
|
io = ::IO.try_convert(io)
|
37
37
|
end
|
38
38
|
|
39
|
-
raise TypeError, "can't convert #{io.class} into IO" unless io.is_a?
|
39
|
+
raise TypeError, "can't convert #{io.class} into IO" unless io.is_a?(::IO)
|
40
40
|
end
|
41
41
|
|
42
42
|
monitor = @selector.register(io, set)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Celluloid
|
4
|
+
module IO
|
5
|
+
# SSLServer wraps a TCPServer to provide immediate SSL accept
|
6
|
+
class SSLServer
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :@tcp_server, :listen, :shutdown, :close, :closed?, :to_io, :evented?
|
9
|
+
|
10
|
+
attr_accessor :start_immediately
|
11
|
+
attr_reader :tcp_server
|
12
|
+
|
13
|
+
def initialize(server, ctx)
|
14
|
+
if server.is_a?(::TCPServer)
|
15
|
+
server = Celluloid::IO::TCPServer.from_ruby_server(server)
|
16
|
+
end
|
17
|
+
@tcp_server = server
|
18
|
+
@ctx = ctx
|
19
|
+
@start_immediately = true
|
20
|
+
end
|
21
|
+
|
22
|
+
def accept
|
23
|
+
sock = @tcp_server.accept
|
24
|
+
begin
|
25
|
+
ssl = Celluloid::IO::SSLSocket.new(sock, @ctx)
|
26
|
+
ssl.accept if @start_immediately
|
27
|
+
ssl
|
28
|
+
rescue SSLError
|
29
|
+
sock.close
|
30
|
+
raise
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
3
|
+
module Celluloid
|
4
|
+
module IO
|
5
|
+
# SSLSocket with Celluloid::IO support
|
6
|
+
class SSLSocket
|
7
|
+
include CommonMethods
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
def_delegators :@socket, :read_nonblock, :write_nonblock, :close, :closed?,
|
11
|
+
:cert, :cipher, :client_ca, :peer_cert, :peer_cert_chain, :verify_result
|
12
|
+
|
13
|
+
def initialize(io, ctx = OpenSSL::SSL::SSLContext.new)
|
14
|
+
@context = ctx
|
15
|
+
@socket = OpenSSL::SSL::SSLSocket.new(::IO.try_convert(io), @context)
|
16
|
+
end
|
17
|
+
|
18
|
+
def connect
|
19
|
+
@socket.connect_nonblock
|
20
|
+
rescue ::IO::WaitReadable
|
21
|
+
wait_readable
|
22
|
+
retry
|
23
|
+
end
|
24
|
+
|
25
|
+
def accept
|
26
|
+
@socket.accept_nonblock
|
27
|
+
self
|
28
|
+
rescue ::IO::WaitReadable
|
29
|
+
wait_readable
|
30
|
+
retry
|
31
|
+
rescue ::IO::WaitWritable
|
32
|
+
wait_writable
|
33
|
+
retry
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_io; @socket; end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -5,14 +5,14 @@ module Celluloid
|
|
5
5
|
# TCPServer with combined blocking and evented support
|
6
6
|
class TCPServer
|
7
7
|
extend Forwardable
|
8
|
-
def_delegators :@server, :listen, :sysaccept, :close, :closed
|
8
|
+
def_delegators :@server, :listen, :sysaccept, :close, :closed?, :addr
|
9
9
|
|
10
10
|
def initialize(hostname, port)
|
11
11
|
@server = ::TCPServer.new(hostname, port)
|
12
12
|
end
|
13
13
|
|
14
14
|
def accept
|
15
|
-
actor = Thread.current[:
|
15
|
+
actor = Thread.current[:celluloid_actor]
|
16
16
|
|
17
17
|
if evented?
|
18
18
|
Celluloid.current_actor.wait_readable @server
|
@@ -32,9 +32,16 @@ module Celluloid
|
|
32
32
|
|
33
33
|
# Are we inside a Celluloid ::IO actor?
|
34
34
|
def evented?
|
35
|
-
actor = Thread.current[:
|
35
|
+
actor = Thread.current[:celluloid_actor]
|
36
36
|
actor && actor.mailbox.is_a?(Celluloid::IO::Mailbox)
|
37
37
|
end
|
38
|
+
|
39
|
+
# Convert a Ruby TCPServer into a Celluloid::IO::TCPServer
|
40
|
+
def self.from_ruby_server(ruby_server)
|
41
|
+
server = allocate
|
42
|
+
server.instance_variable_set(:@server, ruby_server)
|
43
|
+
server
|
44
|
+
end
|
38
45
|
end
|
39
46
|
end
|
40
47
|
end
|
@@ -39,8 +39,6 @@ module Celluloid
|
|
39
39
|
|
40
40
|
# Guess it's not an IP address, so let's try DNS
|
41
41
|
unless @addr
|
42
|
-
# TODO: suppport asynchronous DNS
|
43
|
-
# Even EventMachine doesn't do async DNS by default o_O
|
44
42
|
addrs = Array(DNSResolver.new.resolve(remote_host))
|
45
43
|
raise Resolv::ResolvError, "DNS result has no information for #{remote_host}" if addrs.empty?
|
46
44
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Celluloid
|
4
|
+
module IO
|
5
|
+
# UNIXServer with combined blocking and evented support
|
6
|
+
class UNIXServer
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :@server, :listen, :sysaccept, :close, :closed?
|
9
|
+
|
10
|
+
def self.open(socket_path)
|
11
|
+
self.new(socket_path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(socket_path)
|
15
|
+
@server = ::UNIXServer.new(socket_path)
|
16
|
+
end
|
17
|
+
|
18
|
+
def accept
|
19
|
+
actor = Thread.current[:celluloid_actor]
|
20
|
+
|
21
|
+
if evented?
|
22
|
+
Celluloid.current_actor.wait_readable @server
|
23
|
+
accept_nonblock
|
24
|
+
else
|
25
|
+
Celluloid::IO::UNIXSocket.from_ruby_socket @server.accept
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def accept_nonblock
|
30
|
+
Celluloid::IO::UNIXSocket.from_ruby_socket @server.accept_nonblock
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_io
|
34
|
+
@server
|
35
|
+
end
|
36
|
+
|
37
|
+
# Are we inside a Celluloid ::IO actor?
|
38
|
+
def evented?
|
39
|
+
actor = Thread.current[:celluloid_actor]
|
40
|
+
actor && actor.mailbox.is_a?(Celluloid::IO::Mailbox)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Celluloid
|
4
|
+
module IO
|
5
|
+
# UNIXSocket with combined blocking and evented support
|
6
|
+
class UNIXSocket
|
7
|
+
include CommonMethods
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
def_delegators :@socket, :read_nonblock, :write_nonblock, :close, :closed?, :readline, :puts, :addr
|
11
|
+
|
12
|
+
# Convert a Ruby UNIXSocket into a Celluloid::IO::UNIXSocket
|
13
|
+
def self.from_ruby_socket(ruby_socket)
|
14
|
+
# Some hax here, but whatever ;)
|
15
|
+
socket = allocate
|
16
|
+
socket.instance_variable_set(:@socket, ruby_socket)
|
17
|
+
socket
|
18
|
+
end
|
19
|
+
|
20
|
+
# Open a UNIX connection.
|
21
|
+
def self.open(socket_path, &block)
|
22
|
+
self.new(socket_path, &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Open a UNIX connection.
|
26
|
+
def initialize(socket_path, &block)
|
27
|
+
# FIXME: not doing non-blocking connect
|
28
|
+
@socket = if block
|
29
|
+
::UNIXSocket.open(socket_path, &block)
|
30
|
+
else
|
31
|
+
::UNIXSocket.new(socket_path)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_io
|
36
|
+
@socket
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/celluloid/io/version.rb
CHANGED
data/lib/celluloid/io.rb
CHANGED
@@ -10,13 +10,18 @@ require 'celluloid/io/reactor'
|
|
10
10
|
require 'celluloid/io/tcp_server'
|
11
11
|
require 'celluloid/io/tcp_socket'
|
12
12
|
require 'celluloid/io/udp_socket'
|
13
|
+
require 'celluloid/io/unix_server'
|
14
|
+
require 'celluloid/io/unix_socket'
|
15
|
+
|
16
|
+
require 'celluloid/io/ssl_server'
|
17
|
+
require 'celluloid/io/ssl_socket'
|
13
18
|
|
14
19
|
module Celluloid
|
15
20
|
# Actors with evented IO support
|
16
21
|
module IO
|
17
22
|
def self.included(klass)
|
18
23
|
klass.send :include, Celluloid
|
19
|
-
klass.
|
24
|
+
klass.mailbox_class Celluloid::IO::Mailbox
|
20
25
|
end
|
21
26
|
|
22
27
|
extend Forwardable
|
data/log/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.log
|