thread_local_var_accessors 0.1.1 → 1.0.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 +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +2 -2
- data/README.md +38 -7
- data/lib/thread_local_var_accessors/version.rb +1 -1
- data/lib/thread_local_var_accessors.rb +86 -6
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44a2d47618384051b762c595994639af0699cde590462760853d3be02a611ffa
|
4
|
+
data.tar.gz: 4d4e3629f6bdfa482e5f080c6576d4a74d465a6b67c567b3c169db87e3b782fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e840c90fd9f096762ee4fd12ba5c4cffc9fb6952af177375327e04395cd9734a572542f1301ada916704daa507c21aaf42d4543d4dd01538e85bdf652a631c34
|
7
|
+
data.tar.gz: 826a2db9381d3f7ab70482b0c866427554e58e4c7d70e238964e34593437add0d276067a21aa2e2775f8b9dc050cf05e99776f56374f330dd2a9e952738ecda7
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
2023-05-04: Version 1.0.0
|
2
|
+
- added support for default values:
|
3
|
+
- renamed `tlv_new` to `tlv_init` (leaving `tlv_new` as an alias)
|
4
|
+
- added new instance methods: `tlv_default`, `tlv_set_default`
|
5
|
+
- updated docs to explain how defaults are cross-threads
|
6
|
+
- updated the README.md
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -49,12 +49,22 @@ becomes very simple:
|
|
49
49
|
timeout # fetches the current TLV value, unique to each thread
|
50
50
|
...
|
51
51
|
self.timeout = 0.5 # stores the TLV value just for this thread
|
52
|
+
|
53
|
+
The `tlv_init` method creates a _new_ TLVar and sets its default value.
|
54
|
+
|
55
|
+
Note that the default value is used when any thread evaluates the instance
|
56
|
+
variable and there has been no thread-specific value assignment.
|
57
|
+
|
58
|
+
The TLV default value is used across *all* threads.
|
59
|
+
|
60
|
+
tlv_init(:timeout, _default_)
|
61
|
+
tlv_init(:timeout) { _default_ }
|
52
62
|
|
53
63
|
Alternative ways to initialize:
|
54
64
|
|
55
65
|
tlv_set(:timeout, 0)
|
56
66
|
|
57
|
-
tlv_set(:timeout) # ensure that @timeout is initialized to an
|
67
|
+
tlv_set(:timeout) # ensure that @timeout is initialized to an TLV
|
58
68
|
@timeout.value = 0
|
59
69
|
|
60
70
|
The following methods are used within the above reader, writer, accessor
|
@@ -105,17 +115,30 @@ Then:
|
|
105
115
|
|
106
116
|
## Usage
|
107
117
|
|
108
|
-
|
118
|
+
To use the class methods, they must be included into the current module or class, with:
|
109
119
|
|
110
|
-
|
111
|
-
|
112
|
-
|
120
|
+
class MyNewClass
|
121
|
+
include ThreadLocalVarAccessors
|
122
|
+
...
|
123
|
+
end
|
124
|
+
|
125
|
+
With the include above, you can use the class methods to declare instance getter and setter methods:
|
126
|
+
|
127
|
+
class MyNewClass
|
128
|
+
include ThreadLocalVarAccessors
|
129
|
+
|
130
|
+
tlv_reader :name1
|
131
|
+
tlv_writer :name2
|
132
|
+
tlv_accessor :name3, :name4
|
133
|
+
|
134
|
+
end
|
113
135
|
|
114
136
|
The above invocations:
|
137
|
+
|
115
138
|
- create reader methods for `name1`, `name3`, and `name4`.
|
116
139
|
- create writer methods for `name2`, `name3`, and `name4`.
|
117
140
|
|
118
|
-
The writer methods accept a value as the second argument, or from the result of an associated block.
|
141
|
+
The writer methods accept a value as the second argument, or from the result of an optional, associated block.
|
119
142
|
|
120
143
|
Note: to use the read-and-operate operators, eg: `+=`, `-=`, `||=`, etc., the object must have both a reader and writer method. In other words, it needs to have been created as an `tlv_accessor`.
|
121
144
|
|
@@ -130,9 +153,17 @@ Alternative block forms:
|
|
130
153
|
tlv_set(name) { |oldval| newval }
|
131
154
|
tlv_set_once(name) { |oldval| newval }
|
132
155
|
|
133
|
-
|
134
156
|
In all cases, the `name` can be a string or symbol, with or without a leading `@`.
|
135
157
|
|
158
|
+
Ultimately, these methods are all doing these basic accesses of the corresponding instance variables:
|
159
|
+
|
160
|
+
@name1 ||= ThreadLocalVar.new
|
161
|
+
@name1.value = per_thread_value
|
162
|
+
...
|
163
|
+
@name1.value # returns the per_thread_value
|
164
|
+
|
165
|
+
If you prefer the style above, then you don't really need these accessor methods.
|
166
|
+
|
136
167
|
### Example Usage
|
137
168
|
|
138
169
|
```ruby
|
@@ -31,18 +31,67 @@
|
|
31
31
|
# becomes very simple:
|
32
32
|
#
|
33
33
|
# tlv_accessor :timeout
|
34
|
-
#
|
34
|
+
#
|
35
|
+
# Create a new TLV instance with an associated default, applied across all threads.
|
36
|
+
#
|
37
|
+
# tlv_init :timeout, default_timeout
|
38
|
+
#
|
39
|
+
# tlv_init :timeout { default_timeout }
|
40
|
+
#
|
41
|
+
#
|
42
|
+
# Reference the current thread value for the TLV variable:
|
43
|
+
#
|
35
44
|
# timeout # fetches the current TLV value, unique to each thread
|
36
|
-
#
|
45
|
+
#
|
46
|
+
# Assign the current thread value for the TLV variable:
|
47
|
+
#
|
37
48
|
# self.timeout = 0.5 # stores the TLV value just for this thread
|
38
49
|
#
|
39
|
-
# Alternative ways to initialize:
|
50
|
+
# Alternative ways to initialize the thread-local value:
|
40
51
|
#
|
41
52
|
# ltv_set(:timeout, 0)
|
42
53
|
#
|
43
54
|
# ltv_set(:timeout) # ensure that @timeout is initialized to an LTV
|
55
|
+
#
|
44
56
|
# @timeout.value = 0
|
45
57
|
#
|
58
|
+
# Each thread-local instance can be independently assigned a value, which defaults
|
59
|
+
# to the _default_ value, or _block_, that was associated with the original
|
60
|
+
# `ThreadLocalVar.new` method. This module also provides an easy way to do this:
|
61
|
+
#
|
62
|
+
# Initializes a TLV on the `@timeout` instance variable with a default value of
|
63
|
+
# 0.15 seconds:
|
64
|
+
#
|
65
|
+
# tlv_init(:timeout, 0.15)
|
66
|
+
#
|
67
|
+
# This does the same, but uses a block (a Proc object) to possibly return a
|
68
|
+
# dynamic default value, as the proc is invoked each time the TLV instance is
|
69
|
+
# evaluted in a Thread.
|
70
|
+
#
|
71
|
+
# tlv_init(:sleep_time) { computed_sleep_time }
|
72
|
+
#
|
73
|
+
# The block-proc is evaluated at the time the default value is needed, not when
|
74
|
+
# the TLV is assigned to the instance variable. In other words, much later
|
75
|
+
# during process, when the instance variable value is evaluated, _that_ is when
|
76
|
+
# the default block is evaluated.
|
77
|
+
#
|
78
|
+
# Note that `tlv_init` does not assign the thread-local value; it assigns the
|
79
|
+
# _instance variable_ to a new TLV with the given default. If any thread
|
80
|
+
# evaluates that instance variable, the default value will be returned unless
|
81
|
+
# and until each thread associates a new, thread-local value with the TLV.
|
82
|
+
#
|
83
|
+
# The default for an existing TLV can be redefined, using either an optional
|
84
|
+
# default value, or an optional default block.
|
85
|
+
#
|
86
|
+
#
|
87
|
+
# tlv_set_default(:timeout, new_default)
|
88
|
+
# tlv_set_default(:timeout) { new_default }
|
89
|
+
#
|
90
|
+
# The default for an existing TLV can also be obtained, independently of the
|
91
|
+
# current thread's local value, if any:
|
92
|
+
#
|
93
|
+
# tlv_default(:timeout)
|
94
|
+
#
|
46
95
|
# The following methods are used within the above reader, writer, accessor
|
47
96
|
# methods:
|
48
97
|
#
|
@@ -86,7 +135,8 @@
|
|
86
135
|
#
|
87
136
|
# Each thread referencing the instance variable, will get the same TLV object,
|
88
137
|
# but when the `.value` method is invoked, each thread will receive the initial
|
89
|
-
# value, or whatever local value may have been assigned subsequently
|
138
|
+
# value, or whatever local value may have been assigned subsequently, or the
|
139
|
+
# default, which is the same across all the threads.
|
90
140
|
#
|
91
141
|
# To obtain the value of such an TLV instance variable, do:
|
92
142
|
#
|
@@ -170,9 +220,39 @@ module ThreadLocalVarAccessors
|
|
170
220
|
end
|
171
221
|
|
172
222
|
# @param [String|Symbol] name the TLV name
|
223
|
+
# @param [Object|nil] default the optional default value
|
224
|
+
# @param [Proc] block the optional associated block
|
173
225
|
# @return [ThreadLocalVar] a new TLV set in the instance variable
|
174
|
-
|
175
|
-
|
226
|
+
# @example Default argument
|
227
|
+
# tlv_init(:ivar, default_value)
|
228
|
+
# @example Default block
|
229
|
+
# tlv_init(:ivar) { default_value }
|
230
|
+
def tlv_init(name, default=nil, &block)
|
231
|
+
instance_variable_set(name.to_ivar, Concurrent::ThreadLocalVar.new(default, &block))
|
232
|
+
end
|
233
|
+
alias tlv_new tlv_init
|
234
|
+
|
235
|
+
# Fetches the default value for the TLVar
|
236
|
+
def tlv_default(name)
|
237
|
+
instance_variable_get(name.to_ivar)&.send(:default)
|
238
|
+
end
|
239
|
+
|
240
|
+
# Sets the default value or block for the TLV _(which is applied across all threads)_
|
241
|
+
def tlv_set_default(name, default=nil, &block)
|
242
|
+
tlv = instance_variable_get(name.to_ivar)
|
243
|
+
if tlv
|
244
|
+
raise ArgumentError, "tlv_set_default: can only use a default or a block, not both" if default && block
|
245
|
+
|
246
|
+
if block
|
247
|
+
tlv.instance_variable_set(:@default_block, block)
|
248
|
+
tlv.instance_variable_set(:@default, nil)
|
249
|
+
else
|
250
|
+
tlv.instance_variable_set(:@default_block, nil)
|
251
|
+
tlv.instance_variable_set(:@default, default)
|
252
|
+
end
|
253
|
+
else
|
254
|
+
tlv_init(name, default, &block)
|
255
|
+
end
|
176
256
|
end
|
177
257
|
|
178
258
|
# @!visibility private
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thread_local_var_accessors
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alan Stebbens
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -199,6 +199,7 @@ executables: []
|
|
199
199
|
extensions: []
|
200
200
|
extra_rdoc_files: []
|
201
201
|
files:
|
202
|
+
- CHANGELOG.md
|
202
203
|
- Gemfile
|
203
204
|
- Gemfile.lock
|
204
205
|
- LICENSE
|