26
26
27
27
include (" Middleware.jl" )
28
28
include (" admin.jl" )
29
+ include (" file_io.jl" )
30
+ include (" server_cache.jl" )
29
31
30
32
include (" job_management/JobInterface.jl" )
31
33
include (" job_management/DiskService.jl" )
@@ -49,237 +51,12 @@ function get_regions()
49
51
return regions
50
52
end
51
53
52
- """
53
- initialize_regional_data_cache(reef_data_path::String, reg_cache_fn::String)
54
-
55
- Create initial regional data store with data from `reef_data_path`, excluding geospatial
56
- data and save to `reg_cache_fn` path.
57
- """
58
- function initialize_regional_data_cache (reef_data_path:: String , reg_cache_fn:: String )
59
- regional_assessment_data = OrderedDict{
60
- String,Union{RegionalCriteria,DataFrame,Dict}
61
- }()
62
- for reg in get_regions ()
63
- @debug " $(now ()) : Initializing cache for $reg "
64
- data_paths = String[]
65
- data_names = String[]
66
-
67
- slope_table = nothing
68
- flat_table = nothing
69
-
70
- for (k, dp) in criteria_data_map ()
71
- g = glob (" $reg *$dp .tif" , reef_data_path)
72
- if length (g) == 0
73
- continue
74
- end
75
-
76
- push! (data_paths, first (g))
77
- push! (data_names, string (k))
78
- if occursin (" valid" , string (dp))
79
- # Load up Parquet files
80
- parq_file = replace (first (g), " .tif" => " _lookup.parq" )
81
-
82
- if occursin (" slope" , string (dp))
83
- slope_table = GeoParquet. read (parq_file)
84
- elseif occursin (" flat" , string (dp))
85
- @warn " Skipping data for reef flats as it is currently unused"
86
- # flat_table = GeoParquet.read(parq_file)
87
- else
88
- msg = " Unknown lookup found: $(parq_file) . Must be 'slope' or 'flat'"
89
- throw (ArgumentError (msg))
90
- end
91
- end
92
- end
93
-
94
- # Pre-extract long/lat coordinates
95
- coords = GI. coordinates .(slope_table. geometry)
96
- slope_table[! , :lons ] .= first .(coords)
97
- slope_table[! , :lats ] .= last .(coords)
98
-
99
- # coords = GI.coordinates.(flat_table.geometry)
100
- # flat_table[!, :lons] .= first.(coords)
101
- # flat_table[!, :lats] .= last.(coords)
102
-
103
- rst_stack = RasterStack (data_paths; name= data_names, lazy= true )
104
- regional_assessment_data[reg] = RegionalCriteria (
105
- rst_stack,
106
- slope_table,
107
- slope_table[[1 ], :] # flat_table
108
- )
109
-
110
- @debug " $(now ()) : Finished initialization for $reg "
111
- end
112
-
113
- regional_assessment_data[" region_long_names" ] = Dict (
114
- " FarNorthern" => " Far Northern Management Area" ,
115
- " Cairns-Cooktown" => " Cairns/Cooktown Management Area" ,
116
- " Townsville-Whitsunday" => " Townsville/Whitsunday Management Area" ,
117
- " Mackay-Capricorn" => " Mackay/Capricorn Management Area"
118
- )
119
-
120
- # Store cache on disk to avoid excessive cold startup times
121
- @debug " Saving regional data cache to disk"
122
- serialize (reg_cache_fn, regional_assessment_data)
123
-
124
- return regional_assessment_data
125
- end
126
-
127
- """
128
- setup_regional_data(config::Dict)
129
-
130
- Load regional data to act as an in-memory cache.
131
-
132
- # Arguments
133
- - `config` : Configuration settings, typically loaded from a TOML file.
134
- - `reef_data_path` : Path to pre-prepared reef data
135
-
136
- # Returns
137
- OrderedDict of `RegionalCriteria` for each region.
138
- """
139
- function setup_regional_data (config:: Dict )
140
- reef_data_path = config[" prepped_data" ][" PREPPED_DATA_DIR" ]
141
- reg_cache_dir = config[" server_config" ][" REGIONAL_CACHE_DIR" ]
142
- reg_cache_fn = joinpath (reg_cache_dir, " regional_cache.dat" )
143
-
144
- if @isdefined (REGIONAL_DATA)
145
- @debug " Using previously generated regional data store."
146
- elseif isfile (reg_cache_fn)
147
- @debug " Loading regional data cache from disk"
148
- # Updates to packages like DiskArrays can break deserialization
149
- try
150
- @eval const REGIONAL_DATA = deserialize ($ (reg_cache_fn))
151
- catch err
152
- @warn " Failed to deserialize $(reg_cache_fn) with error:" err
153
- rm (reg_cache_fn)
154
- end
155
- end
156
-
157
- if ! @isdefined (REGIONAL_DATA)
158
- @debug " Setting up regional data store..."
159
- regional_assessment_data = initialize_regional_data_cache (
160
- reef_data_path,
161
- reg_cache_fn
162
- )
163
- # Remember, `@eval` runs in global scope.
164
- @eval const REGIONAL_DATA = $ (regional_assessment_data)
165
- end
166
-
167
- # If REGIONAL_DATA is defined, but failed to load supporting data that cannot be
168
- # cached to disk, such as the reef outlines, (e.g., due to incorrect config), then it
169
- # will cause errors later on.
170
- # Then there's no way to address this, even between web server sessions, as `const`
171
- # values cannot be modified.
172
- # Here, we check for existence and try to load again if needed.
173
- if ! haskey (REGIONAL_DATA, " reef_outlines" )
174
- reef_outline_path = joinpath (reef_data_path, " rrap_canonical_outlines.gpkg" )
175
- REGIONAL_DATA[" reef_outlines" ] = GDF. read (reef_outline_path)
176
- end
177
-
178
- return REGIONAL_DATA
179
- end
180
-
181
- """
182
- _cache_location(config::Dict)::String
183
-
184
- Retrieve cache location for geotiffs.
185
- """
186
- function _cache_location (config:: Dict ):: String
187
- cache_loc = try
188
- in_debug = haskey (config[" server_config" ], " DEBUG_MODE" )
189
- if in_debug && lowercase (config[" server_config" ][" DEBUG_MODE" ]) == " true"
190
- if " DEBUG_CACHE_DIR" ∉ keys (ENV )
191
- ENV [" DEBUG_CACHE_DIR" ] = mktempdir ()
192
- end
193
-
194
- ENV [" DEBUG_CACHE_DIR" ]
195
- else
196
- config[" server_config" ][" TIFF_CACHE_DIR" ]
197
- end
198
- catch err
199
- @warn " Encountered error:" err
200
- if " DEBUG_CACHE_DIR" ∉ keys (ENV )
201
- ENV [" DEBUG_CACHE_DIR" ] = mktempdir ()
202
- end
203
-
204
- ENV [" DEBUG_CACHE_DIR" ]
205
- end
206
-
207
- return cache_loc
208
- end
209
-
210
- """
211
- cache_filename(qp::Dict, config::Dict, suffix::String, ext::String)
212
-
213
- Generate a filename for a cache.
214
-
215
- # Arguments
216
- - `qp` : Query parameters to hash
217
- - `config` : app configuration (to extract cache parent directory from)
218
- - `suffix` : a suffix to use in the filename (pass `""` if none required)
219
- - `ext` : file extension to use
220
- """
221
- function cache_filename (qp:: Dict , config:: Dict , suffix:: String , ext:: String )
222
- file_id = create_job_id (qp)
223
- temp_path = _cache_location (config)
224
- cache_file_path = joinpath (temp_path, " $(file_id)$(suffix) .$(ext) " )
225
-
226
- return cache_file_path
227
- end
228
-
229
- """
230
- n_gdal_threads(config::Dict)::String
231
-
232
- Retrieve the configured number of threads to use when writing COGs with GDAL.
233
- """
234
- function n_gdal_threads (config:: Dict ):: String
235
- n_cog_threads = try
236
- config[" server_config" ][" COG_THREADS" ]
237
- catch
238
- " 1" # Default to using a single thread for GDAL write
239
- end
240
-
241
- return n_cog_threads
242
- end
243
-
244
- """
245
- tile_size(config::Dict)::Tuple
246
-
247
- Retrieve the configured size of map tiles in pixels (width and height / lon and lat).
248
- """
249
- function tile_size (config:: Dict ):: Tuple
250
- tile_dims = try
251
- res = parse (Int, config[" server_config" ][" TILE_SIZE" ])
252
- (res, res)
253
- catch
254
- (256 , 256 ) # 256x256
255
- end
256
-
257
- return tile_dims
258
- end
259
-
260
54
function get_auth_router (config:: Dict )
261
55
# Setup auth middleware - depends on config.toml - can return identity func
262
56
auth = setup_jwt_middleware (config)
263
57
return router (" " ; middleware= [auth])
264
58
end
265
59
266
- """
267
- warmup_cache(config_path::String)
268
-
269
- Invokes warm up of regional data cache to reduce later spin up times.
270
- """
271
- function warmup_cache (config_path:: String )
272
- config = TOML. parsefile (config_path)
273
-
274
- # Create re-usable empty tile
275
- no_data_path = cache_filename (Dict (" no_data" => " none" ), config, " no_data" , " png" )
276
- if ! isfile (no_data_path)
277
- save (no_data_path, zeros (RGBA, tile_size (config)))
278
- end
279
-
280
- return setup_regional_data (config)
281
- end
282
-
283
60
function start_server (config_path)
284
61
@info " Launching server... please wait"
285
62
@@ -291,6 +68,9 @@ function start_server(config_path)
291
68
@info " Setting up auth middleware and router."
292
69
auth = get_auth_router (config)
293
70
71
+ @info " Setting up criteria routes..."
72
+ setup_criteria_routes (config, auth)
73
+
294
74
@info " Setting up region routes..."
295
75
setup_region_routes (config, auth)
296
76
0 commit comments