package cmdpacks import ( "context" "time" "github.com/go-co-op/gocron/v2" "lmika.dev/cmd/dynamo-browse/internal/common/ui/commandctrl" "lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/controllers" "lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/services/tables" "ucl.lmika.dev/ucl" ) type asyncModule struct { tableService *tables.Service state *controllers.State } func (m asyncModule) asyncDo(ctx context.Context, args ucl.CallArgs) (any, error) { var block ucl.Invokable if err := args.Bind(&block); err != nil { return nil, err } return nil, commandctrl.ScheduleTask(ctx, func(ctx context.Context) error { _, err := block.Invoke(ctx) return err }) } func (m asyncModule) asyncIn(ctx context.Context, args ucl.CallArgs) (any, error) { var ( duration int block ucl.Invokable ) if err := args.Bind(&duration, &block); err != nil { return nil, err } _, err := commandctrl.CronScheduler(ctx).NewJob( gocron.OneTimeJob( gocron.OneTimeJobStartDateTime(time.Now().Add(time.Duration(duration)*time.Second)), ), gocron.NewTask(func(ctx context.Context) { commandctrl.ScheduleTask(ctx, func(ctx context.Context) error { _, err := block.Invoke(ctx) return err }) }), gocron.WithContext(ctx), ) return nil, err } func (m asyncModule) asyncQuery(ctx context.Context, args ucl.CallArgs) (any, error) { var ( block ucl.Invokable ) args, q, tableInfo, err := parseQuery(ctx, args, m.state.ResultSet(), m.tableService, 1) if err != nil { return nil, err } if err := args.Bind(&block); err != nil { return nil, err } return nil, commandctrl.ScheduleAuxTask(ctx, "query: "+q.String(), func(ctx context.Context) error { newResultSet, err := m.tableService.ScanOrQuery(context.Background(), tableInfo, q, nil) if err != nil { return err } return commandctrl.ScheduleTask(ctx, func(ctx context.Context) error { _, err := block.Invoke(ctx, newResultSetProxy(newResultSet)) return err }) }) } func moduleAsync(tableService *tables.Service, state *controllers.State) ucl.Module { m := asyncModule{ state: state, tableService: tableService, } return ucl.Module{ Name: "async", Builtins: map[string]ucl.BuiltinHandler{ "do": m.asyncDo, "in": m.asyncIn, "query": m.asyncQuery, }, } }