From 827c18b47117d1d605d252998ee7d94130c22d2f Mon Sep 17 00:00:00 2001 From: Rolf Schmidt Date: Mon, 13 Dec 2021 13:11:32 +0100 Subject: [PATCH] Performance: Improve exists call function caching and make sure that expensive marschal object copies are reduced where it is not needed. --- app/models/core_workflow/attributes.rb | 30 +++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/app/models/core_workflow/attributes.rb b/app/models/core_workflow/attributes.rb index 5640cf851..c599fcd7b 100644 --- a/app/models/core_workflow/attributes.rb +++ b/app/models/core_workflow/attributes.rb @@ -56,22 +56,42 @@ class CoreWorkflow::Attributes result end - def selected - if @payload['params']['id'] && payload_class.exists?(id: @payload['params']['id']) - result = saved_only + def exists? + return if @payload['params']['id'].blank? + + @exists ||= payload_class.exists?(id: @payload['params']['id']) + end + + def overwritten + + # params loading and preparing is very expensive so cache it + checksum = Digest::MD5.hexdigest(Marshal.dump(@payload['params'])) + return @overwritten[checksum] if @overwritten.present? && @overwritten[checksum] + + @overwritten = {} + @overwritten[checksum] = begin + result = saved_only(dump: true) overwrite_selected(result) + end + end + + def selected + if exists? + overwritten else selected_only end end - def saved_only - return if @payload['params']['id'].blank? + def saved_only(dump: false) + return if !exists? # dont use lookup here because the cache will not # know about new attributes and make crashes @saved_only ||= payload_class.find_by(id: @payload['params']['id']) + return @saved_only if !dump + # we use marshal here because clone still uses references and dup can't # detect changes for the rails object Marshal.load(Marshal.dump(@saved_only))