Skip to content

Commit

Permalink
Initial implementation extracted from async-io.
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed Mar 22, 2023
0 parents commit 96a591d
Show file tree
Hide file tree
Showing 31 changed files with 1,399 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
root = true

[*]
indent_style = tab
indent_size = 2
57 changes: 57 additions & 0 deletions .github/workflows/coverage.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Coverage

on: [push, pull_request]

permissions:
contents: read

env:
CONSOLE_OUTPUT: XTerm
COVERAGE: PartialSummary

jobs:
test:
name: ${{matrix.ruby}} on ${{matrix.os}}
runs-on: ${{matrix.os}}-latest

strategy:
matrix:
os:
- ubuntu
- macos

ruby:
- "3.2"

steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{matrix.ruby}}
bundler-cache: true

- name: Run tests
timeout-minutes: 5
run: bundle exec bake test

- uses: actions/upload-artifact@v2
with:
name: coverage-${{matrix.os}}-${{matrix.ruby}}
path: .covered.db

validate:
needs: test
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: "3.2"
bundler-cache: true

- uses: actions/download-artifact@v3

- name: Validate coverage
timeout-minutes: 5
run: bundle exec bake covered:validate --paths */.covered.db \;
61 changes: 61 additions & 0 deletions .github/workflows/documentation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Documentation

on:
push:
branches:
- main

# Allows you to run this workflow manually from the Actions tab:
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages:
permissions:
contents: read
pages: write
id-token: write

# Allow one concurrent deployment:
concurrency:
group: "pages"
cancel-in-progress: true

env:
CONSOLE_OUTPUT: XTerm
BUNDLE_WITH: maintenance

jobs:
generate:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- uses: ruby/setup-ruby@v1
with:
ruby-version: "3.2"
bundler-cache: true

- name: Installing packages
run: sudo apt-get install wget

- name: Generate documentation
timeout-minutes: 5
run: bundle exec bake utopia:project:static --force no

- name: Upload documentation artifact
uses: actions/upload-pages-artifact@v1
with:
path: docs

deploy:
runs-on: ubuntu-latest

environment:
name: github-pages
url: ${{steps.deployment.outputs.page_url}}

needs: generate
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1
34 changes: 34 additions & 0 deletions .github/workflows/test-external.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Test External

on: [push, pull_request]

permissions:
contents: read

env:
CONSOLE_OUTPUT: XTerm

jobs:
test:
name: ${{matrix.ruby}} on ${{matrix.os}}
runs-on: ${{matrix.os}}-latest

strategy:
matrix:
os:
- ubuntu
- macos

ruby:
- "3.2"

steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{matrix.ruby}}
bundler-cache: true

- name: Run tests
timeout-minutes: 10
run: bundle exec bake test:external
48 changes: 48 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Test

on: [push, pull_request]

permissions:
contents: read

env:
CONSOLE_OUTPUT: XTerm

jobs:
test:
name: ${{matrix.ruby}} on ${{matrix.os}}
runs-on: ${{matrix.os}}-latest
continue-on-error: ${{matrix.experimental}}

strategy:
matrix:
os:
- ubuntu
- macos

ruby:
- "3.2"

experimental: [false]

include:
- os: ubuntu
ruby: truffleruby
experimental: true
- os: ubuntu
ruby: jruby
experimental: true
- os: ubuntu
ruby: head
experimental: true

steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{matrix.ruby}}
bundler-cache: true

- name: Run tests
timeout-minutes: 10
run: bundle exec bake test
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/.bundle/
/pkg/
/gems.locked
/.covered.db
/external
17 changes: 17 additions & 0 deletions fixtures/with_temporary_directory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

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

require 'tmpdir'

module WithTemporaryDirectory
attr :temporary_directory

def around
Dir.mktmpdir do |temporary_directory|
@temporary_directory = temporary_directory
yield
end
end
end
15 changes: 15 additions & 0 deletions gems.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

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

source 'https://rubygems.org'

gemspec

group :maintenance, optional: true do
gem "bake-modernize"
gem "bake-gem"

gem "utopia-project"
end
25 changes: 25 additions & 0 deletions io-endpoint.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

require_relative "lib/io/endpoint/version"

Gem::Specification.new do |spec|
spec.name = "io-endpoint"
spec.version = IO::Endpoint::VERSION

spec.summary = "Provides a separation of concerns interface for IO endpoints."
spec.authors = ["Samuel Williams"]
spec.license = "MIT"

spec.cert_chain = ['release.cert']
spec.signing_key = File.expand_path('~/.gem/release.pem')

spec.homepage = "https://github.com/socketry/io-endpoint"

spec.files = Dir.glob(['{lib}/**/*', '*.md'], File::FNM_DOTMATCH, base: __dir__)

spec.required_ruby_version = ">= 3.2"

spec.add_development_dependency "bake"
spec.add_development_dependency "covered"
spec.add_development_dependency "sus"
end
13 changes: 13 additions & 0 deletions lib/io/endpoint.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

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

require_relative "endpoint/version"
require_relative "endpoint/generic"

module IO::Endpoint
def self.file_descriptor_limit
Process.getrlimit(Process::RLIMIT_NOFILE).first
end
end
38 changes: 38 additions & 0 deletions lib/io/endpoint/address_endpoint.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

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

require 'socket'

require_relative 'generic'
require_relative 'wrapper'

module IO::Endpoint
class AddressEndpoint < Generic
def initialize(address, **options)
super(**options)

@address = address
end

def to_s
"\#<#{self.class} #{@address.inspect}>"
end

attr :address

# Bind a socket to the given address. If a block is given, the socket will be automatically closed when the block exits.
# @yield [Socket] the bound socket
# @return [Socket] the bound socket
def bind(&block)
Wrapper.bind(@address, **@options, &block)
end

# Connects a socket to the given address. If a block is given, the socket will be automatically closed when the block exits.
# @return [Socket] the connected socket
def connect(&block)
Wrapper.connect(@address, **@options, &block)
end
end
end
42 changes: 42 additions & 0 deletions lib/io/endpoint/composite_endpoint.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

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

require_relative 'generic'

module IO::Endpoint
class CompositeEndpoint < Generic
def initialize(endpoints, **options)
super(**options)
@endpoints = endpoints
end

def each(&block)
@endpoints.each(&block)
end

def connect(&block)
last_error = nil

@endpoints.each do |endpoint|
begin
return endpoint.connect(&block)
rescue => last_error
end
end

raise last_error
end

def bind(&block)
@endpoints.map(&:bind)
end
end

class Endpoint
def self.composite(*endpoints, **options)
CompositeEndpoint.new(endpoints, **options)
end
end
end
Loading

0 comments on commit 96a591d

Please sign in to comment.