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
         
     |