zendesk/asset_host_selection — pull request #2 by ggrossman (2014-05-18 07:07:17+00:00)
Title: Ensure that at most one AssetProvider object is created for a particular settings hash

Suppose one's CDN configuration contained multiple keys pointing to the same settings hash. For instance:

```
provider_settings = {
:cdn => { :domain => 'example.com', :subdomain => 'cdn', :enabled => true, :cdn => true },
:local => { :domain => 'example.com', :subdomain => 'local', :enabled => true, :cdn => false }
}
provider_settings[:default] = provider_settings[:cdn]
provider_settings[:disabled] = provider_settings[:local]
```

The existing code would not recognize that the same settings hash was employed for :cdn and :default, and also for :local and :disabled, and it would create not two AssetProvider objects but four.

The consequence is now it looks like your asset provider pool has 4 providers, when in fact it really only has 2. This will mess up any code that tries to do equality comparisons on the provider list, since there are distinct AssetProvider objects for :cdn and :default even though they are really supposed to be the same thing. Worse, if an operation happens on a provider like setting its enabled flag to false, the duplicate version of the object will probably be missed and will stay enabled.

The fix here is to use a separate hash to track the mapping of settings hash to AssetProvider object. Using this hash, we ensure that we only generate at most one AssetProvider object for any particular settings hash. Equality is tested on basis of object identity, so that if there is another copy of the exact same CDN settings hash, that WILL be regarded as a distinct CDN object, which is probably the intent.