local-ch / lhc

🚀 Advanced HTTP Client for Ruby. Fueled with interceptors.
GNU General Public License v3.0
43 stars 1 forks source link

DO NOT dup interceptors #115

Closed 10xSebastian closed 6 years ago

10xSebastian commented 6 years ago

In some applications, mainly Salesbutler, we have the problem that the whole log is flooded with:

[WARNING] Can't enable LHS::RequestCycleCache as LHC::Caching interceptor is not enabled/configured (see https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md#caching-interceptor)!

While this warning is actually accurate, the RequestCycleCache is partially not active, which means we loose the benefit of caching the same requests during one request cycle!

The reason why the request cycle cache is partially not working, in this scenario, is the following:

  1. Application makes request using LHS includes: https://github.com/local-ch/sales-butler/blob/master/app/models/customer.rb#L139

  2. LHS includes (auto-loads) additional linked resources: https://github.com/local-ch/lhs/blob/has-many-options/lib/lhs/concerns/record/request.rb#L262

  3. When loading batches, LHS deep_dup options when continue loading batches, to not mess with passed original options, which usually is not the problem: https://github.com/local-ch/lhs/blob/has-many-options/lib/lhs/concerns/record/request.rb#L436

  4. But in the context of the request cycle cache, it's checked if the LHC::Caching interceptor is part of the request options: https://github.com/local-ch/lhs/blob/has-many-options/lib/lhs/concerns/record/request.rb#L461

Which is usually fine:

options[:interceptors] # [LHC::Caching]

But because it's deep_duped during LHS include the interceptor class itself has been duped:

options[:interceptors] # [#<Class:0x007fcde01eb800>]

Which makes the check if the LHC::Caching interceptor is included, fail:

options[:interceptors].include?(LHC::Caching) # false

https://github.com/local-ch/lhs/blob/has-many-options/lib/lhs/concerns/record/request.rb#L461

As the Interceptor classes have flag-character itself, there is no reason to allow duplicating the class itself (everything is an object in ruby).

This PR disallows duplicating interceptor classes.