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 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