Sha256: 0281f4bc254820d954a4d61caf8009185b98cb05c436557cf027fa4ca4f5c4e6

Contents?: true

Size: 1.45 KB

Versions: 1

Compression:

Stored size: 1.45 KB

Contents

# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2023, by Samuel Williams.

require_relative 'address_endpoint'

module IO::Endpoint
	# This class doesn't exert ownership over the specified unix socket and ensures exclusive access by using `flock` where possible.
	class UNIXEndpoint < AddressEndpoint
		def initialize(path, type = Socket::SOCK_STREAM, **options)
			# I wonder if we should implement chdir behaviour in here if path is longer than 104 characters.
			super(Address.unix(path, type), **options)
			
			@path = path
		end
		
		def to_s
			"\#<#{self.class} #{@path.inspect}>"
		end
		
		attr :path
		
		def bound?
			self.connect do
				return true
			end
		rescue Errno::ECONNREFUSED
			return false
		end
		
		def bind(&block)
			super
		rescue Errno::EADDRINUSE
			# If you encounter EADDRINUSE from `bind()`, you can check if the socket is actually accepting connections by attempting to `connect()` to it. If the socket is still bound by an active process, the connection will succeed. Otherwise, it should be safe to `unlink()` the path and try again.
			if !bound? && File.exist?(@path)
				File.unlink(@path)
				retry
			else
				raise
			end
		end
	end
	
	# @param path [String]
	# @param type Socket type
	# @param options keyword arguments passed through to {UNIXEndpoint#initialize}
	#
	# @return [UNIXEndpoint]
	def self.unix(path = "", type = ::Socket::SOCK_STREAM, **options)
		UNIXEndpoint.new(path, type, **options)
	end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
io-endpoint-0.1.0 lib/io/endpoint/unix_endpoint.rb