4
4
"context"
5
5
"embed"
6
6
"fmt"
7
+ "io"
7
8
"net/http"
8
9
"strconv"
9
10
@@ -37,6 +38,7 @@ const (
37
38
DefaultHealthCheckStartupPath = "/healthz"
38
39
DefaultHealthCheckLivenessPath = "/livez"
39
40
DefaultHealthCheckReadinessPath = "/readyz"
41
+ DefaultTasksPath = "/tasks"
40
42
DefaultDebugConfigPath = "/debug/config"
41
43
DefaultDebugPProfPath = "/debug/pprof"
42
44
DefaultDebugBuildPath = "/debug/build"
@@ -63,6 +65,7 @@ var FxCoreModule = fx.Module(
63
65
fxhealthcheck .FxHealthcheckModule ,
64
66
fx .Provide (
65
67
NewFxModuleInfoRegistry ,
68
+ NewTaskRegistry ,
66
69
NewFxCore ,
67
70
fx .Annotate (
68
71
NewFxCoreModuleInfo ,
@@ -92,7 +95,8 @@ type FxCoreParam struct {
92
95
Checker * healthcheck.Checker
93
96
Config * config.Config
94
97
Logger * log.Logger
95
- Registry * FxModuleInfoRegistry
98
+ InfoRegistry * FxModuleInfoRegistry
99
+ TaskRegistry * TaskRegistry
96
100
MetricsRegistry * prometheus.Registry
97
101
}
98
102
@@ -232,7 +236,7 @@ func withHandlers(coreServer *echo.Echo, p FxCoreParam) (*echo.Echo, error) {
232
236
dashboardEnabled := p .Config .GetBool ("modules.core.server.dashboard.enabled" )
233
237
234
238
// dashboard overview
235
- overviewInfo , err := p .Registry .Find (ModuleName )
239
+ overviewInfo , err := p .InfoRegistry .Find (ModuleName )
236
240
if err != nil {
237
241
return nil , err
238
242
}
@@ -248,6 +252,7 @@ func withHandlers(coreServer *echo.Echo, p FxCoreParam) (*echo.Echo, error) {
248
252
overviewTraceProcessorExpose := p .Config .GetBool ("modules.core.server.dashboard.overview.trace_processor" )
249
253
250
254
// template expositions
255
+ tasksExpose := p .Config .GetBool ("modules.core.server.tasks.expose" )
251
256
metricsExpose := p .Config .GetBool ("modules.core.server.metrics.expose" )
252
257
startupExpose := p .Config .GetBool ("modules.core.server.healthcheck.startup.expose" )
253
258
livenessExpose := p .Config .GetBool ("modules.core.server.healthcheck.liveness.expose" )
@@ -260,6 +265,7 @@ func withHandlers(coreServer *echo.Echo, p FxCoreParam) (*echo.Echo, error) {
260
265
modulesExpose := p .Config .GetBool ("modules.core.server.debug.modules.expose" )
261
266
262
267
// template paths
268
+ tasksPath := p .Config .GetString ("modules.core.server.tasks.path" )
263
269
metricsPath := p .Config .GetString ("modules.core.server.metrics.path" )
264
270
startupPath := p .Config .GetString ("modules.core.server.healthcheck.startup.path" )
265
271
livenessPath := p .Config .GetString ("modules.core.server.healthcheck.liveness.path" )
@@ -271,6 +277,48 @@ func withHandlers(coreServer *echo.Echo, p FxCoreParam) (*echo.Echo, error) {
271
277
buildPath := p .Config .GetString ("modules.core.server.debug.build.path" )
272
278
modulesPath := p .Config .GetString ("modules.core.server.debug.modules.path" )
273
279
280
+ // tasks
281
+ if tasksExpose {
282
+ if tasksPath == "" {
283
+ tasksPath = DefaultTasksPath
284
+ }
285
+
286
+ coreServer .POST (fmt .Sprintf ("%s/:name" , tasksPath ), func (c echo.Context ) error {
287
+ ctx := c .Request ().Context ()
288
+
289
+ logger := log .CtxLogger (ctx )
290
+
291
+ name := c .Param ("name" )
292
+
293
+ input , err := io .ReadAll (c .Request ().Body )
294
+ if err != nil {
295
+ logger .Error ().Err (err ).Str ("task" , name ).Msg ("request body read error" )
296
+
297
+ return echo .NewHTTPError (http .StatusInternalServerError , fmt .Sprintf ("cannot read request body: %v" , err .Error ()))
298
+ }
299
+
300
+ err = c .Request ().Body .Close ()
301
+ if err != nil {
302
+ logger .Error ().Err (err ).Str ("task" , name ).Msg ("request body close error" )
303
+
304
+ return echo .NewHTTPError (http .StatusInternalServerError , fmt .Sprintf ("cannot close request body: %v" , err .Error ()))
305
+ }
306
+
307
+ res := p .TaskRegistry .Run (ctx , name , input )
308
+ if ! res .Success {
309
+ logger .Error ().Err (err ).Str ("task" , name ).Msg ("task execution error" )
310
+
311
+ return c .JSON (http .StatusInternalServerError , res )
312
+ }
313
+
314
+ logger .Info ().Str ("task" , name ).Msg ("task execution success" )
315
+
316
+ return c .JSON (http .StatusOK , res )
317
+ })
318
+
319
+ coreServer .Logger .Debug ("registered tasks handler" )
320
+ }
321
+
274
322
// metrics
275
323
if metricsExpose {
276
324
if metricsPath == "" {
@@ -393,14 +441,14 @@ func withHandlers(coreServer *echo.Echo, p FxCoreParam) (*echo.Echo, error) {
393
441
coreServer .Logger .Debug ("registered debug build handler" )
394
442
}
395
443
396
- // debug modules
444
+ // modules
397
445
if modulesExpose || appDebug {
398
446
if modulesPath == "" {
399
447
modulesPath = DefaultDebugModulesPath
400
448
}
401
449
402
450
coreServer .GET (fmt .Sprintf ("%s/:name" , modulesPath ), func (c echo.Context ) error {
403
- info , err := p .Registry .Find (c .Param ("name" ))
451
+ info , err := p .InfoRegistry .Find (c .Param ("name" ))
404
452
if err != nil {
405
453
return echo .NewHTTPError (http .StatusNotFound , err .Error ())
406
454
}
@@ -466,6 +514,9 @@ func withHandlers(coreServer *echo.Echo, p FxCoreParam) (*echo.Echo, error) {
466
514
"overviewLogOutputExpose" : overviewLogOutputExpose ,
467
515
"overviewTraceSamplerExpose" : overviewTraceSamplerExpose ,
468
516
"overviewTraceProcessorExpose" : overviewTraceProcessorExpose ,
517
+ "tasksExpose" : tasksExpose ,
518
+ "tasksPath" : tasksPath ,
519
+ "tasksNames" : p .TaskRegistry .Names (),
469
520
"metricsExpose" : metricsExpose ,
470
521
"metricsPath" : metricsPath ,
471
522
"startupExpose" : startupExpose ,
@@ -486,7 +537,7 @@ func withHandlers(coreServer *echo.Echo, p FxCoreParam) (*echo.Echo, error) {
486
537
"buildPath" : buildPath ,
487
538
"modulesExpose" : modulesExpose || appDebug ,
488
539
"modulesPath" : modulesPath ,
489
- "modulesNames" : p .Registry .Names (),
540
+ "modulesNames" : p .InfoRegistry .Names (),
490
541
"theme" : theme ,
491
542
})
492
543
})
0 commit comments