(new): rich message support
Golang lint / lint (pull_request) Successful in 1m20s
Golang lint / lint (push) Successful in 4m8s

(fix): runtime reliability
(tests): regression coverage
(doc): v1.1 release notes
This commit is contained in:
2026-08-12 16:34:44 +03:00
parent 48ddf66540
commit f03a081ed6
83 changed files with 6122 additions and 1925 deletions
+17 -9
View File
@@ -2,6 +2,7 @@ package laniakea
import (
"context"
"fmt"
"time"
)
@@ -27,6 +28,18 @@ type Runner[T AppData] struct {
fn RunnerFn[T] // The function to execute
}
func executeRunner[T AppData](runner Runner[T], bot *Bot[T]) (err error) {
defer func() {
if recovered := recover(); recovered != nil {
err = fmt.Errorf("runner %q panicked: %v", runner.name, recovered)
}
}()
if runner.fn == nil {
return fmt.Errorf("runner %q has no function", runner.name)
}
return runner.fn(bot)
}
// NewRunner creates a new Runner with the given name and function.
//
// The default configuration is async=true and every=0, i.e. a one-shot
@@ -34,12 +47,7 @@ type Runner[T AppData] struct {
// to customize this. Do not call builder methods concurrently or after the
// bot runtime has begun executing runners.
func NewRunner[T AppData](name string, fn RunnerFn[T]) Runner[T] {
return Runner[T]{
name: name,
fn: fn,
async: true,
every: 0,
}
return Runner[T]{name: name, fn: fn, async: true, every: 0}
}
// Async sets whether the runner executes synchronously or asynchronously.
@@ -89,7 +97,7 @@ func (bot *Bot[T]) ExecRunners(ctx context.Context) {
go func(r Runner[T]) {
defer bot.runnerOnceWG.Done()
startedAt := time.Now()
err := r.fn(bot)
err := executeRunner(r, bot)
bot.safeEmitEvent(ctx, RunnerFinishedEvent{
Name: r.name,
Duration: time.Since(startedAt),
@@ -109,7 +117,7 @@ func (bot *Bot[T]) ExecRunners(ctx context.Context) {
} else if runner.every == 0 && !runner.async {
// One-time sync: block until done
t := time.Now()
err := runner.fn(bot)
err := executeRunner(runner, bot)
elapsed := time.Since(t)
bot.safeEmitEvent(ctx, RunnerFinishedEvent{
Name: runner.name,
@@ -150,7 +158,7 @@ func (bot *Bot[T]) ExecRunners(ctx context.Context) {
return
}
startedAt := time.Now()
err := r.fn(bot)
err := executeRunner(r, bot)
bot.safeEmitEvent(ctx, RunnerFinishedEvent{
Name: r.name,
Duration: time.Since(startedAt),