We have a Rails app that responds to multiple TLDs, including subdomains. One of those domains is a .co.uk. domain, therefore the TLD length in that case is 2 (eg: ourapp.es, ourapp.co.uk, api.ourapp.es, api.ourapp.co.uk.
In order to dynamically change the TLD length we've using this Rack middleware:
class Rack::TldLength
def initialize(app, host_pattern, host_tld_length)
@app = app
@host_pattern = Regexp.new(host_pattern)
@host_tld_length = host_tld_length
end
def call(env)
original_tld_length = tld_length
request = Rack::Request.new(env)
set_tld_length(@host_tld_length) if request.host =~ @host_pattern
@app.call(env)
ensure
set_tld_length(original_tld_length)
end
private
def tld_length
ActionDispatch::Http::URL.tld_length
end
def set_tld_length(length)
ActionDispatch::Http::URL.tld_length = length
end
end
This has been working so far until we decided to migrate from Unicorn to puma. With Unicorn each request would go to a different unicorn worker (process) and there was no problem. However with puma each request can be processed by a different thread. We suspect that changing the value ActionDispatch::Http::URL.tld_length is not thread safe, but we're struggling to find an alternative to this.
It seems that the Rails routing (where we define routes with subdomain constraints) depends on setting the ActionDispatch::Http::URL.tld_length properly.
Is there any workaround to keep the concurrency offered by having multiple threads while still being able to handle multiple domains with different TLD lengths?