lib/scrivito/cms_backend.rb in scrivito_sdk-0.65.2 vs lib/scrivito/cms_backend.rb in scrivito_sdk-0.66.0.rc1
- old
+ new
@@ -88,34 +88,40 @@
@query_counter = 0
end
def find_workspace_data_by_id(id)
if die_content_service
- from_csid = CmsDataCache.read_workspace_csid(id)
+ begin
+ cached_workspace_state = CmsDataCache.read_workspace_state(id)
- changes = CmsRestApi.get("/workspaces/#{id}/changes", from: from_csid)
+ cached_csid = cached_workspace_state.try(:first)
+ cached_workspace_data_tag = cached_workspace_state.try(:second)
- objs = changes["objs"]
- if objs.present?
- if objs != "*"
- last_state = Backend::ContentStateNode.find(from_csid)
+ changes = CmsRestApi.get("/workspaces/#{id}/changes", from: cached_csid)
- successor_state = changes["to"]
- current_state = last_state.create_successor(successor_state, objs)
- end
+ update_obj_cache(id, cached_csid, changes)
- # TODO what if workspace data is missing?
- # have the backend team include a new key `current`
- current_csid = changes["workspace"]["content_state_id"]
- CmsDataCache.write_workspace_csid(id, current_csid)
- end
+ workspace_data, workspace_data_tag = update_workspace_cache(
+ id, cached_workspace_data_tag, changes["workspace"])
- # TODO what if workspace data is missing?
- # implement workspace data caching
- workspace_data = changes["workspace"]
+ current_csid = changes["current"]
+ current_workspace_state = [current_csid, workspace_data_tag]
- return WorkspaceData.new(workspace_data)
+ if current_workspace_state != cached_workspace_state
+ CmsDataCache.write_workspace_state(id, current_workspace_state)
+ end
+
+ return WorkspaceData.new(workspace_data.merge(
+ "content_state_id" => current_csid))
+
+ rescue Scrivito::ClientError => client_error
+ if client_error.http_code == 404
+ return nil
+ else
+ raise
+ end
+ end
end
workspace_data_from_cache = WorkspaceDataFromService.find_from_cache(id)
from_content_state_id = workspace_data_from_cache.try(:content_state_id)
@@ -166,21 +172,26 @@
result << ObjDataFromService.new(raw_data)
end
end
end
- def find_blob_data(id, access, verb)
- id = Addressable::URI.normalize_component(id, Addressable::URI::CharacterClasses::UNRESERVED)
- if blob_data = fetch_blob_data_from_cache(id, access, verb)
+ def find_blob_data(id, access, verb, transformation_definition)
+ if blob_data = find_blob_data_from_cache(id, access, verb, transformation_definition)
blob_data
else
- blob_datas = request_blob_datas_from_backend(id)
- store_blob_datas_in_cache(id, blob_datas)
+ id = normalize_blob_id(id)
+ blob_datas = request_blob_datas_from_backend(id, transformation_definition)
+ store_blob_datas_in_cache(id, transformation_definition, blob_datas)
blob_datas[access][verb]
end
end
+ def find_blob_data_from_cache(id, access, verb, transformation_definition)
+ cache_key = blob_data_cache_key(normalize_blob_id(id), access, verb, transformation_definition)
+ CmsDataCache.cache.read(cache_key)
+ end
+
def find_blob_metadata(id, url)
if blob_metadata = fetch_blob_metadata_from_cache(id)
blob_metadata
else
blob_metadata = request_blob_metadata_from_s3(url)
@@ -188,56 +199,71 @@
blob_metadata
end
end
def search_objs(workspace, params)
+ cache_index = 'search'
+ cache_key = params.to_param
+
if die_content_service
- # TODO caching
- return request_search_result_from_backend(workspace, params)
+ cache = Backend::ObjDataCache.view_for_revision(workspace.revision)
+
+ if hit = cache.read_index(cache_index, cache_key)
+ return hit
+ end
+
+ result = request_search_result_from_backend(workspace, params)
+
+ cache.write_index(cache_index, cache_key, result)
+
+ return result
end
content_state = workspace.revision.content_state
- cache_index = 'search'
- cache_key = params.to_param
if result = fetch_search_result_from_cache(content_state, cache_index, cache_key)
result
else
request_search_result_from_backend(workspace, params).tap do |result|
store_search_result_in_cache(content_state, cache_index, cache_key, result)
end
end
end
- def find_obj_class_data_by_name(revision, name)
- find_all_obj_class_data(revision).find { |obj_class_data| obj_class_data.name == name }
- end
+ private
- def find_all_obj_class_data(revision)
- content_state = revision.content_state
- if obj_classes_data = fetch_obj_classes_data_from_cache(content_state)
- obj_classes_data
+ def update_workspace_cache(id, cached_data_tag, changed_workspace)
+ if changed_workspace
+ workspace_data = changed_workspace
else
- request_obj_classes_data_from_backend(revision).tap do |obj_classes_data|
- store_obj_classes_data_in_cache(content_state, obj_classes_data)
+ cached_workspace_data = CmsDataCache.read_data_from_tag(cached_data_tag)
+
+ if cached_workspace_data
+ workspace_data = cached_workspace_data
+ workspace_data_tag = cached_data_tag
+ else
+ workspace_data = CmsRestApi.get("/workspaces/#{id}")
end
end
- end
- private
+ workspace_data_tag ||= CmsDataCache.write_data_to_tag(workspace_data)
- def fetch_obj_classes_data_from_cache(content_state)
- ContentStateCaching.find_obj_classes_data(content_state) if caching?
+ [workspace_data, workspace_data_tag]
end
- def request_obj_classes_data_from_backend(revision)
- response = CmsRestApi.get("revisions/#{revision.id}/obj_classes", include_inactive: true)
- response['results'].map { |raw_data| ObjClassData.new(raw_data) }
- end
+ def update_obj_cache(workspace_id, cached_csid, changes)
+ objs = changes["objs"]
+ if objs.present? && objs != "*"
+ last_state = Backend::ContentStateNode.find(cached_csid)
+ changes_index = Backend::ObjDataCache.changes_index_from(objs)
+ successor = last_state.create_successor(changes["to"], changes_index)
- def store_obj_classes_data_in_cache(content_state, obj_classes_data)
- ContentStateCaching.store_obj_classes_data(content_state, obj_classes_data) if caching?
+ cache = Backend::ObjDataCache.view_for_workspace(workspace_id, successor)
+ changes_index.each do |id, tag|
+ cache.write_obj_tag(id, tag)
+ end
+ end
end
def fetch_search_result_from_cache(content_state, cache_index, cache_key)
content_state.find_obj_data(cache_index, cache_key) if caching?
end
@@ -248,30 +274,36 @@
def store_search_result_in_cache(content_state, cache_index, cache_key, result)
content_state.save_obj_data(cache_index, cache_key, result) if caching?
end
- def fetch_blob_data_from_cache(id, access, verb)
- CmsDataCache.cache.read(blob_data_cache_key(id, access, verb))
- end
-
- def request_blob_datas_from_backend(id)
+ def request_blob_datas_from_backend(id, transformation_definition)
@query_counter += 1
- CmsRestApi.get("blobs/#{id}")
+ if transformation_definition
+ CmsRestApi.get("blobs/#{id}/transform", transformation: transformation_definition)
+ else
+ CmsRestApi.get("blobs/#{id}")
+ end
end
- def store_blob_datas_in_cache(id, blob_datas)
+ def store_blob_datas_in_cache(id, transformation_definition, blob_datas)
%w[public_access private_access].each do |access|
%w[get head].each do |verb|
blob_data = blob_datas[access][verb]
- CmsDataCache.cache.write(blob_data_cache_key(id, access, verb),
- blob_data, blob_data['maxage'])
+ cache_key = blob_data_cache_key(id, access, verb, transformation_definition)
+ CmsDataCache.cache.write(cache_key, blob_data, blob_data['maxage'])
end
end
end
- def blob_data_cache_key(id, access, verb)
- "blob_data/#{id}/#{access}/#{verb}"
+ def blob_data_cache_key(id, access, verb, transformation_definition)
+ cache_key = "blob_data/#{id}/#{access}/#{verb}"
+ cache_key << "/#{transformation_definition.to_query}" if transformation_definition
+ cache_key
+ end
+
+ def normalize_blob_id(id)
+ Addressable::URI.normalize_component(id, Addressable::URI::CharacterClasses::UNRESERVED)
end
def fetch_blob_metadata_from_cache(id)
CmsDataCache.cache.read(blob_metadata_cache_key(id))
end