thread_attr_accessor 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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: