Class: Thredded::CollectionToStringsWithCacheRenderer

Inherits:
ActionView::AbstractRenderer
  • Object
show all
Defined in:
lib/thredded/collection_to_strings_with_cache_renderer.rb

Class Attribute Summary collapse

Instance Method Summary collapse

Class Attribute Details

.render_threadsObject

The default number of threads to use for rendering.


9
10
11
# File 'lib/thredded/collection_to_strings_with_cache_renderer.rb', line 9

def render_threads
  @render_threads
end

Instance Method Details

#render_collection_to_strings_with_cache(view_context, collection:, partial:, expires_in:, render_threads: self.class.render_threads, locals: {}, **opts) ⇒ Object

Parameters:

  • view_context
  • collection (Array<T>)
  • partial (String)
  • expires_in (ActiveSupport::Duration)
  • render_threads (Integer) (defaults to: self.class.render_threads)

    the number of threads to use for rendering. This is useful even on MRI ruby for IO-bound operations.

  • locals (Hash) (defaults to: {})

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/thredded/collection_to_strings_with_cache_renderer.rb', line 22

def render_collection_to_strings_with_cache( # rubocop:disable Metrics/ParameterLists
  view_context, collection:, partial:, expires_in:, render_threads: self.class.render_threads, locals: {}, **opts
)
  template = @lookup_context.find_template(partial, [], true, locals, {})
  collection = collection.to_a
  instrument(:collection, identifier: template.identifier, count: collection.size) do |instrumentation_payload|
    return [] if collection.blank?
    keyed_collection = collection.each_with_object({}) do |item, hash|
      key = ActiveSupport::Cache.expand_cache_key(
        view_context.cache_fragment_name(item, virtual_path: template.virtual_path), :views
      )      # #read_multi & #write may require key mutability, Dalli 2.6.0.

      hash[key.frozen? ? key.dup : key] = item
    end
    cache = collection_cache
    cached_partials = cache.read_multi(*keyed_collection.keys)
    instrumentation_payload[:cache_hits] = cached_partials.size if instrumentation_payload

    collection_to_render = keyed_collection.reject { |key, _| cached_partials.key?(key) }.values
    rendered_partials = render_partials(
      view_context,
      collection: collection_to_render, render_threads: render_threads,
      partial: partial, locals: locals, **opts
    ).each

    keyed_collection.map do |cache_key, item|
      [item, cached_partials[cache_key] || rendered_partials.next.tap do |rendered|
        cache.write(cache_key, rendered, expires_in: expires_in)
      end]
    end
  end
end