
001package ca.uhn.fhir.jpa.search.cache; 002 003/*- 004 * #%L 005 * HAPI FHIR JPA Server 006 * %% 007 * Copyright (C) 2014 - 2022 Smile CDR, Inc. 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import ca.uhn.fhir.interceptor.model.RequestPartitionId; 024import ca.uhn.fhir.jpa.entity.Search; 025 026import java.time.Instant; 027import java.util.Optional; 028 029public interface ISearchCacheSvc { 030 031 /** 032 * Places a new search of some sort in the cache, or updates an existing search. The search passed in is guaranteed to have 033 * a {@link Search#getUuid() UUID} so that is a good candidate for consistent identification. 034 * 035 * @param theSearch The search to store 036 * @return Returns a copy of the search as it was saved. Callers should use the returned Search object for any further processing. 037 */ 038 Search save(Search theSearch); 039 040 /** 041 * Fetch a search using its UUID. The search should be fully loaded when it is returned (i.e. includes are fetched, so that access to its 042 * fields will not cause database errors if the current tranaction scope ends. 043 * 044 * @param theUuid The search UUID 045 * @return The search if it exists 046 */ 047 Optional<Search> fetchByUuid(String theUuid); 048 049 /** 050 * TODO: this is perhaps an inappropriate responsibility for this service 051 * 052 * <p> 053 * This method marks a search as in progress, but should only allow exactly one call to do so across the cluster. This 054 * is done so that if two client threads request the next page at the exact same time (which is unlikely but not 055 * impossible) only one will actually proceed to load the next results and the other will just wait for them 056 * to arrive. 057 * 058 * @param theSearch The search to mark 059 * @return This method should return an empty optional if the search was not marked (meaning that another thread 060 * succeeded in marking it). If the search doesn't exist or some other error occurred, an exception will be thrown 061 * instead of {@link Optional#empty()} 062 */ 063 Optional<Search> tryToMarkSearchAsInProgress(Search theSearch); 064 065 /** 066 * Look for any existing searches matching the given resource type and query string. 067 * <p> 068 * This method is allowed to perform a "best effort" return, so it can return searches that don't match the query string exactly, or 069 * which have a created timestamp before <code>theCreatedAfter</code> date. The caller is responsible for removing 070 * any inappropriate Searches and picking the most relevant one. 071 * </p> 072 * 073 * @param theResourceType The resource type of the search. Results MUST match this type 074 * @param theQueryString The query string. Results SHOULD match this type 075 * @param theCreatedAfter Results SHOULD not include any searches created before this cutoff timestamp 076 * @param theRequestPartitionId Search should examine only the requested partitions. Cache MUST not return results matching the given partition IDs 077 * @return A collection of candidate searches 078 */ 079 Optional<Search> findCandidatesForReuse(String theResourceType, String theQueryString, Instant theCreatedAfter, RequestPartitionId theRequestPartitionId); 080 081 /** 082 * This method will be called periodically to delete stale searches. Implementations are not required to do anything 083 * if they have some other mechanism for expiring stale results other than manually looking for them 084 * and deleting them. 085 */ 086 void pollForStaleSearchesAndDeleteThem(); 087}