Mercurial > gemma
comparison pkg/controllers/system.go @ 4214:49564382ffff
Added a import queue job to recalculate the contour lines of the sounding results if the heights have changed.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Fri, 16 Aug 2019 13:15:34 +0200 |
parents | 45be361f2d48 |
children | 8aff98c84a5a |
comparison
equal
deleted
inserted
replaced
4197:5d7ce7f926eb | 4214:49564382ffff |
---|---|
21 "io/ioutil" | 21 "io/ioutil" |
22 "log" | 22 "log" |
23 "net/http" | 23 "net/http" |
24 "strings" | 24 "strings" |
25 "sync" | 25 "sync" |
26 "time" | |
26 | 27 |
27 "github.com/gorilla/mux" | 28 "github.com/gorilla/mux" |
28 | 29 |
29 "gemma.intevation.de/gemma/pkg/auth" | 30 "gemma.intevation.de/gemma/pkg/auth" |
31 "gemma.intevation.de/gemma/pkg/common" | |
30 "gemma.intevation.de/gemma/pkg/config" | 32 "gemma.intevation.de/gemma/pkg/config" |
31 "gemma.intevation.de/gemma/pkg/geoserver" | 33 "gemma.intevation.de/gemma/pkg/geoserver" |
34 "gemma.intevation.de/gemma/pkg/imports" | |
32 "gemma.intevation.de/gemma/pkg/models" | 35 "gemma.intevation.de/gemma/pkg/models" |
33 ) | 36 ) |
34 | 37 |
35 const ( | 38 const ( |
36 getFeatureColourSQL = `SELECT r,g,b,a | 39 getFeatureColourSQL = `SELECT r,g,b,a |
150 | 153 |
151 jr = JSONResult{Result: settings} | 154 jr = JSONResult{Result: settings} |
152 return | 155 return |
153 } | 156 } |
154 | 157 |
155 type reconfFunc func(sql.NullString, string) (func(), error) | 158 type reconfFunc func(sql.NullString, string) (func(*http.Request), error) |
156 | 159 |
157 var ( | 160 var ( |
158 reconfigureFuncsMu sync.Mutex | 161 reconfigureFuncsMu sync.Mutex |
159 reconfigureFuncs = map[string]reconfFunc{} | 162 reconfigureFuncs = map[string]reconfFunc{} |
160 ) | 163 ) |
169 reconfigureFuncsMu.Lock() | 172 reconfigureFuncsMu.Lock() |
170 defer reconfigureFuncsMu.Unlock() | 173 defer reconfigureFuncsMu.Unlock() |
171 return reconfigureFuncs[key] | 174 return reconfigureFuncs[key] |
172 } | 175 } |
173 | 176 |
174 func reconfigureClassBreaks(old sql.NullString, curr, which string, recalc func()) (func(), error) { | 177 func reconfigureClassBreaks( |
178 old sql.NullString, curr, | |
179 which string, | |
180 recalc func(*http.Request), | |
181 ) (func(*http.Request), error) { | |
175 | 182 |
176 // If new values are broken, don't proceed. | 183 // If new values are broken, don't proceed. |
177 currCVs, err := models.ParseColorValues(curr) | 184 currCVs, err := models.ParseColorValues(curr) |
178 if err != nil { | 185 if err != nil { |
179 return nil, err | 186 return nil, err |
180 } | 187 } |
181 | 188 |
182 doBoth := func() { | 189 doBoth := func(req *http.Request) { |
183 log.Printf("info: Trigger re-calculation of %s.", which) | 190 log.Printf("info: Trigger re-calculation of %s.", which) |
184 geoserver.ReconfigureStyle(which) | 191 geoserver.ReconfigureStyle(which) |
185 recalc() | 192 recalc(req) |
186 } | 193 } |
187 | 194 |
188 if !old.Valid { | 195 if !old.Valid { |
189 return doBoth, nil | 196 return doBoth, nil |
190 } | 197 } |
211 } | 218 } |
212 | 219 |
213 // Only the color changed -> no expensive recalc needed. | 220 // Only the color changed -> no expensive recalc needed. |
214 if colorChanged { | 221 if colorChanged { |
215 log.Println("info: Only colors changed.") | 222 log.Println("info: Only colors changed.") |
216 return func() { geoserver.ReconfigureStyle(which) }, nil | 223 return func(*http.Request) { geoserver.ReconfigureStyle(which) }, nil |
217 } | 224 } |
218 | 225 |
219 return nil, nil | 226 return nil, nil |
220 } | 227 } |
221 | 228 |
222 func init() { | 229 func init() { |
223 registerReconfigureFunc("morphology_classbreaks", | 230 registerReconfigureFunc("morphology_classbreaks", |
224 func(old sql.NullString, curr string) (func(), error) { | 231 func(old sql.NullString, curr string) (func(*http.Request), error) { |
225 return reconfigureClassBreaks( | 232 return reconfigureClassBreaks( |
226 old, curr, | 233 old, curr, |
227 "sounding_results_contour_lines_geoserver", | 234 "sounding_results_contour_lines_geoserver", |
228 func() { | 235 func(req *http.Request) { |
229 log.Println( | 236 if s, ok := auth.GetSession(req); ok { |
230 "todo: Trigger expensive recalculation of sounding result contours.") | 237 triggerSoundingResultsContoursRecalc(s.User, curr) |
238 } | |
231 }) | 239 }) |
232 }) | 240 }) |
233 registerReconfigureFunc("morphology_classbreaks_compare", | 241 registerReconfigureFunc("morphology_classbreaks_compare", |
234 func(old sql.NullString, curr string) (func(), error) { | 242 func(old sql.NullString, curr string) (func(*http.Request), error) { |
235 return reconfigureClassBreaks( | 243 return reconfigureClassBreaks( |
236 old, curr, | 244 old, curr, |
237 "sounding_differences", | 245 "sounding_differences", |
238 func() { go deleteSoundingDiffs() }) | 246 func(*http.Request) { go deleteSoundingDiffs() }) |
239 }) | 247 }) |
248 } | |
249 | |
250 func triggerSoundingResultsContoursRecalc(who, breaks string) { | |
251 var serialized string | |
252 job := &imports.IsoRefresh{ClassBreaks: breaks} | |
253 serialized, err := common.ToJSONString(job) | |
254 if err != nil { | |
255 log.Printf("error: %v\n", err) | |
256 return | |
257 } | |
258 var jobID int64 | |
259 if jobID, err = imports.AddJob( | |
260 imports.ISRJobKind, | |
261 time.Time{}, | |
262 nil, | |
263 nil, | |
264 who, | |
265 false, | |
266 serialized, | |
267 ); err != nil { | |
268 log.Printf("error: %v\n", err) | |
269 return | |
270 } | |
271 log.Printf( | |
272 "info: Recalculate sounding results contours in job %d.\n", | |
273 jobID) | |
274 | |
240 } | 275 } |
241 | 276 |
242 func deleteSoundingDiffs() { | 277 func deleteSoundingDiffs() { |
243 // TODO: Better do that in import queue? | 278 // TODO: Better do that in import queue? |
244 ctx := context.Background() | 279 ctx := context.Background() |
277 if getStmt, err = tx.PrepareContext(ctx, getConfigSQL); err != nil { | 312 if getStmt, err = tx.PrepareContext(ctx, getConfigSQL); err != nil { |
278 return | 313 return |
279 } | 314 } |
280 defer getStmt.Close() | 315 defer getStmt.Close() |
281 | 316 |
282 reconfigure := map[string]func(){} | 317 reconfigure := map[string]func(*http.Request){} |
283 | 318 |
284 for key, value := range *settings { | 319 for key, value := range *settings { |
285 var old sql.NullString | 320 var old sql.NullString |
286 err = getStmt.QueryRowContext(ctx, key).Scan(&old) | 321 err = getStmt.QueryRowContext(ctx, key).Scan(&old) |
287 switch { | 322 switch { |
290 case err != nil: | 325 case err != nil: |
291 return | 326 return |
292 } | 327 } |
293 | 328 |
294 if cmp := reconfigureFunc(key); cmp != nil { | 329 if cmp := reconfigureFunc(key); cmp != nil { |
295 var fn func() | 330 var fn func(*http.Request) |
296 if fn, err = cmp(old, value); err != nil { | 331 if fn, err = cmp(old, value); err != nil { |
297 return | 332 return |
298 } | 333 } |
299 if fn != nil { | 334 if fn != nil { |
300 reconfigure[key] = fn | 335 reconfigure[key] = fn |
309 if err = tx.Commit(); err != nil { | 344 if err = tx.Commit(); err != nil { |
310 return | 345 return |
311 } | 346 } |
312 | 347 |
313 for _, fn := range reconfigure { | 348 for _, fn := range reconfigure { |
314 fn() | 349 fn(req) |
315 } | 350 } |
316 | 351 |
317 jr = JSONResult{ | 352 jr = JSONResult{ |
318 Code: http.StatusCreated, | 353 Code: http.StatusCreated, |
319 Result: struct { | 354 Result: struct { |