forked from MapComplete/MapComplete
		
	Invalidate cache if a point has been deleted or changed geometry. Fix #865; review cache retention times and disable cache for external geojson datasets, fix #1660
This commit is contained in:
		
							parent
							
								
									adaff94dbd
								
							
						
					
					
						commit
						a399260bf0
					
				
					 6 changed files with 68 additions and 39 deletions
				
			
		|  | @ -5,6 +5,8 @@ import { GeoOperations } from "../../GeoOperations" | |||
| import FeaturePropertiesStore from "./FeaturePropertiesStore" | ||||
| import { UIEventSource } from "../../UIEventSource" | ||||
| import { Utils } from "../../../Utils" | ||||
| import { Tiles } from "../../../Models/TileRange" | ||||
| import { BBox } from "../../BBox" | ||||
| 
 | ||||
| class SingleTileSaver { | ||||
|     private readonly _storage: UIEventSource<Feature[]> | ||||
|  | @ -54,6 +56,8 @@ class SingleTileSaver { | |||
|  * Also see the sibling class | ||||
|  */ | ||||
| export default class SaveFeatureSourceToLocalStorage { | ||||
|     public readonly storage: TileLocalStorage<Feature[]> | ||||
|     private zoomlevel: number | ||||
|     constructor( | ||||
|         backend: string, | ||||
|         layername: string, | ||||
|  | @ -62,7 +66,9 @@ export default class SaveFeatureSourceToLocalStorage { | |||
|         featureProperties: FeaturePropertiesStore, | ||||
|         maxCacheAge: number | ||||
|     ) { | ||||
|         this.zoomlevel = zoomlevel | ||||
|         const storage = TileLocalStorage.construct<Feature[]>(backend, layername, maxCacheAge) | ||||
|         this.storage = storage | ||||
|         const singleTileSavers: Map<number, SingleTileSaver> = new Map<number, SingleTileSaver>() | ||||
|         features.features.addCallbackAndRunD((features) => { | ||||
|             const sliced = GeoOperations.slice(zoomlevel, features) | ||||
|  | @ -80,4 +86,12 @@ export default class SaveFeatureSourceToLocalStorage { | |||
|             }) | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     public invalidateCacheAround(bbox: BBox) { | ||||
|         const range = Tiles.tileRangeFrom(bbox, this.zoomlevel) | ||||
|         Tiles.MapRange(range, (x, y) => { | ||||
|             const index = Tiles.tile_index(this.zoomlevel, x, y) | ||||
|             this.storage.invalidate(index) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import { IdbLocalStorage } from "../../Web/IdbLocalStorage" | ||||
| import { UIEventSource } from "../../UIEventSource" | ||||
| import { Tiles } from "../../../Models/TileRange" | ||||
| 
 | ||||
| /** | ||||
|  * A class which allows to read/write a tile to local storage. | ||||
|  | @ -91,9 +92,17 @@ export default class TileLocalStorage<T> { | |||
|             await IdbLocalStorage.GetDirectly(this._layername + "_" + tileIndex + "_date") | ||||
|         ) | ||||
|         const maxAge = this._maxAgeSeconds | ||||
|         const timeDiff = Date.now() - date | ||||
|         const timeDiff = (Date.now() - date) / 1000 | ||||
|         if (timeDiff >= maxAge) { | ||||
|             console.debug("Dropping cache for", this._layername, tileIndex, "out of date") | ||||
|             console.debug( | ||||
|                 "Dropping cache for", | ||||
|                 this._layername, | ||||
|                 tileIndex, | ||||
|                 "out of date. Max allowed age is", | ||||
|                 maxAge, | ||||
|                 "current age is", | ||||
|                 timeDiff | ||||
|             ) | ||||
|             await IdbLocalStorage.SetDirectly(this._layername + "_" + tileIndex, undefined) | ||||
| 
 | ||||
|             return undefined | ||||
|  | @ -102,7 +111,8 @@ export default class TileLocalStorage<T> { | |||
|         return <any>data | ||||
|     } | ||||
| 
 | ||||
|     invalidate(zoomlevel: number, tileIndex) { | ||||
|     public invalidate(tileIndex: number) { | ||||
|         console.log("Invalidated tile", tileIndex) | ||||
|         this.getTileSource(tileIndex).setData(undefined) | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ export default class LayoutSource extends FeatureSourceMerger { | |||
|     private readonly supportsForceDownload: UpdatableFeatureSource[] | ||||
| 
 | ||||
|     private readonly fromCache: Map<string, LocalStorageFeatureSource> | ||||
|     private static readonly fromCacheZoomLevel = 15 | ||||
|     public static readonly fromCacheZoomLevel = 15 | ||||
|     constructor( | ||||
|         layers: LayerConfig[], | ||||
|         featureSwitches: FeatureSwitchState, | ||||
|  |  | |||
|  | @ -27,14 +27,14 @@ export default class LocalStorageFeatureSource extends DynamicTileSource { | |||
|             options?.maxAge ?? 24 * 60 * 60 | ||||
|         ) | ||||
|         super( | ||||
|            new ImmutableStore(zoomlevel), | ||||
|             new ImmutableStore(zoomlevel), | ||||
|             layer.minzoom, | ||||
|             (tileIndex) => | ||||
|                 new StaticFeatureSource( | ||||
|                     storage.getTileSource(tileIndex).mapD((features) => { | ||||
|                         if (features.length === undefined) { | ||||
|                             console.trace("These are not features:", features) | ||||
|                             storage.invalidate(zoomlevel, tileIndex) | ||||
|                             storage.invalidate(tileIndex) | ||||
|                             return [] | ||||
|                         } | ||||
|                         return features.filter((f) => !f.properties.id.match(/(node|way)\/-[0-9]+/)) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue