func afterTask(ctx *app.Context, task *Task, started time.Time, terr *error) { name := task.Name() if err := recover(); err != nil { skip, stackSkip, _, _ := runtimeutil.GetPanic() var buf bytes.Buffer fmt.Fprintf(&buf, "Panic executing task %s: %v\n", name, err) stack := runtimeutil.FormatStack(stackSkip) location, code := runtimeutil.FormatCaller(skip, 5, true, true) if location != "" { buf.WriteString("\n At ") buf.WriteString(location) if code != "" { buf.WriteByte('\n') buf.WriteString(code) buf.WriteByte('\n') } } if stack != "" { buf.WriteString("\nStack:\n") buf.WriteString(stack) } *terr = errors.New(buf.String()) } end := time.Now() running.Lock() defer running.Unlock() c := running.tasks[task] - 1 if c > 0 { running.tasks[task] = c } else { delete(running.tasks, task) } ctx.Logger().Infof("Finished task %s (%d instances now running) at %v (took %v)", name, c, end, end.Sub(started)) }
func executeTask(ctx *app.Context, task *Task) (ran bool, err error) { var n int if n, err = numberOfInstances(task); err != nil { return } started := time.Now() ctx.Logger().Infof("Starting task %s (%d instances now running) at %v", task.Name(), n, started) ran = true defer afterTask(ctx, task, started, &err) task.Handler(ctx) return }
func gondolaRunTasksHandler(ctx *app.Context) { if ctx.GetHeader("X-Appengine-Cron") != "true" { ctx.Forbidden("") return } pendingTasks.Lock() for _, v := range pendingTasks.tasks { task := v ctx.Go(func(c *app.Context) { if _, err := executeTask(c, task); err != nil { ctx.Logger().Error(err) } }) } pendingTasks.tasks = nil pendingTasks.Unlock() ctx.Wait() }
func registerUser(ctx *app.Context) { username := ctx.RequireIndexValue(0) userVal, _ := newEmptyUser(ctx) updating := false if ctx.Orm().MustOne(ByUsername(username), userVal.Interface()) { // Updating existing user updating = true } else { // Creating a new one userVal = newUser(ctx, username) } var askPassword bool ctx.ParseParamValue("p", &askPassword) if !updating || askPassword { password1, err := speakeasy.Ask("Password:"******"Confirm Password:"******"passwords don't match")) } setUserValue(userVal, "Password", password.New(password1)) } var admin bool ctx.ParseParamValue("s", &admin) setUserValue(userVal, "Admin", admin) var email string ctx.ParseParamValue("e", &email) if email != "" { setUserValue(userVal, "Email", email) } ctx.Orm().MustSave(userVal.Interface()) ctx.Logger().Infof("saved user as %+v", userVal.Interface()) }