Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FEATURE: add interface compatible constant version of thread local var
ThreadLocalVar can be expensive as it spins a thread in finalizers. In some cases consumers may want to swap in a constant value implementations that is very cheap. `Concurrent::ConstantThreadLocalVar` is interface compatible with AbstractThreadLocalVar, however does not allow any changing of .value
- Loading branch information
1 parent
bbeacbc
commit db332e8
Showing
3 changed files
with
92 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
require 'concurrent/atomic/abstract_thread_local_var' | ||
|
||
module Concurrent | ||
class ConstantThreadLocalVar < AbstractThreadLocalVar | ||
def value | ||
default | ||
end | ||
|
||
def value=(value) | ||
if value != default | ||
raise ArgumentError, "Constant thread local vars may not be altered" | ||
end | ||
end | ||
|
||
def bind(value) | ||
self.value = value | ||
if block_given? | ||
yield | ||
end | ||
end | ||
|
||
protected | ||
def allocate_storage | ||
# nothing to do | ||
end | ||
|
||
def default | ||
if @default_block | ||
@default_block.call | ||
else | ||
@default | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
require 'rbconfig' | ||
|
||
module Concurrent | ||
|
||
require 'concurrent/atomic/constant_thread_local_var' | ||
|
||
RSpec.describe ConstantThreadLocalVar do | ||
|
||
context "#value" do | ||
it 'can return default value' do | ||
v = described_class.new("apple") | ||
expect(v.value).to eq("apple") | ||
|
||
v = described_class.new do | ||
"orange" | ||
end | ||
expect(v.value).to eq("orange") | ||
end | ||
end | ||
|
||
context "#value=" do | ||
it 'can set value to same value' do | ||
v = described_class.new("apple") | ||
v.value = "apple" | ||
end | ||
|
||
it 'will raise an ArgumentError when attempting to change immutable value' do | ||
v = described_class.new do | ||
"apple" | ||
end | ||
|
||
expect do | ||
v.value = "orange" | ||
end.to raise_error(ArgumentError) | ||
end | ||
end | ||
|
||
context '#bind' do | ||
it 'will raise when attempting to bind to a different value' do | ||
v = described_class.new("apple") | ||
expect do | ||
v.bind("orange") {} | ||
end.to raise_error(ArgumentError) | ||
end | ||
|
||
it 'works when bind value is the same' do | ||
|
||
v = described_class.new("apple") | ||
v.bind("apple") do | ||
expect(v.value).to eq("apple") | ||
end | ||
end | ||
end | ||
end | ||
|
||
end |