Skip to content

Commit

Permalink
Use Fiber storage for inheritance/dynamic scope. (#3)
Browse files Browse the repository at this point in the history
* Modernize gem.
  • Loading branch information
ioquatix authored May 2, 2024
1 parent 60eee17 commit 7bee19f
Show file tree
Hide file tree
Showing 18 changed files with 353 additions and 200 deletions.
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ root = true
[*]
indent_style = tab
indent_size = 2

[*.{yml,yaml}]
indent_style = space
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.3"

steps:
- uses: actions/checkout@v4
- 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@v3
with:
name: coverage-${{matrix.os}}-${{matrix.ruby}}
path: .covered.db

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

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

- uses: actions/download-artifact@v3

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

on:
push:
branches:
- main

# 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@v4

- uses: ruby/setup-ruby@v1
with:
ruby-version: "3.3"
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@v3
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@v4
36 changes: 36 additions & 0 deletions .github/workflows/test-external.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
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.1"
- "3.2"
- "3.3"

steps:
- uses: actions/checkout@v4
- 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
24 changes: 15 additions & 9 deletions .github/workflows/development.yml → .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
name: Development
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}}

Expand All @@ -14,12 +21,11 @@ jobs:
- macos

ruby:
- 2.5
- 2.6
- 2.7
- "3.1"
- "3.2"
- "3.3"

experimental: [false]
env: [""]

include:
- os: ubuntu
Expand All @@ -33,12 +39,12 @@ jobs:
experimental: true

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

- name: Run tests
timeout-minutes: 5
run: ${{matrix.env}} bundle exec rspec
timeout-minutes: 10
run: bundle exec bake test
9 changes: 3 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
/.bundle/
/.yardoc
/_yardoc/
/coverage/
/doc/
/pkg/
/spec/reports/
/tmp/
/gems.locked
/.covered.db
/external

# rspec failure tracking
.rspec_status
Expand Down
2 changes: 0 additions & 2 deletions .rspec

This file was deleted.

25 changes: 25 additions & 0 deletions example/request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

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

require_relative '../lib/fiber/local'

require 'securerandom'

module RequestID
extend Fiber::Local
end

Fiber.new do
RequestID.instance = SecureRandom.uuid

pp RequestID.instance

pp Fiber.current

Fiber.new do
pp RequestID.instance
end.resume
end.resume

15 changes: 10 additions & 5 deletions fiber-local.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@ Gem::Specification.new do |spec|
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/fiber-local"

spec.files = Dir.glob('{lib}/**/*', File::FNM_DOTMATCH, base: __dir__)
spec.metadata = {
"source_code_uri" => "https://github.com/socketry/fiber-local.git",
}

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

spec.required_ruby_version = ">= 2.5.0"
spec.required_ruby_version = ">= 3.1"

spec.add_development_dependency "bundler"
spec.add_development_dependency "covered"
spec.add_development_dependency "rspec"
spec.add_dependency "fiber-storage"
end
15 changes: 14 additions & 1 deletion gems.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2020-2024, by Samuel Williams.

source "https://rubygems.org"

gemspec

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

gem "utopia-project"
end

group :test do
gem "sus"
gem "covered"

gem "bake-test"
gem "bake-test-external"
end
45 changes: 16 additions & 29 deletions lib/fiber/local.rb
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
# frozen_string_literal: true

# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# Released under the MIT License.
# Copyright, 2020-2024, by Samuel Williams.

require_relative "local/version"
require 'fiber/storage'

class Fiber
module Local
def self.extended(klass)
instance_attribute_name = klass.name.gsub('::', '_').gsub(/\W/, '').downcase
klass.instance_variable_set(:@instance_attribute_name, instance_attribute_name)
klass.instance_variable_set(:@instance_variable_name, :"@#{instance_attribute_name}")

Thread.attr_accessor(instance_attribute_name)
end

# Instantiate a new thread-local object.
# By default, invokes {new} to generate the instance.
# @returns [Object]
Expand All @@ -34,29 +26,24 @@ def local
# Get the current thread-local instance. Create it if required.
# @returns [Object] The thread-local instance.
def instance
thread = Thread.current
name = self.name

if instance = thread[self.name]
if instance = Fiber[@instance_variable_name]
return instance
end

unless instance = thread.thread_variable_get(name)
thread = Thread.current
unless instance = thread.instance_variable_get(@instance_variable_name)
if instance = self.local
thread.thread_variable_set(name, instance)
thread.instance_variable_set(@instance_variable_name, instance)
end
end

thread[self.name] = instance

return instance
end

# Assigns to the fiber-local instance.
# @parameter instance [Object] The object that will become the thread-local instance.
def instance= instance
thread = Thread.current
thread[self.name] = instance
Fiber[@instance_variable_name] = instance
end
end
end
Loading

0 comments on commit 7bee19f

Please sign in to comment.