bones-rpc 0.0.1
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 +7 -0
- data/.gitignore +17 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bones-rpc.gemspec +29 -0
- data/lib/bones-rpc.rb +2 -0
- data/lib/bones/rpc.rb +23 -0
- data/lib/bones/rpc/adapter.rb +49 -0
- data/lib/bones/rpc/adapter/base.rb +41 -0
- data/lib/bones/rpc/adapter/erlang.rb +28 -0
- data/lib/bones/rpc/adapter/json.rb +23 -0
- data/lib/bones/rpc/adapter/msgpack.rb +52 -0
- data/lib/bones/rpc/adapter/parser.rb +37 -0
- data/lib/bones/rpc/address.rb +167 -0
- data/lib/bones/rpc/cluster.rb +266 -0
- data/lib/bones/rpc/connection.rb +146 -0
- data/lib/bones/rpc/connection/reader.rb +49 -0
- data/lib/bones/rpc/connection/socket.rb +4 -0
- data/lib/bones/rpc/connection/socket/connectable.rb +196 -0
- data/lib/bones/rpc/connection/socket/ssl.rb +35 -0
- data/lib/bones/rpc/connection/socket/tcp.rb +28 -0
- data/lib/bones/rpc/connection/writer.rb +51 -0
- data/lib/bones/rpc/context.rb +48 -0
- data/lib/bones/rpc/errors.rb +33 -0
- data/lib/bones/rpc/failover.rb +38 -0
- data/lib/bones/rpc/failover/disconnect.rb +33 -0
- data/lib/bones/rpc/failover/ignore.rb +31 -0
- data/lib/bones/rpc/failover/retry.rb +39 -0
- data/lib/bones/rpc/future.rb +26 -0
- data/lib/bones/rpc/instrumentable.rb +41 -0
- data/lib/bones/rpc/instrumentable/log.rb +45 -0
- data/lib/bones/rpc/instrumentable/noop.rb +33 -0
- data/lib/bones/rpc/loggable.rb +112 -0
- data/lib/bones/rpc/node.rb +317 -0
- data/lib/bones/rpc/node/registry.rb +32 -0
- data/lib/bones/rpc/parser.rb +114 -0
- data/lib/bones/rpc/parser/buffer.rb +80 -0
- data/lib/bones/rpc/protocol.rb +106 -0
- data/lib/bones/rpc/protocol/acknowledge.rb +82 -0
- data/lib/bones/rpc/protocol/adapter_helper.rb +164 -0
- data/lib/bones/rpc/protocol/binary_helper.rb +431 -0
- data/lib/bones/rpc/protocol/ext_message.rb +86 -0
- data/lib/bones/rpc/protocol/notify.rb +38 -0
- data/lib/bones/rpc/protocol/request.rb +45 -0
- data/lib/bones/rpc/protocol/response.rb +58 -0
- data/lib/bones/rpc/protocol/synchronize.rb +70 -0
- data/lib/bones/rpc/read_preference.rb +43 -0
- data/lib/bones/rpc/read_preference/nearest.rb +57 -0
- data/lib/bones/rpc/read_preference/selectable.rb +81 -0
- data/lib/bones/rpc/readable.rb +57 -0
- data/lib/bones/rpc/session.rb +195 -0
- data/lib/bones/rpc/uri.rb +222 -0
- data/lib/bones/rpc/version.rb +6 -0
- metadata +198 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4f7529f76c8f4902d50e0c9f3c300c7fd5a94c67
|
4
|
+
data.tar.gz: b5b201099c32bb8641955f0b90ce11681153df4c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d41c7548cda95b8bdf7f385099e7adb267f4fb9cc7aa17287aceb00c0c5c3dfd8116436967ce121364b692dd2b642831bac693b6d9239d6158dbb2ebc508ef31
|
7
|
+
data.tar.gz: 056db3be7bbd457c18844d0ebf643b19caad4ed4e821ab216763ff1b8b15fb0090e296ea4f5e18b16324264165eed5fd55a514d895459de08e1c318cab33f3f3
|
data/.gitignore
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
bones
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.0.0
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Andrew Bennett
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Bones::RPC
|
2
|
+
|
3
|
+
Bones::RPC client for ruby
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'bones-rpc'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install bones-rpc
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bones-rpc.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bones/rpc/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "bones-rpc"
|
8
|
+
spec.version = Bones::RPC::VERSION
|
9
|
+
spec.authors = ["Andrew Bennett"]
|
10
|
+
spec.email = ["andrew@delorum.com"]
|
11
|
+
spec.description = %q{Bones::RPC client for ruby}
|
12
|
+
spec.summary = %q{Bones::RPC client for ruby}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "celluloid"
|
22
|
+
spec.add_dependency "celluloid-io"
|
23
|
+
spec.add_dependency "erlang-etf"
|
24
|
+
spec.add_dependency "msgpack"
|
25
|
+
spec.add_dependency "optionable"
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
28
|
+
spec.add_development_dependency "rake"
|
29
|
+
end
|
data/lib/bones-rpc.rb
ADDED
data/lib/bones/rpc.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'logger'
|
3
|
+
require 'stringio'
|
4
|
+
require 'monitor'
|
5
|
+
require 'timeout'
|
6
|
+
require 'celluloid/io'
|
7
|
+
require 'optionable'
|
8
|
+
require 'bones/rpc/errors'
|
9
|
+
require 'bones/rpc/loggable'
|
10
|
+
require 'bones/rpc/uri'
|
11
|
+
require 'bones/rpc/adapter'
|
12
|
+
require 'bones/rpc/parser'
|
13
|
+
require 'bones/rpc/protocol'
|
14
|
+
require 'bones/rpc/session'
|
15
|
+
require 'bones/rpc/version'
|
16
|
+
|
17
|
+
module Bones
|
18
|
+
module RPC
|
19
|
+
extend Loggable
|
20
|
+
|
21
|
+
FutureValue = Struct.new(:value)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Bones
|
3
|
+
module RPC
|
4
|
+
module Adapter
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def get(adapter_name)
|
8
|
+
adapters[adapter_name] || raise(Errors::InvalidAdapter, "Unknown adapter #{adapter_name.inspect}")
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_by_ext_head(head)
|
12
|
+
ext_heads[head] || raise(Errors::InvalidExtMessage, "Unknown adapter for ext head #{head.inspect}")
|
13
|
+
end
|
14
|
+
|
15
|
+
def register(adapter)
|
16
|
+
adapter.send(:attr_reader, :adapter_name)
|
17
|
+
adapter.send(:include, Adapter::Base)
|
18
|
+
adapter.send(:extend, adapter)
|
19
|
+
adapters[adapter] ||= adapter
|
20
|
+
adapters[adapter.adapter_name] ||= adapter
|
21
|
+
adapters[adapter.adapter_name.to_s] ||= adapter
|
22
|
+
return adapter
|
23
|
+
end
|
24
|
+
|
25
|
+
def register_ext_head(adapter, head)
|
26
|
+
ext_heads[head] ||= adapter
|
27
|
+
return adapter
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def adapters
|
33
|
+
@adapters ||= {}
|
34
|
+
end
|
35
|
+
|
36
|
+
def ext_heads
|
37
|
+
@ext_heads ||= {}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
require 'bones/rpc/adapter/parser'
|
44
|
+
|
45
|
+
require 'bones/rpc/adapter/base'
|
46
|
+
|
47
|
+
require 'bones/rpc/adapter/erlang'
|
48
|
+
require 'bones/rpc/adapter/json'
|
49
|
+
require 'bones/rpc/adapter/msgpack'
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Bones
|
3
|
+
module RPC
|
4
|
+
module Adapter
|
5
|
+
module Base
|
6
|
+
|
7
|
+
def adapter_name
|
8
|
+
raise NotImplementedError, "Adapter #{self.name} does not implement #adapter_name"
|
9
|
+
end
|
10
|
+
|
11
|
+
def deserialize(buffer = "")
|
12
|
+
if buffer.is_a?(String)
|
13
|
+
buffer = StringIO.new(buffer)
|
14
|
+
end
|
15
|
+
unpack(buffer)
|
16
|
+
end
|
17
|
+
|
18
|
+
def pack(message, buffer = "")
|
19
|
+
raise NotImplementedError, "Adapter #{self.name} does not implement #pack"
|
20
|
+
end
|
21
|
+
|
22
|
+
def packer(buffer)
|
23
|
+
raise NotImplementedError, "Adapter #{self.name} does not implement #packer"
|
24
|
+
end
|
25
|
+
|
26
|
+
def serialize(message, buffer = "")
|
27
|
+
pack(message, buffer)
|
28
|
+
end
|
29
|
+
|
30
|
+
def unpack(buffer)
|
31
|
+
raise NotImplementedError, "Adapter #{self.name} does not implement #unpack"
|
32
|
+
end
|
33
|
+
|
34
|
+
def unpacker(buffer)
|
35
|
+
raise NotImplementedError, "Adapter #{self.name} does not implement #unpacker"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'erlang/etf'
|
3
|
+
|
4
|
+
module Bones
|
5
|
+
module RPC
|
6
|
+
module Adapter
|
7
|
+
module Erlang
|
8
|
+
|
9
|
+
@adapter_name = :erlang
|
10
|
+
|
11
|
+
def pack(message, buffer="")
|
12
|
+
data = ::Erlang.term_to_binary(message)
|
13
|
+
len = data.bytesize
|
14
|
+
buffer << [len].pack('N')
|
15
|
+
buffer << data
|
16
|
+
end
|
17
|
+
|
18
|
+
def unpack(buffer)
|
19
|
+
len, = buffer.read(4).unpack('N')
|
20
|
+
data = buffer.read(len)
|
21
|
+
::Erlang.binary_to_term(data)
|
22
|
+
end
|
23
|
+
|
24
|
+
Adapter.register self
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Bones
|
5
|
+
module RPC
|
6
|
+
module Adapter
|
7
|
+
module JSON
|
8
|
+
|
9
|
+
@adapter_name = :json
|
10
|
+
|
11
|
+
def pack(message, buffer="")
|
12
|
+
buffer << ::JSON.dump(message)
|
13
|
+
end
|
14
|
+
|
15
|
+
def unpack(buffer)
|
16
|
+
::JSON.load(buffer)
|
17
|
+
end
|
18
|
+
|
19
|
+
Adapter.register self
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'msgpack'
|
3
|
+
|
4
|
+
module Bones
|
5
|
+
module RPC
|
6
|
+
module Adapter
|
7
|
+
module MessagePack
|
8
|
+
|
9
|
+
@adapter_name = :msgpack
|
10
|
+
|
11
|
+
def pack(message, buffer="")
|
12
|
+
buffer << ::MessagePack.pack(message)
|
13
|
+
end
|
14
|
+
|
15
|
+
def unpack(buffer)
|
16
|
+
::MessagePack.unpack(buffer)
|
17
|
+
end
|
18
|
+
|
19
|
+
def unpack_stream(stream)
|
20
|
+
buffer = StringIO.new(stream)
|
21
|
+
::MessagePack::Unpacker.new(buffer).read
|
22
|
+
end
|
23
|
+
|
24
|
+
def read(unpacker)
|
25
|
+
(unpacker.adapter_unpacker ||= ::MessagePack::Unpacker.new(unpacker.buffer)).read
|
26
|
+
end
|
27
|
+
|
28
|
+
def unpacker(data)
|
29
|
+
::MessagePack::Unpacker.new(StringIO.new(data))
|
30
|
+
end
|
31
|
+
|
32
|
+
def parser(data)
|
33
|
+
Adapter::Parser.new(self, data)
|
34
|
+
end
|
35
|
+
|
36
|
+
def unpacker_pos(parser)
|
37
|
+
size = parser.unpacker.buffer.size
|
38
|
+
pos = parser.unpacker.buffer.io.pos
|
39
|
+
(pos > size) ? (pos - size) : 0
|
40
|
+
end
|
41
|
+
|
42
|
+
def unpacker_seek(parser, n)
|
43
|
+
pos = unpacker_pos(parser)
|
44
|
+
parser.unpacker.buffer.skip(n - pos) if pos < n
|
45
|
+
return pos
|
46
|
+
end
|
47
|
+
|
48
|
+
Adapter.register self
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Bones
|
3
|
+
module RPC
|
4
|
+
module Adapter
|
5
|
+
class Parser
|
6
|
+
|
7
|
+
attr_reader :adaper, :data
|
8
|
+
|
9
|
+
def initialize(adapter, data)
|
10
|
+
@adapter = Adapter.get(adapter)
|
11
|
+
@data = data
|
12
|
+
end
|
13
|
+
|
14
|
+
def packer
|
15
|
+
@packer ||= @adapter.packer(data)
|
16
|
+
end
|
17
|
+
|
18
|
+
def read
|
19
|
+
unpacker.read
|
20
|
+
end
|
21
|
+
|
22
|
+
def unpacker_seek(n)
|
23
|
+
@adapter.unpacker_seek(self, n)
|
24
|
+
end
|
25
|
+
|
26
|
+
def unpacker
|
27
|
+
@unpacker ||= @adapter.unpacker(data)
|
28
|
+
end
|
29
|
+
|
30
|
+
def unpacker_pos
|
31
|
+
@adapter.unpacker_pos(self)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Bones
|
3
|
+
module RPC
|
4
|
+
|
5
|
+
# Encapsulates behaviour around addresses and resolving dns.
|
6
|
+
#
|
7
|
+
# @since 2.0.0
|
8
|
+
class Address
|
9
|
+
|
10
|
+
# @!attribute host
|
11
|
+
# @return [ String ] The host name.
|
12
|
+
# @!attribute ip
|
13
|
+
# @return [ String ] The ip address.
|
14
|
+
# @!attribute original
|
15
|
+
# @return [ String ] The original host name.
|
16
|
+
# @!attribute port
|
17
|
+
# @return [ Integer ] The port.
|
18
|
+
# @!attribute resolved
|
19
|
+
# @return [ String ] The full resolved address.
|
20
|
+
attr_reader :host, :ip, :original, :path, :port
|
21
|
+
|
22
|
+
# Instantiate the new address.
|
23
|
+
#
|
24
|
+
# @example Instantiate the address.
|
25
|
+
# Bones::RPC::Address.new("localhost:27017")
|
26
|
+
#
|
27
|
+
# @param [ String ] address The host:port pair as a string.
|
28
|
+
#
|
29
|
+
# @since 2.0.0
|
30
|
+
def initialize(address, port = nil)
|
31
|
+
if address.is_a?(Bones::RPC::Address)
|
32
|
+
@host = address.host
|
33
|
+
@ip = address.ip
|
34
|
+
@original = address.original
|
35
|
+
@port = address.port
|
36
|
+
@path = address.path
|
37
|
+
return
|
38
|
+
end
|
39
|
+
|
40
|
+
if port.nil?
|
41
|
+
@original = address
|
42
|
+
else
|
43
|
+
@original = "#{address}:#{port}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def inspect
|
48
|
+
"<#{self.class} \"#{to_s}\">"
|
49
|
+
end
|
50
|
+
|
51
|
+
def ipv4?
|
52
|
+
ip.is_a?(Resolv::IPv4)
|
53
|
+
end
|
54
|
+
|
55
|
+
def ipv6?
|
56
|
+
ip.is_a?(Resolv::IPv6)
|
57
|
+
end
|
58
|
+
|
59
|
+
def resolved
|
60
|
+
if valid?
|
61
|
+
if unix?
|
62
|
+
"unix:#{path}"
|
63
|
+
else
|
64
|
+
host_string = ipv6? ? "[#{ip}]" : ip.to_s
|
65
|
+
[host_string, port].join(':')
|
66
|
+
end
|
67
|
+
else
|
68
|
+
original
|
69
|
+
end
|
70
|
+
end
|
71
|
+
alias_method :to_s, :resolved
|
72
|
+
|
73
|
+
def unix?
|
74
|
+
path.is_a?(String)
|
75
|
+
end
|
76
|
+
|
77
|
+
def valid?
|
78
|
+
unix? or (valid_ip? and valid_port?)
|
79
|
+
end
|
80
|
+
alias_method :connectable?, :valid?
|
81
|
+
|
82
|
+
def valid_ip?
|
83
|
+
ipv4? or ipv6?
|
84
|
+
end
|
85
|
+
|
86
|
+
def valid_port?
|
87
|
+
!port.nil? && port != 0
|
88
|
+
end
|
89
|
+
|
90
|
+
# Resolve the address for the provided node. If the address cannot be
|
91
|
+
# resolved the node will be flagged as down.
|
92
|
+
#
|
93
|
+
# @example Resolve the address.
|
94
|
+
# address.resolve(node)
|
95
|
+
#
|
96
|
+
# @param [ Node ] node The node to resolve for.
|
97
|
+
#
|
98
|
+
# @return [ String ] The resolved address.
|
99
|
+
#
|
100
|
+
# @since 2.0.0
|
101
|
+
def resolve(node)
|
102
|
+
begin
|
103
|
+
resolve! unless valid?
|
104
|
+
valid?
|
105
|
+
rescue Resolv::ResolvError, SocketError => e
|
106
|
+
node.instrument(Node::WARN, prefix: " BONES-RPC:", message: "Could not resolve IP or UNIX path for: #{original}")
|
107
|
+
node.down and false
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def resolve!
|
112
|
+
address = @original
|
113
|
+
|
114
|
+
host = nil
|
115
|
+
path = nil
|
116
|
+
|
117
|
+
if address.is_a?(String) && port.nil?
|
118
|
+
if !!(address =~ /\Aunix:/) # UNIX
|
119
|
+
path = address.gsub(/\Aunix:/, '')
|
120
|
+
elsif !!(address =~ /\A\[.+\]\:\d+\z/) # IPv6
|
121
|
+
host, port = address.split(']:')
|
122
|
+
host.gsub!(/\A\[/, '')
|
123
|
+
else # IPv4 (hopefully)
|
124
|
+
host, port = address.split(':')
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
if path
|
129
|
+
# Ensure path is valid
|
130
|
+
@path = ::Socket.unpack_sockaddr_un(::Socket.pack_sockaddr_un(path))
|
131
|
+
return
|
132
|
+
elsif port.nil?
|
133
|
+
raise ArgumentError, "wrong number of arguments (1 for 2)"
|
134
|
+
else
|
135
|
+
@host = host || address
|
136
|
+
@port = port.to_i
|
137
|
+
end
|
138
|
+
|
139
|
+
# Is it an IPv4 address?
|
140
|
+
if !!(Resolv::IPv4::Regex =~ @host)
|
141
|
+
@ip = Resolv::IPv4.create(@host)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Guess it's not IPv4! Is it IPv6?
|
145
|
+
unless @ip
|
146
|
+
if !!(Resolv::IPv6::Regex =~ @host)
|
147
|
+
@original = "[#{@host}]:#{@port}"
|
148
|
+
@ip = Resolv::IPv6.create(@host)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Guess it's not an IP address, so let's try DNS
|
153
|
+
unless @ip
|
154
|
+
addrs = Array(::Celluloid::IO::DNSResolver.new.resolve(@host))
|
155
|
+
raise Resolv::ResolvError, "DNS result has no information for #{@host}" if addrs.empty?
|
156
|
+
|
157
|
+
# Pseudorandom round-robin DNS support :/
|
158
|
+
@ip = addrs[rand(addrs.size)]
|
159
|
+
end
|
160
|
+
|
161
|
+
if !valid_ip?
|
162
|
+
raise ArgumentError, "unsupported address class: #{@ip.class}"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|