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