Class: Async::IO::Endpoint

Inherits:
Object
  • Object
show all
Defined in:
lib/async/io/endpoint.rb,
lib/async/io/ssl_endpoint.rb,
lib/async/io/endpoint/each.rb,
lib/async/io/host_endpoint.rb,
lib/async/io/unix_endpoint.rb,
lib/async/io/socket_endpoint.rb

Overview

Endpoints represent a way of connecting or binding to an address.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**options) ⇒ Endpoint

Returns a new instance of Endpoint.



32
33
34
# File 'lib/async/io/endpoint.rb', line 32

def initialize(**options)
	@options = options.freeze
end

Instance Attribute Details

#optionsObject

Returns the value of attribute options.



44
45
46
# File 'lib/async/io/endpoint.rb', line 44

def options
  @options
end

Class Method Details

.each(specifications, &block) ⇒ Object

Generate a list of endpoints from an array.



47
48
49
50
51
52
53
# File 'lib/async/io/endpoint/each.rb', line 47

def self.each(specifications, &block)
	return to_enum(:each, specifications) unless block_given?
	
	specifications.each do |specification|
		yield try_convert(specification)
	end
end

.parse(string, **options) ⇒ Object

Create an Endpoint instance by URI scheme. The host and port of the URI will be passed to the Endpoint factory method, along with any options.



123
124
125
126
127
# File 'lib/async/io/endpoint.rb', line 123

def self.parse(string, **options)
	uri = URI.parse(string)
	
	self.public_send(uri.scheme, uri.host, uri.port, **options)
end

.socket(socket, **options) ⇒ Object



68
69
70
# File 'lib/async/io/socket_endpoint.rb', line 68

def self.socket(socket, **options)
	SocketEndpoint.new(socket, **options)
end

.ssl(*args, ssl_context: nil, hostname: nil, **options) ⇒ SSLEndpoint

Parameters:

  • args
  • ssl_context (OpenSSL::SSL::SSLContext, nil) (defaults to: nil)
  • hostname (String, nil) (defaults to: nil)
  • options

    keyword arguments passed through to tcp

Returns:



114
115
116
# File 'lib/async/io/ssl_endpoint.rb', line 114

def self.ssl(*args, ssl_context: nil, hostname: nil, **options)
	SSLEndpoint.new(self.tcp(*args, **options), ssl_context: ssl_context, hostname: hostname)
end

.tcp(*args, **options) ⇒ HostEndpoint

Parameters:

  • args

    nodename, service, family, socktype, protocol, flags. ‘socktype` will be set to Socket::SOCK_STREAM.

  • options

    keyword arguments passed on to HostEndpoint#initialize

Returns:



100
101
102
103
104
# File 'lib/async/io/host_endpoint.rb', line 100

def self.tcp(*args, **options)
	args[3] = ::Socket::SOCK_STREAM
	
	HostEndpoint.new(args, **options)
end

.try_convert(specification) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/async/io/endpoint/each.rb', line 30

def self.try_convert(specification)
	if specification.is_a? self
		specification
	elsif specification.is_a? Array
		self.send(*specification)
	elsif specification.is_a? String
		self.parse(specification)
	elsif specification.is_a? ::BasicSocket
		self.socket(specification)
	elsif specification.is_a? Generic
		self.new(specification)
	else
		raise ArgumentError.new("Not sure how to convert #{specification} to endpoint!")
	end
end

.udp(*args, **options) ⇒ HostEndpoint

Parameters:

  • args

    nodename, service, family, socktype, protocol, flags. ‘socktype` will be set to Socket::SOCK_DGRAM.

  • options

    keyword arguments passed on to HostEndpoint#initialize

Returns:



110
111
112
113
114
# File 'lib/async/io/host_endpoint.rb', line 110

def self.udp(*args, **options)
	args[3] = ::Socket::SOCK_DGRAM
	
	HostEndpoint.new(args, **options)
end

.unix(path = "", type = ::Socket::SOCK_STREAM, **options) ⇒ UNIXEndpoint

Parameters:

  • path (String) (defaults to: "")
  • type (defaults to: ::Socket::SOCK_STREAM)

    Socket type

  • options

    keyword arguments passed through to UNIXEndpoint#initialize

Returns:



69
70
71
# File 'lib/async/io/unix_endpoint.rb', line 69

def self.unix(path = "", type = ::Socket::SOCK_STREAM, **options)
	UNIXEndpoint.new(path, type, **options)
end

Instance Method Details

#accept(backlog = Socket::SOMAXCONN, &block) ⇒ Object

Accept connections from the specified endpoint.

Parameters:

  • backlog (Integer) (defaults to: Socket::SOMAXCONN)

    the number of connections to listen for.



89
90
91
92
93
94
95
# File 'lib/async/io/endpoint.rb', line 89

def accept(backlog = Socket::SOMAXCONN, &block)
	bind do |server|
		server.listen(backlog)
		
		server.accept_each(&block)
	end
end

#bound { ... } ⇒ Object

Map all endpoints by invoking ‘#bind`.

Yields:

  • the bound wrapper.



99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/async/io/endpoint.rb', line 99

def bound
	wrappers = []
	
	self.each do |endpoint|
		wrapper = endpoint.bind
		wrappers << wrapper
		
		yield wrapper
	end
	
	return wrappers
ensure
	wrappers.each(&:close) if $!
end

#each {|Endpoint| ... } ⇒ Object

Endpoints sometimes have multiple paths.

Yields:

  • (Endpoint)

    Enumerate all discrete paths as endpoints.



81
82
83
84
85
# File 'lib/async/io/endpoint.rb', line 81

def each
	return to_enum unless block_given?
	
	yield self
end

#hostnameString

Returns The hostname of the bound socket.

Returns:

  • (String)

    The hostname of the bound socket.



47
48
49
# File 'lib/async/io/endpoint.rb', line 47

def hostname
	@options[:hostname]
end

#lingerInteger?

Controls SO_LINGER. The amount of time the socket will stay in the ‘TIME_WAIT` state after being closed.

Returns:

  • (Integer, nil)

    The value for SO_LINGER.



65
66
67
# File 'lib/async/io/endpoint.rb', line 65

def linger
	@options[:linger]
end

#local_addressAddress

Returns the address to bind to before connecting.

Returns:

  • (Address)

    the address to bind to before connecting.



75
76
77
# File 'lib/async/io/endpoint.rb', line 75

def local_address
	@options[:local_address]
end

#reuse_addressBoolean

If ‘SO_REUSEADDR` is enabled on a socket prior to binding it, the socket can be successfully bound unless there is a conflict with another socket bound to exactly the same combination of source address and port. Additionally, when set, binding a socket to the address of an existing socket in `TIME_WAIT` is not an error.

Returns:

  • (Boolean)

    The value for ‘SO_REUSEADDR`.



59
60
61
# File 'lib/async/io/endpoint.rb', line 59

def reuse_address
	@options[:reuse_address]
end

#reuse_portBoolean?

If ‘SO_REUSEPORT` is enabled on a socket, the socket can be successfully bound even if there are existing sockets bound to the same address, as long as all prior bound sockets also had `SO_REUSEPORT` set before they were bound.

Returns:

  • (Boolean, nil)

    The value for ‘SO_REUSEPORT`.



53
54
55
# File 'lib/async/io/endpoint.rb', line 53

def reuse_port
	@options[:reuse_port]
end

#timeoutNumeric

Returns The default timeout for socket operations.

Returns:

  • (Numeric)

    The default timeout for socket operations.



70
71
72
# File 'lib/async/io/endpoint.rb', line 70

def timeout
	@options[:timeout]
end

#with(**options) ⇒ Object



36
37
38
39
40
41
42
# File 'lib/async/io/endpoint.rb', line 36

def with(**options)
	dup = self.dup
	
	dup.options = @options.merge(options)
	
	return dup
end