Skip to content

Commit

Permalink
AppV2: ensure isolation of handler state per request
Browse files Browse the repository at this point in the history
Implemented a new duplication mechanism for the handler to create
separate instances per request. This change addresses an issue where the
same handler instance was shared across multiple requests, leading to
state leakage and inconsistencies in AppV2.

Each request now uses a fresh handler instance, ensuring isolated and
consistent state management.

Updates goplus/builder#532

Signed-off-by: Aofei Sheng <aofei@aofeisheng.com>
  • Loading branch information
aofei committed May 28, 2024
1 parent 72ad5b0 commit f5e250b
Showing 1 changed file with 13 additions and 3 deletions.
16 changes: 13 additions & 3 deletions classfile_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,22 @@ type iHandler interface {
func Gopt_AppV2_Main(app AppType, handlers ...iHandler) {
app.InitYap()
for _, h := range handlers {
reflect.ValueOf(h).Elem().Field(1).Set(reflect.ValueOf(app)) // (*handler).AppV2 = app
hVal := reflect.ValueOf(h).Elem()
hVal.FieldByName("AppV2").Set(reflect.ValueOf(app))
hType := hVal.Type()
handle := func(ctx *Context) {
// We must duplicate the handler instance for each request
// to ensure state isolation.
h2Val := reflect.New(hType).Elem()
h2Val.Set(hVal)
h2 := h2Val.Addr().Interface().(iHandler)
h2.Main(ctx)
}
switch method, path := parseClassfname(h.Classfname()); method {
case "handle":
app.Handle(path, h.Main)
app.Handle(path, handle)
default:
app.Route(strings.ToUpper(method), path, h.Main)
app.Route(strings.ToUpper(method), path, handle)
}
}
if me, ok := app.(interface{ MainEntry() }); ok {
Expand Down

0 comments on commit f5e250b

Please sign in to comment.