ngmoco / cache-money

A Write-Through Cacheing Library for ActiveRecord
Apache License 2.0
161 stars 31 forks source link

undefined method `<=>' error #5

Closed feurio closed 14 years ago

feurio commented 14 years ago

For most parts of my rails application cache-money works really nice.

But how do I solve this kind of error. Without cache-money I do not have this kind of errors:

NoMethodError (undefined method <=>' for #UserActivity:0x1072c9b58): /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cash/index.rb:124:inadd_object_to_cache' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cash/index.rb:123:in sort' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cash/index.rb:123:inadd_object_to_cache' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cash/index.rb:161:in update_index_with_minimal_network_operations' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cash/index.rb:31:inupdate' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cash/write_through.rb:60:in update_caches' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cash/write_through.rb:60:ineach' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cash/write_through.rb:60:in update_caches' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cash/write_through.rb:48:insend' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cash/write_through.rb:48:in unfold' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cash/write_through.rb:26:inupdate_caches' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cache_money.rb:52:in transaction_without_trace_ActiveRecord_self_name_transaction' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cash/transactional.rb:13:intransaction' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cache_money.rb:52:in transaction_without_trace_ActiveRecord_self_name_transaction' /Library/Ruby/Gems/1.8/gems/newrelic_rpm-2.12.3/lib/new_relic/agent/method_tracer.rb:319:intransaction' /Library/Ruby/Gems/1.8/gems/newrelic_rpm-2.12.3/lib/new_relic/agent/method_tracer.rb:141:in trace_execution_scoped' /Library/Ruby/Gems/1.8/gems/newrelic_rpm-2.12.3/lib/new_relic/agent/method_tracer.rb:314:intransaction' app/models/user_activity.rb:126:in generate_html' app/models/user_activity.rb:108:increate_html' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cache_money.rb:52:in transaction_without_trace_ActiveRecord_self_name_transaction' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cash/transactional.rb:13:intransaction' /Library/Ruby/Gems/1.8/gems/af-cache-money-0.2.10/lib/cache_money.rb:52:in transaction_without_trace_ActiveRecord_self_name_transaction' /Library/Ruby/Gems/1.8/gems/newrelic_rpm-2.12.3/lib/new_relic/agent/method_tracer.rb:319:intransaction' /Library/Ruby/Gems/1.8/gems/newrelic_rpm-2.12.3/lib/new_relic/agent/method_tracer.rb:141:in trace_execution_scoped' /Library/Ruby/Gems/1.8/gems/newrelic_rpm-2.12.3/lib/new_relic/agent/method_tracer.rb:314:intransaction' app/models/activity.rb:151:in `log'

ngmoco commented 14 years ago

Can you provide a test case that exercises this error?

ashleym1972 commented 14 years ago

We actually define this method in our initializer, which now seems stupid, but was a quick work around. I thought I changed the cache-money include to have this method and checking the source I confirmed it. So please send me a test case that shows this error.

feurio commented 14 years ago

It is quite difficult for me to create a test case for this because right now I do not know for certain what causes the error. And it also looks like the error only occurs because of the combination of our models and maybe plugins we use... My first guess was that it might be a problem with polymorphic models, because only models that are part of a polymorphic association seem to have this kind of a problem... Today I tried different versions of cache-money from GitHub. The one I use now is the latest version from ngmoco. After some debugging I know that the problem seems to be in line number 124 of ngmoco-cache-money-0.2.10/lib/cash/index.rb. The error message occurs when the variables a and b are both active records objects. Because both objects do not have the <=> method the no-method-error is thrown... I observed that just before sorting the active records objects the same code gets called several times for arrays with fixnums and the error is not thrown.

I think tomorrow (in Germany) I have to dig a little bit deeper into the code, because right know I only understand where the error happens but do not exactly know why....

feurio commented 14 years ago

OK, after some further investigation I now know a lot more what happened here. First I started my journey with cache-money with the kallen-cache-money gem, which is - as I learned later not actively maintained anymore. The installation instructions are different compared to ngmoco-cache-money.

For both gems it was not clear for me which memcache gems I could use: memcache-client or memcached...

Another problem was that the ActiveRecord models of my rails app I have below vendor/plugins did not work with "is_cached :repository => $cache" that should be added to ActiveRecord. The error message I got was:

ActionView::TemplateError (indices delegated to @cache_config.indices, but @cache_config is nil: Globalize::Backend::Database::Locale(id: integer, code: string, name: string)) on line #14 of app/views/my_cards/index.html.erb: 11: :height => get_slider_height('creation'), 12: :slider_name => 'creation', 13: :cont_name => 'my_cards', 14: :title => t('views.my_cards.index.create_new_card_collection.header'), 15: :description => t('views.my_cards.index.create_new_card_collection.description') 16: }%> 17:

/Library/Ruby/Gems/1.8/gems/ngmoco-cache-money-0.2.10/lib/cash/config.rb:23:in `indices'
/Library/Ruby/Gems/1.8/gems/ngmoco-cache-money-0.2.10/lib/cash/query/abstract.rb:5:in `__send__'
/Library/Ruby/Gems/1.8/gems/ngmoco-cache-money-0.2.10/lib/cash/query/abstract.rb:5:in `indices'
/Library/Ruby/Gems/1.8/gems/ngmoco-cache-money-0.2.10/lib/cash/query/abstract.rb:139:in `indexed_on?'
/Library/Ruby/Gems/1.8/gems/ngmoco-cache-money-0.2.10/lib/cash/query/abstract.rb:73:in `cacheable?'
/Library/Ruby/Gems/1.8/gems/ngmoco-cache-money-0.2.10/lib/cash/query/abstract.rb:24:in `perform'
/Library/Ruby/Gems/1.8/gems/ngmoco-cache-money-0.2.10/lib/cash/query/abstract.rb:7:in `perform'
/Library/Ruby/Gems/1.8/gems/ngmoco-cache-money-0.2.10/lib/cash/finders.rb:24:in `find_every'
app/views/my_cards/index.html.erb:14
app/controllers/application_controller.rb:292:in `render_comuungo'
app/controllers/application_controller.rb:291:in `render_comuungo'
app/controllers/my_cards_controller.rb:49:in `index'

The different combinations of configuration, gems and the models below vendor/plugins led to different errors.

After trial and error the way I got everything working was:

  1. install memcached (0.19.7)
  2. Install ngmoco-cache-money (0.2.10)
  3. Add "config.gem 'memcached'" to environment.rb
  4. Add "config.gem 'ngmoco-cache-money', :lib => "cache_money" to environment.rb
  5. Disable automatic cache-money support for models by removing "is_cached(:repository => $cache)" in the init.rb file of the ngmoco-cache-money gem
  6. Enable cache-money on a per model base by adding "is_cached(:repository => $cache)" to each of my models in app/models.

Now as all seems to work I still have two questions left:

  1. How can I leave the automatic support for all ActiveRecord models alone without blowing up my ActiveRecord models below vendor/plugins?
  2. What is the preferred memcache gem: memcache-client or memcached? Evan Weaver says that memcached is 10 times as fast as the memcache-client? Is this true for cache-money? And is cache-money supporting memcached?

Thanks a lot for all your help!

ashleym1972 commented 14 years ago

Sorry for the delay.

  1. That's a problem. It looks like the plugin is calling an index method that we are over-riding or that cache-money did not load before or after the plugin. It's a strange issue that we ran into, where the cache-money code did not get included in the plugin ActiveRecords. We brought the models out to our code base. It's a problem with the way the objects are patched.
  2. We used memcache-client and found it to be slow and unpredictable. Cache-money supports both through the memcached wrapper.
ashleym1972 commented 14 years ago

You should be able to now disable global active record caching in the memcached.yml file.