Module: Card::View::Fetch

Included in:
Card::View
Defined in:
lib/card/view/fetch.rb

Overview

Support context-aware card view caching.

View definitions can contain cache settings that guide whether and how the view should be cached.

Constant Summary collapse

DEPENDENT_CACHE_LEVEL =
{ always: :cache_yield, standard: :yield, never: :stub }.freeze

Instance Method Summary collapse

Instance Method Details

#cache_settingObject

view-specific setting as set in view definition. (always, standard, or never)



64
65
66
# File 'lib/card/view/fetch.rb', line 64

def cache_setting
  format.view_cache_setting requested_view
end

#clean_enough_to_cache?Boolean

altered view requests and altered cards are not cacheable

Returns:

  • (Boolean)


69
70
71
72
73
74
75
# File 'lib/card/view/fetch.rb', line 69

def clean_enough_to_cache?
  requested_view == ok_view &&
    !card.unknown? &&
    !card.db_content_changed?
  # FIXME: might consider other changes as disqualifying, though
  # we should make sure not to disallow caching of virtual cards
end

#dependent_cache_levelObject

DEPENDENT CACHING handling of views rendered within another cached view.



80
81
82
83
84
# File 'lib/card/view/fetch.rb', line 80

def dependent_cache_level
  level = dependent_cache_level_unvalidated
  validate_stub if level == :stub
  level
end

#dependent_cache_level_unvalidatedObject



86
87
88
89
# File 'lib/card/view/fetch.rb', line 86

def dependent_cache_level_unvalidated
  return :yield if ok_view == :too_deep
  dependent_cache_ok? ? dependent_cache_setting : :stub
end

#dependent_cache_ok?Boolean

Returns:

  • (Boolean)


91
92
93
94
95
# File 'lib/card/view/fetch.rb', line 91

def dependent_cache_ok?
  return false unless parent && clean_enough_to_cache?
  return true if normalized_options[:skip_perms]
  dependent_cacheable_permissible?
end

#dependent_cache_settingObject



115
116
117
118
# File 'lib/card/view/fetch.rb', line 115

def dependent_cache_setting
  level = DEPENDENT_CACHE_LEVEL[cache_setting]
  level || raise("unknown cache setting: #{cache_setting}")
end

#dependent_cacheable_permissible?Boolean

Returns:

  • (Boolean)


97
98
99
100
101
102
103
104
# File 'lib/card/view/fetch.rb', line 97

def dependent_cacheable_permissible?
  case permission_task
  when :none                  then true
  when parent.permission_task then true
  when Symbol                 then card.anyone_can?(permission_task)
  else                             false
  end
end

#determine_cache_levelObject

Each of the following represents an accepted value for cache directives on view definitions. eg: view :myview, cache: :standard do ...

  • always - store independent cached view, even if that means double caching. (eg view is inside another one already being cached)
  • standard (default) cache independently or dependently, but don't double cache
  • never don't ever cache this view


32
33
34
35
# File 'lib/card/view/fetch.rb', line 32

def determine_cache_level
  return :yield unless Cardio.config.view_cache
  send "#{caching? ? 'dependent' : 'independent'}_cache_level"
end

#fetch(&block) ⇒ Object

fetching can result in one of three things:

  • simply yielding the initial render call
  • storing or retrieving the render to/from the cache
  • creating a stub within another render (so that the stub may be rendered later)


13
14
15
16
17
18
19
20
21
# File 'lib/card/view/fetch.rb', line 13

def fetch &block
  with_fetch_logging do |cache_level|
    case cache_level
    when :yield       then yield
    when :cache_yield then cache_fetch(&block)
    when :stub        then stub
    end
  end
end

#independent_cache_levelObject

INDEPENDENT CACHING takes place on its own (not within another view being cached)



50
51
52
# File 'lib/card/view/fetch.rb', line 50

def independent_cache_level
  independent_cache_ok? ? :cache_yield : :yield
end

#independent_cache_ok?Boolean

Returns:

  • (Boolean)


54
55
56
57
58
# File 'lib/card/view/fetch.rb', line 54

def independent_cache_ok?
  cache_setting != :never &&
    foreign_live_options.empty? &&
    clean_enough_to_cache?
end

#permission_taskObject

task directly associated with the view in its definition via the "perms" directive



108
109
110
# File 'lib/card/view/fetch.rb', line 108

def permission_task
  @permission_task ||= Card::Format.perms[requested_view] || :read
end

#with_fetch_logging {|cache_level| ... } ⇒ Object

Yields:

  • (cache_level)


37
38
39
40
41
42
43
44
45
# File 'lib/card/view/fetch.rb', line 37

def with_fetch_logging
  cache_level = determine_cache_level
  logging = false # TODO: make configurable
  if logging
    puts "FETCH_VIEW (#{card.name}##{requested_view})" \
         "cache-level = #{cache_level}"
  end
  yield cache_level
end