(new): expand runtime APIs
(fix): harden concurrent lifecycle (tests): add regression coverage (doc): update v1.2 guidance
This commit is contained in:
+14
-6
@@ -10,6 +10,8 @@ import (
|
||||
"git.scuroneko.dev/scuroneko/sneklog/v2"
|
||||
)
|
||||
|
||||
var errMiddlewareBlocked = errors.New("middleware blocked call")
|
||||
|
||||
// Plugin represents a collection of commands and payloads (e.g., callback handlers),
|
||||
// with shared middleware and configuration.
|
||||
//
|
||||
@@ -268,7 +270,7 @@ func (p *Plugin[T]) executeCmd(cmd string, ctx *MessageContext, db T) error {
|
||||
// Run command-specific middlewares
|
||||
for _, m := range command.middlewares {
|
||||
if !m.Execute(ctx, db) {
|
||||
return AsInternalError(errors.New("middleware blocked call"))
|
||||
return errMiddlewareBlocked
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,7 +291,7 @@ func (p *Plugin[T]) executePayload(payload string, ctx *MessageContext, db T) er
|
||||
// Run command-specific middlewares
|
||||
for _, m := range command.middlewares {
|
||||
if !m.Execute(ctx, db) {
|
||||
return AsInternalError(errors.New("middleware blocked call"))
|
||||
return errMiddlewareBlocked
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,6 +365,7 @@ func (m Middleware[T]) SetAsync(async bool) Middleware[T] {
|
||||
// continue to share storage with the synchronous flow. Async middleware
|
||||
// must treat those fields as read-only — mutating them races the sync chain
|
||||
// that mutates the same context concurrently.
|
||||
// Bot runtimes wait for tracked asynchronous middleware before returning.
|
||||
func (m Middleware[T]) Execute(ctx *MessageContext, db T) bool {
|
||||
if m.executor == nil {
|
||||
reportMiddlewareError(ctx, m.name, ErrMiddlewareExecutorNil)
|
||||
@@ -370,14 +373,19 @@ func (m Middleware[T]) Execute(ctx *MessageContext, db T) bool {
|
||||
}
|
||||
if m.async {
|
||||
ctxCopy := *ctx
|
||||
go func(ctx MessageContext) {
|
||||
task := func() {
|
||||
defer func() {
|
||||
if recovered := recover(); recovered != nil {
|
||||
reportMiddlewareError(&ctx, m.name, fmt.Errorf("%w in middleware %q: %v", ErrHandlerPanic, m.name, recovered))
|
||||
reportMiddlewareError(&ctxCopy, m.name, fmt.Errorf("%w in middleware %q: %v", ErrHandlerPanic, m.name, recovered))
|
||||
}
|
||||
}()
|
||||
m.executor(&ctx, db)
|
||||
}(ctxCopy)
|
||||
m.executor(&ctxCopy, db)
|
||||
}
|
||||
if ctx.asyncTask != nil {
|
||||
ctx.asyncTask(task)
|
||||
} else {
|
||||
go task()
|
||||
}
|
||||
return true
|
||||
}
|
||||
result := false
|
||||
|
||||
Reference in New Issue
Block a user