Closed rience closed 2 years ago
As far as I understand, you're looking for something like this:
# initialize config once
config = MultiTenantConfig.new
using_tenant("a") { config.x } # this return the value for tenant "a"
using_tenant("b") { config.x } # this return the value for tenant "b"
Right?
So, here is how I see it.
An Anyway::Config instance stores the actual values within the #values
Hash and uses #values
reader everywhere.
We can make our values tenant-aware:
class MultiTenantConfig < Anyway::Config
def values
values_for_tenant(Current.tenant)
end
private
def values_for_tenant(name)
return tenant_values[name] if tenant_values.key?(name)
# load new instance of the config in the context of the current tenant
tenant_config = self.class.new
# you can return them all, or merge tenant-dependent values with global,
# or do whatever you want here
tenant_values[name] = tenant_config.values
end
def tenant_values
@tenant_values ||= {}
end
end
This way we cache a config per tenant (lazily).
Thank you - it does work nicely. I have to make some additional modifications - because I wanted to fallback to other sources (i.e. YAML or default values) if these values can't be found in database so I did the following
def values_for_tenant(tenant)
# returning cached values for tenant (if exists)
return tenant_values[tenant.id] if tenant_values.key?(tenant.id)
# getting all config values for tenant and put them in hash
configs = # query db
overrides = configs.to_h do |config|
[config.key.to_sym, config.value]
end.to_h
# caching values for tenant but first merge with general config params (the ones that come from YAML or class defaults)
tenant_values[tenant.id] = method(:values).super_method.call.merge(overrides)
end
I also had to overwrite clear
method. Otherwise it'd cache values for tenants.
def clear
super
tenant_values.clear
end
And it does works great. Thank you for your help.
Is your feature request related to a problem? Please describe.
I'd like to have custom loader that will load config from database. However, this can't be cached because this is multi-tenant system where configuration will change from request to request.
Describe the solution you'd like
Would it be possible to provide custom loader which will be called every time config value is requested.
Describe alternatives you've considered
Reload the whole config each request.