( requestTimeout time.Duration, data *TemplateData, changesChan chan bool, )
| 384 | } |
| 385 | |
| 386 | func buildRoutes( |
| 387 | requestTimeout time.Duration, |
| 388 | data *TemplateData, |
| 389 | changesChan chan bool, |
| 390 | ) *http.ServeMux { |
| 391 | router := http.NewServeMux() |
| 392 | |
| 393 | router.HandleFunc("/dynamic/events", func(w http.ResponseWriter, r *http.Request) { |
| 394 | ctx := r.Context() |
| 395 | |
| 396 | writeStatus := func(w http.ResponseWriter, code int) { |
| 397 | msg := fmt.Sprintf("%d - %s", code, http.StatusText(http.StatusGone)) |
| 398 | http.Error(w, msg, code) |
| 399 | } |
| 400 | |
| 401 | select { |
| 402 | case <-ctx.Done(): |
| 403 | writeStatus(w, http.StatusGone) |
| 404 | case <-time.After(requestTimeout): |
| 405 | writeStatus(w, http.StatusRequestTimeout) |
| 406 | case <-changesChan: |
| 407 | writeStatus(w, http.StatusOK) |
| 408 | } |
| 409 | }) |
| 410 | |
| 411 | router.HandleFunc("/dynamic/template", func(w http.ResponseWriter, r *http.Request) { |
| 412 | http.ServeFile(w, r, data.Filename) |
| 413 | }) |
| 414 | |
| 415 | javascriptTemplate := template.Must(template.New("tenant-data.js").Funcs(template.FuncMap{ |
| 416 | "toJSON": func(v interface{}) string { |
| 417 | data, _ := json.Marshal(v) |
| 418 | return string(data) |
| 419 | }, |
| 420 | }).Parse(tenantDataAsset)) |
| 421 | |
| 422 | router.HandleFunc("/dynamic/tenant-data", func(w http.ResponseWriter, r *http.Request) { |
| 423 | if err := javascriptTemplate.Execute(w, data); err != nil { |
| 424 | http.Error(w, err.Error(), 500) |
| 425 | } |
| 426 | }) |
| 427 | |
| 428 | router.Handle("/", http.FileServer(http.FS(templatePreviewAssets))) |
| 429 | return router |
| 430 | } |
| 431 | |
| 432 | func broadcastTemplateChanges(ctx context.Context, filename string) (chan bool, error) { |
| 433 | changesChan := make(chan bool) |
no test coverage detected