contentful / contentful_model

A lightweight wrapper around the Contentful api gem, to make it behave more like ActiveRecord
MIT License
44 stars 42 forks source link

Infinite loop calling .all, .first, .find and .query on a Contentful model #111

Closed svpersteve closed 6 years ago

svpersteve commented 6 years ago

Hi 😄

I'm trying to render articles from Contentful as a blog and both Rails console and Rails server are hanging when they try to call Article.all, Article.all.load or Article.first.

I've made a new Rails app to isolate what I'm doing and show you what I've done: https://github.com/svpersteve/contentful_articles

I'm not sure if this is a bug or if it's something I've done wrong.

dlitvakb commented 6 years ago

Hi @svpersteve,

By any chance do you have a circular reference between your articles?

This may be the cause of your issue, if you do have a circular reference, there's a few different configuration options you can tweak depending on your needs.

If using caching, then on the initializer add:

config.options = {
  max_include_resolution_depth: THE_DEPTH_YOU_DESIRE # this is most likely 2 if you're linking articles with other articles
}

This will limit the default behaviour of generating a tree 20 levels deep (if reached, in case of circularity, this is reached extremely easy and is extremely slow) of all the relationships present in your content. By limiting this number to the specific value you need, the hydration process becomes extremely fast. This method allows for proper caching, at the cost of a bit slower hydration time and larger memory footprint.

If not using caching (this would generate a stack level too deep error if caching), instead add the following:

config.options = {
  reuse_entries: true
}

This will allow for an unlimited amount of nesting via reference reusing, but will prevent you from being able to cache properly. This method does use less memory and has a faster hydration time.

Hope this helps,

Cheers

svpersteve commented 6 years ago

Ah brilliant, thanks @dlitvakb! It works when I add max_include_resolution_depth.

Just while you're here, do you have an example of what a circular reference between articles on Contentful might look like? As far as I can see they're just articles with fields, I don't see how they're linking to each other.

dlitvakb commented 6 years ago

Hey @svpersteve,

A circular reference looks something like this:

Say you have Entry A and Entry B, each of them have a reference field. A has a link to B, B has a link to A. Therefore, you can traverse the relationship tree like A -> B -> A -> B -> ... -> A indefinitely.

This can be happening on the 1st level of the relationship, or maybe you have A -> B -> C -> A or even a more complex relationship. But in any case, this is generating a circular structure, which may become extremely complex as when hydrating it it can exponentially grow.

Hope this explains the issue a bit better,

Cheers

svpersteve commented 6 years ago

Ah, I think it must be the Twitter cards and/or article authors. Thanks for taking the time to explain @dlitvakb 🙏🏻