thread_local_var_accessors 0.1.1 → 1.0.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
  SHA256:
3
- metadata.gz: 1b6e9d88de11a15e80e03d531bbb506da4b962e057ee1e88f0eb56f79c0eca74
4
- data.tar.gz: 919b3b1100b7d8683317869cda3dbd87672ba6e30a0a86c565fffd0cefadcc99
3
+ metadata.gz: 44a2d47618384051b762c595994639af0699cde590462760853d3be02a611ffa
4
+ data.tar.gz: 4d4e3629f6bdfa482e5f080c6576d4a74d465a6b67c567b3c169db87e3b782fa
5
5
  SHA512:
6
- metadata.gz: 2c1c294e53542491de381e69ff49b9b68942f6d5dc06ef8256f954dbec8af9c23396a4fd995d10701017b790c51880c6928c451c4e521c0b7cef80233af50aba
7
- data.tar.gz: 740127f6247210b11f2ad478005eb459780afa6f50e451416b74a6ac35081d1ab818151b85bab786dd60031f71ee67cc01fc7b45423c454976f66834e000d0e0
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- thread_local_var_accessors (0.1.1)
4
+ thread_local_var_accessors (1.0.0)
5
5
  concurrent-ruby
6
6
 
7
7
  GEM
@@ -87,4 +87,4 @@ DEPENDENCIES
87
87
  yard
88
88
 
89
89
  BUNDLED WITH
90
- 2.4.6
90
+ 2.4.12
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 [TLV](TLV)
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
- Use the class methods to declare instance getter and setter methods:
118
+ To use the class methods, they must be included into the current module or class, with:
109
119
 
110
- tlv_reader :name1
111
- tlv_writer :name2
112
- tlv_accessor :name3, :name4
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
@@ -1,3 +1,3 @@
1
1
  module ThreadLocalVarAccessors
2
- VERSION = '0.1.1'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -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
- def tlv_new(name)
175
- instance_variable_set(name.to_ivar, Concurrent::ThreadLocalVar.new)
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.1.1
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-03-28 00:00:00.000000000 Z
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