diff --git a/test/benchmark/bm_caching.rb b/test/benchmark/bm_caching.rb index 887c3139..48ac97c7 100644 --- a/test/benchmark/bm_caching.rb +++ b/test/benchmark/bm_caching.rb @@ -31,6 +31,10 @@ class ApiAssertion get("/caching/#{on_off}") end + def get_fragment_caching(on_off = 'on'.freeze) + get("/fragment_caching/#{on_off}") + end + def get_non_caching(on_off = 'on'.freeze) get("/non_caching/#{on_off}") end @@ -101,8 +105,10 @@ assertion.debug { assertion.get_status } time = 10 { 'caching on: caching serializers: gc off' => { disable_gc: true, send: [:get_caching, 'on'] }, + 'caching on: fragment caching serializers: gc off' => { disable_gc: true, send: [:get_fragment_caching, 'on'] }, 'caching on: non-caching serializers: gc off' => { disable_gc: true, send: [:get_non_caching, 'on'] }, 'caching off: caching serializers: gc off' => { disable_gc: true, send: [:get_caching, 'off'] }, + 'caching off: fragment caching serializers: gc off' => { disable_gc: true, send: [:get_fragment_caching, 'off'] }, 'caching off: non-caching serializers: gc off' => { disable_gc: true, send: [:get_non_caching, 'off'] } }.each do |label, options| assertion.clear diff --git a/test/benchmark/controllers.rb b/test/benchmark/controllers.rb index e95ab11a..d2c04d55 100644 --- a/test/benchmark/controllers.rb +++ b/test/benchmark/controllers.rb @@ -1,12 +1,13 @@ class PostController < ActionController::Base POST = begin + updated_at = Time.current if ENV['BENCH_STRESS'] comments = (0..50).map do |i| - Comment.new(id: i, body: 'ZOMG A COMMENT') + Comment.new(id: i, body: 'ZOMG A COMMENT', updated_at: updated_at + i) end else - comments = [Comment.new(id: 1, body: 'ZOMG A COMMENT')] + comments = [Comment.new(id: 1, body: 'ZOMG A COMMENT', updated_at: updated_at)] end author = Author.new(id: 42, first_name: 'Joao', last_name: 'Moura') Post.new(id: 1337, title: 'New Post', blog: nil, body: 'Body', comments: comments, author: author) @@ -17,6 +18,11 @@ class PostController < ActionController::Base render json: POST, serializer: CachingPostSerializer, adapter: :json, meta: { caching: perform_caching } end + def render_with_fragment_caching_serializer + toggle_cache_status + render json: POST, serializer: FragmentCachingPostSerializer, adapter: :json, meta: { caching: perform_caching } + end + def render_with_non_caching_serializer toggle_cache_status render json: POST, adapter: :json, meta: { caching: perform_caching } @@ -73,5 +79,6 @@ Rails.application.routes.draw do get '/status(/:on)' => 'post#render_cache_status' get '/clear' => 'post#clear' get '/caching(/:on)' => 'post#render_with_caching_serializer' + get '/fragment_caching(/:on)' => 'post#render_with_fragment_caching_serializer' get '/non_caching(/:on)' => 'post#render_with_non_caching_serializer' end diff --git a/test/benchmark/fixtures.rb b/test/benchmark/fixtures.rb index abe56a42..5242db2a 100644 --- a/test/benchmark/fixtures.rb +++ b/test/benchmark/fixtures.rb @@ -13,7 +13,7 @@ end Rails.configuration.serializers << BlogSerializer class CommentSerializer < ActiveModel::Serializer - attributes :id, :body + attributes :id, :body, :updated_at belongs_to :post belongs_to :author @@ -43,7 +43,7 @@ end Rails.configuration.serializers << PostSerializer class CachingAuthorSerializer < AuthorSerializer - cache key: 'writer', only: [:first_name, :last_name], skip_digest: true + cache key: 'writer', skip_digest: true end Rails.configuration.serializers << CachingAuthorSerializer @@ -58,9 +58,9 @@ class CachingPostSerializer < ActiveModel::Serializer attributes :id, :title, :body - has_many :comments, serializer: CommentSerializer belongs_to :blog, serializer: BlogSerializer - belongs_to :author, serializer: AuthorSerializer + belongs_to :author, serializer: CachingAuthorSerializer + has_many :comments, serializer: CachingCommentSerializer link(:post_authors) { 'https://example.com/post_authors' } @@ -77,6 +77,41 @@ class CachingPostSerializer < ActiveModel::Serializer end Rails.configuration.serializers << CachingPostSerializer +class FragmentCachingAuthorSerializer < AuthorSerializer + cache key: 'writer', only: [:first_name, :last_name], skip_digest: true +end +Rails.configuration.serializers << FragmentCachingAuthorSerializer + +class FragmentCachingCommentSerializer < CommentSerializer + cache expires_in: 1.day, except: [:updated_at], skip_digest: true +end +Rails.configuration.serializers << CachingCommentSerializer + +# see https://github.com/rails-api/active_model_serializers/pull/1690/commits/68715b8f99bc29677e8a47bb3f305f23c077024b#r60344532 +class FragmentCachingPostSerializer < ActiveModel::Serializer + cache key: 'post', expires_in: 0.1, skip_digest: true + + attributes :id, :title, :body + + belongs_to :blog, serializer: BlogSerializer + belongs_to :author, serializer: FragmentCachingAuthorSerializer + has_many :comments, serializer: FragmentCachingCommentSerializer + + link(:post_authors) { 'https://example.com/post_authors' } + + meta do + { + rating: 5, + favorite_count: 10 + } + end + + def blog + Blog.new(id: 999, name: 'Custom blog') + end +end +Rails.configuration.serializers << FragmentCachingPostSerializer + if ENV['ENABLE_ACTIVE_RECORD'] == 'true' require 'active_record' @@ -167,7 +202,7 @@ else end class Comment < BenchmarkModel - attr_accessor :id, :body + attr_accessor :id, :body, :updated_at end class Author < BenchmarkModel