Skip to content

Commit

Permalink
Add Configuration#multi_tenant! for opting into multi-tentant suppo…
Browse files Browse the repository at this point in the history
…rt where configuration is per-thread

This is a follow up to #549 to improve usage in a single tenant scenario
where you might configure NetSuite on the main thread (ie. via Rails
initializer), then make requests in another thread (ie. Sidekiq jobs).

By default we assume single-tenant usage and the configuration is shared
across all threads. If you opt into multi-tenant usage, each child
thread starts with the main thread's configuration, but can then be
further configured without altering other threads.
  • Loading branch information
cgunther committed Aug 18, 2022
1 parent 4a415ce commit 95c6aa6
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
2 changes: 2 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@


### Added
* Add `Configuration#multi_tenant!` for opting into multi-tentant support where configuration is per-thread (#)

### Fixed
### Breaking Changes

Expand Down
11 changes: 10 additions & 1 deletion lib/netsuite/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ def reset!

clear_wsdl_cache

Thread.main[:netsuite_gem_multi_tenant] = false
attributes.clear
end

def attributes
Thread.current[:netsuite_gem_attributes] ||= {}
if Thread.main[:netsuite_gem_multi_tenant]
Thread.current[:netsuite_gem_attributes] ||= (Thread.main[:netsuite_gem_attributes] || {}).dup
else
Thread.main[:netsuite_gem_attributes] ||= {}
end
end

def connection(params={}, credentials={})
Expand Down Expand Up @@ -407,5 +412,9 @@ def proxy(proxy = nil)
attributes[:proxy]
end
end

def multi_tenant!
Thread.main[:netsuite_gem_multi_tenant] = true
end
end
end
22 changes: 21 additions & 1 deletion spec/netsuite/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,31 @@
expect(config.attributes).to be_empty
end

it 'ensures that attributes are not shared between threads' do
it 'treats attributes as shared/global in default single tenant mode' do
config.attributes[:blah] = 'something'
expect(config.attributes[:blah]).to eq('something')

thread = Thread.new {
expect(config.attributes[:blah]).to eq('something')

config.attributes[:blah] = 'something_else'
expect(config.attributes[:blah]).to eq('something_else')
}

thread.join

expect(config.attributes[:blah]).to eq('something_else')
end

it 'treats attributes as thread-local in multi-tenant mode, which each thread starting with the main threads attributes' do
config.multi_tenant!

config.attributes[:blah] = 'something'
expect(config.attributes[:blah]).to eq('something')

thread = Thread.new {
expect(config.attributes[:blah]).to eq('something')

config.attributes[:blah] = 'something_else'
expect(config.attributes[:blah]).to eq('something_else')
}
Expand Down

0 comments on commit 95c6aa6

Please sign in to comment.