thread_attr_accessor 0.3.1 → 0.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9799a38f085c32f2cda8a9f59dd80a38306aa949
4
- data.tar.gz: 4e5e96c47926aee33179fa291c6fc6dbf97168e2
3
+ metadata.gz: a4b351b621718a171e16dbddbfc528d221f1d1c3
4
+ data.tar.gz: 35592bc912b26fc5a2f6f9f3039a04433c21b580
5
5
  SHA512:
6
- metadata.gz: c00ade061a7ff933fa3819aa2af0ab04deba068b168ce05501138391da2a350f058424a907fb07d624e179980e753943194f03d6d3d52ae49709f93742037597
7
- data.tar.gz: 8cdacf0a89aa6dc976fffd4acebc39a87338d93a8d583a884ffb68717f34828c8bc53eab7c34018a565719618b9a56e24aae886a0743ca5e2f3348c4797d5852
6
+ metadata.gz: 76a0c55f20268e3a3dab3e19a2d9a4ce76864baec23f4ac2f971010d12b7a61903c4a709041641958ed3f6459c901237bea7d65ed8b9ac37d8ceaffdf46f617d
7
+ data.tar.gz: e7224b12d3a2f1d9b1e9b8f887b15091c14900b50fa1246807401a1ce7f09f57841ddc87f02bc7e87bebb464b9ca9432f692893333e55fca5acc91ae0fefe8a4
data/Gemfile CHANGED
@@ -1,4 +1,9 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem 'pry'
4
+ gem 'pry-doc'
5
+ gem 'pry-byebug'
6
+ gem 'pry-stack_explorer'
7
+
3
8
  # Specify your gem's dependencies in thread_attr_accessor.gemspec
4
9
  gemspec
@@ -0,0 +1,16 @@
1
+ # Ruby doesn't provide a standard way to look up a fiber's parent
2
+
3
+ require 'fiber'
4
+
5
+ class Fiber
6
+ module ParentFiber
7
+ attr_reader :parent_fiber
8
+
9
+ def initialize(&block)
10
+ @parent_fiber = Fiber.current
11
+ super(&block)
12
+ end
13
+ end
14
+
15
+ prepend ParentFiber
16
+ end
@@ -0,0 +1,26 @@
1
+ # Ruby doesn't provide a standard way to access another fiber's variables
2
+
3
+ require 'hamster'
4
+
5
+ class Fiber
6
+ module Storage
7
+ def storage
8
+ @storage ||= Hamster.hash
9
+ end
10
+
11
+ def fiber_variable?(key)
12
+ storage.has_key?(key)
13
+ end
14
+
15
+ def fiber_variable_set(key, value)
16
+ @storage = storage.put(key, value)
17
+ value
18
+ end
19
+
20
+ def fiber_variable_get(key)
21
+ storage.get(key)
22
+ end
23
+ end
24
+
25
+ prepend Storage
26
+ end
@@ -1,5 +1,9 @@
1
+ require 'fiber'
2
+
1
3
  require_relative "thread_attr_accessor/version"
2
4
  require_relative 'core_ext/thread/parent_thread'
5
+ require_relative 'core_ext/fiber/parent_fiber'
6
+ require_relative 'core_ext/fiber/storage'
3
7
 
4
8
  # `extend` this module on your class/module to get per-thread class attribute
5
9
  # accessors. Example:
@@ -24,14 +28,75 @@ module ThreadAttrAccessor
24
28
  "#{base.name}.#{name}"
25
29
  end
26
30
 
31
+ class FiberStorage
32
+ attr_reader :fiber, :thread
33
+ def initialize(fiber = Fiber.current, thread = Thread.current)
34
+ @fiber = fiber
35
+ @thread = thread
36
+ end
37
+
38
+ def [](key)
39
+ fiber.fiber_variable_get(key)
40
+ end
41
+
42
+ def []=(key, value)
43
+ fiber.fiber_variable_set(key, value)
44
+ if fiber.parent_fiber.nil?
45
+ thread.thread_variable_set(key, value)
46
+ end
47
+
48
+ value
49
+ end
50
+
51
+ def has_key?(key)
52
+ fiber.fiber_variable?(key)
53
+ end
54
+ end
55
+
56
+ class ThreadStorage
57
+ attr_reader :thread
58
+ def initialize(thread)
59
+ @thread = thread
60
+ end
61
+
62
+ def [](key)
63
+ thread.thread_variable_get(key)
64
+ end
65
+
66
+ def []=(key, value)
67
+ thread.thread_variable_set(key, value)
68
+ end
69
+
70
+ def has_key?(key)
71
+ !!thread.thread_variable_get(key)
72
+ end
73
+ end
74
+
27
75
  def self.search_in_ancestor_threads(key)
28
- ancestor = Thread.current.parent_thread
76
+ fiber = Fiber.current
77
+ thread = Thread.current
29
78
 
30
- until ancestor.nil? || (ancestor_value = ancestor.thread_variable_get(key))
31
- ancestor = ancestor.parent_thread
79
+ until fiber.nil?
80
+ storage = FiberStorage.new(fiber, thread)
81
+
82
+ if storage.has_key?(key)
83
+ return storage[key]
84
+ else
85
+ fiber = fiber.parent_fiber
86
+ end
87
+ end
88
+
89
+ until thread.nil?
90
+ storage = ThreadStorage.new(thread)
91
+
92
+ if storage.has_key?(key)
93
+ return storage[key]
94
+ else
95
+ thread = thread.parent_thread
96
+ end
32
97
  end
33
98
 
34
- ancestor_value
99
+ nil
35
100
  end
36
101
 
37
102
  def self.extended(base)
@@ -50,7 +115,8 @@ module ThreadAttrAccessor
50
115
  thread_key = ThreadAttrAccessor.thread_accessor_key(self, name)
51
116
 
52
117
  mod.send(:define_method, "#{name}=") do |value|
53
- Thread.current.thread_variable_set(thread_key, value)
118
+ FiberStorage.new[thread_key] = value
119
+ value
54
120
  end
55
121
 
56
122
  if private
@@ -73,17 +139,12 @@ module ThreadAttrAccessor
73
139
 
74
140
  if get_default
75
141
  get_value = ->(thread_key) {
76
- if value = Thread.current.thread_variable_get(thread_key)
77
- value
78
- else
79
- default_value = get_default.call(thread_key)
80
- Thread.current.thread_variable_set(thread_key, default_value)
81
- default_value
82
- end
142
+ storage = FiberStorage.new
143
+ storage[thread_key] ||= get_default.call(thread_key)
83
144
  }
84
145
  else
85
146
  get_value = ->(thread_key) {
86
- Thread.current.thread_variable_get(thread_key)
147
+ FiberStorage.new[thread_key]
87
148
  }
88
149
  end
89
150
 
@@ -1,3 +1,3 @@
1
1
  module ThreadAttrAccessor
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -19,6 +19,9 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = []
20
20
  spec.require_paths = ["lib"]
21
21
 
22
+ spec.add_dependency "hamster", "~> 1.0"
23
+
22
24
  spec.add_development_dependency "bundler", "~> 1.8"
23
25
  spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
24
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thread_attr_accessor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Renato Zannon
@@ -10,6 +10,20 @@ bindir: exe
10
10
  cert_chain: []
11
11
  date: 2015-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hamster
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +52,20 @@ dependencies:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
54
  version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
41
69
  description:
42
70
  email:
43
71
  - zannon@tn.com.br
@@ -54,6 +82,8 @@ files:
54
82
  - Rakefile
55
83
  - bin/console
56
84
  - bin/setup
85
+ - lib/core_ext/fiber/parent_fiber.rb
86
+ - lib/core_ext/fiber/storage.rb
57
87
  - lib/core_ext/thread/parent_thread.rb
58
88
  - lib/thread_attr_accessor.rb
59
89
  - lib/thread_attr_accessor/version.rb
@@ -83,3 +113,4 @@ signing_key:
83
113
  specification_version: 4
84
114
  summary: A thread-aware module-level attr_accessor
85
115
  test_files: []
116
+ has_rdoc: