@@ -1129,28 +1129,64 @@ impl LogServer {
11291129 let collection_id = Uuid :: parse_str ( & scout_logs. collection_id )
11301130 . map ( CollectionUuid )
11311131 . map_err ( |_| Status :: invalid_argument ( "Failed to parse collection id" ) ) ?;
1132-
11331132 let prefix = collection_id. storage_prefix_for_log ( ) ;
11341133 let log_reader = LogReader :: new (
11351134 self . config . reader . clone ( ) ,
11361135 Arc :: clone ( & self . storage ) ,
11371136 prefix,
11381137 ) ;
1139- let ( start_position, limit_position) = match log_reader. manifest ( ) . await {
1140- Ok ( Some ( manifest) ) => ( manifest. oldest_timestamp ( ) , manifest. next_write_timestamp ( ) ) ,
1141- Ok ( None ) => ( LogPosition :: from_offset ( 1 ) , LogPosition :: from_offset ( 1 ) ) ,
1142- Err ( wal3:: Error :: UninitializedLog ) => {
1143- return Err ( Status :: not_found ( format ! (
1144- "collection {collection_id} not found"
1145- ) ) ) ;
1138+ let cache_key = cache_key_for_manifest_and_etag ( collection_id) ;
1139+ let mut cached_manifest_and_e_tag = None ;
1140+ if let Some ( cache) = self . cache . as_ref ( ) {
1141+ if let Some ( cache_bytes) = cache. get ( & cache_key) . await . ok ( ) . flatten ( ) {
1142+ let met = serde_json:: from_slice :: < ManifestAndETag > ( & cache_bytes. bytes ) . ok ( ) ;
1143+ cached_manifest_and_e_tag = met;
11461144 }
1147- Err ( err) => {
1148- return Err ( Status :: new (
1149- err. code ( ) . into ( ) ,
1150- format ! ( "could not scout logs: {err:?}" ) ,
1151- ) ) ;
1145+ }
1146+ // NOTE(rescrv): We verify and if verification fails, we take the cached manifest to fall
1147+ // back to the uncached path.
1148+ if let Some ( cached) = cached_manifest_and_e_tag. as_ref ( ) {
1149+ if !log_reader. verify ( cached) . await . unwrap_or_default ( ) {
1150+ cached_manifest_and_e_tag. take ( ) ;
11521151 }
1153- } ;
1152+ }
1153+ let ( start_position, limit_position) =
1154+ if let Some ( manifest_and_e_tag) = cached_manifest_and_e_tag {
1155+ (
1156+ manifest_and_e_tag. manifest . oldest_timestamp ( ) ,
1157+ manifest_and_e_tag. manifest . next_write_timestamp ( ) ,
1158+ )
1159+ } else {
1160+ let ( start_position, limit_position) = match log_reader. manifest_and_e_tag ( ) . await {
1161+ Ok ( Some ( manifest_and_e_tag) ) => {
1162+ if let Some ( cache) = self . cache . as_ref ( ) {
1163+ let json = serde_json:: to_string ( & manifest_and_e_tag)
1164+ . map_err ( |err| Status :: unknown ( err. to_string ( ) ) ) ?;
1165+ let cached_bytes = CachedBytes {
1166+ bytes : Vec :: from ( json) ,
1167+ } ;
1168+ cache. insert ( cache_key, cached_bytes) . await ;
1169+ }
1170+ (
1171+ manifest_and_e_tag. manifest . oldest_timestamp ( ) ,
1172+ manifest_and_e_tag. manifest . next_write_timestamp ( ) ,
1173+ )
1174+ }
1175+ Ok ( None ) => ( LogPosition :: from_offset ( 1 ) , LogPosition :: from_offset ( 1 ) ) ,
1176+ Err ( wal3:: Error :: UninitializedLog ) => {
1177+ return Err ( Status :: not_found ( format ! (
1178+ "collection {collection_id} not found"
1179+ ) ) ) ;
1180+ }
1181+ Err ( err) => {
1182+ return Err ( Status :: new (
1183+ err. code ( ) . into ( ) ,
1184+ format ! ( "could not scout logs: {err:?}" ) ,
1185+ ) ) ;
1186+ }
1187+ } ;
1188+ ( start_position, limit_position)
1189+ } ;
11541190 let start_offset = start_position. offset ( ) as i64 ;
11551191 let limit_offset = limit_position. offset ( ) as i64 ;
11561192 Ok ( Response :: new ( ScoutLogsResponse {
0 commit comments