Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CachedRender#should_render? #27

Open
jgaskins opened this issue Oct 26, 2015 · 2 comments
Open

CachedRender#should_render? #27

jgaskins opened this issue Oct 26, 2015 · 2 comments

Comments

@jgaskins
Copy link
Member

I've noticed when writing cache invalidation for CachedRender components that I frequently have it wrong in my head and I was wondering if anyone else had this trouble. I used the name should_render? based on React's shouldComponentUpdate() function, but I frequently find myself writing the boolean expression for whether the cache is fresh instead of when it is stale. For example:

class TodoList
  include Clearwater::Component
  include Clearwater::CachedRender

  # ...

  def should_render? previous
    todos.equal? previous.todos
  end
end

This is compounded when you have more cache dependencies. Here is an example from an app I've been working on, a real-time food-delivery tracker. It tracks the state of the delivery ("driver is en route to the restaurant", for example) and the driver's location so we can display it on a map.

class DeliveryTracker
  def should_render? previous
    !(
      driver_location.equal?(previous.driver_location) &&
      delivery_status.equal?(previous.delivery_status)
    )
  end
end

Note how I had to wrap the entire boolean expression in !(). This makes me wonder if we should instead use a cache_fresh? method instead (probably not the final name). Is anyone else having this problem? Does anyone else use CachedRender at all?

@balmoral
Copy link

That's a good point. I've found myself using valid? and invalidate! to determine and set cache status.

@jgaskins
Copy link
Member Author

One possibility that sounds really good to me is to just use one of Ruby's equality operators. The idea is that if two components would have the same output, they're equivalent.

Ruby provides 4 different types of equality:

  • ==: The generic "equal" definition, used by include? and the Comparable mixin
  • eql?: Sometimes called "hash equality" because it's what Hash#[] and Hash#fetch use to determine if two keys match.
  • equal?: Identity equivalence. The convention here is that this should only be true if two references point to the same object in memory, so this is probably not a good candidate.
  • ===: "Case equality", used by the case statement as well as Enumerable#grep. I'd probably call this the "match operator" because it can be used to check whether a value falls within a range, a string matches a regex, an object is an instance of a class (or one of its subclasses), etc.

Any of these except equal? are good candidates, in my opinion. I really like the idea of using === at the very least, but I can't come up with a use case where == or eql? would be bad, either.

This can be done in a backward-compatible way so we can deprecate Component#should_render?. However, I don't think it's a good idea to do this for 1.0 since we already have a release candidate. Maybe deprecate it in 1.1 and remove in 2.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants