Browse Source

Improve memory safety with `defer` for event cleanup across handlers, optimize conditional logging, and bump version to `v0.4.3`.

main
mleku 4 months ago
parent
commit
2dd119401b
No known key found for this signature in database
  1. 55
      app/handle-req.go
  2. 12
      pkg/database/export.go
  3. 3
      pkg/encoders/event/binary_test.go
  4. 2
      pkg/version/version

55
app/handle-req.go

@ -115,9 +115,14 @@ func (l *Listener) HandleReq(msg []byte) (err error) {
} }
} }
// Use a separate context for QueryEvents to prevent cancellation issues // Use a separate context for QueryEvents to prevent cancellation issues
queryCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second) queryCtx, cancel := context.WithTimeout(
context.Background(), 30*time.Second,
)
defer cancel() defer cancel()
log.T.F("HandleReq: About to QueryEvents for %s, main context done: %v", l.remote, l.ctx.Err() != nil) log.T.F(
"HandleReq: About to QueryEvents for %s, main context done: %v",
l.remote, l.ctx.Err() != nil,
)
if events, err = l.QueryEvents(queryCtx, f); chk.E(err) { if events, err = l.QueryEvents(queryCtx, f); chk.E(err) {
if errors.Is(err, badger.ErrDBClosed) { if errors.Is(err, badger.ErrDBClosed) {
return return
@ -125,22 +130,40 @@ func (l *Listener) HandleReq(msg []byte) (err error) {
log.T.F("HandleReq: QueryEvents error for %s: %v", l.remote, err) log.T.F("HandleReq: QueryEvents error for %s: %v", l.remote, err)
err = nil err = nil
} }
log.T.F("HandleReq: QueryEvents completed for %s, found %d events", l.remote, len(events)) defer func() {
for _, ev := range events {
ev.Free()
}
}()
log.T.F(
"HandleReq: QueryEvents completed for %s, found %d events",
l.remote, len(events),
)
} }
var tmp event.S var tmp event.S
privCheck: privCheck:
for _, ev := range events { for _, ev := range events {
if kind.IsPrivileged(ev.Kind) && if kind.IsPrivileged(ev.Kind) &&
accessLevel != "admin" { // admins can see all events accessLevel != "admin" { // admins can see all events
log.I.F("checking privileged event %s", ev.ID) log.T.C(
func() string {
return fmt.Sprintf(
"checking privileged event %0x", ev.ID,
)
},
)
pk := l.authedPubkey.Load() pk := l.authedPubkey.Load()
if pk == nil { if pk == nil {
continue continue
} }
if utils.FastEqual(ev.Pubkey, pk) { if utils.FastEqual(ev.Pubkey, pk) {
log.I.F( log.T.C(
"privileged event %s is for logged in pubkey %0x", ev.ID, func() string {
pk, return fmt.Sprintf(
"privileged event %s is for logged in pubkey %0x",
ev.ID, pk,
)
},
) )
tmp = append(tmp, ev) tmp = append(tmp, ev)
continue continue
@ -152,18 +175,26 @@ privCheck:
continue continue
} }
if utils.FastEqual(pt, pk) { if utils.FastEqual(pt, pk) {
log.I.F( log.T.C(
func() string {
return fmt.Sprintf(
"privileged event %s is for logged in pubkey %0x", "privileged event %s is for logged in pubkey %0x",
ev.ID, pk, ev.ID, pk,
) )
},
)
tmp = append(tmp, ev) tmp = append(tmp, ev)
continue privCheck continue privCheck
} }
} }
log.W.F( log.T.C(
func() string {
return fmt.Sprintf(
"privileged event %s does not contain the logged in pubkey %0x", "privileged event %s does not contain the logged in pubkey %0x",
ev.ID, pk, ev.ID, pk,
) )
},
)
} else { } else {
tmp = append(tmp, ev) tmp = append(tmp, ev)
} }
@ -171,10 +202,14 @@ privCheck:
events = tmp events = tmp
seen := make(map[string]struct{}) seen := make(map[string]struct{})
for _, ev := range events { for _, ev := range events {
log.T.F( log.D.C(
func() string {
return fmt.Sprintf(
"REQ %s: sending EVENT id=%s kind=%d", env.Subscription, "REQ %s: sending EVENT id=%s kind=%d", env.Subscription,
hex.Enc(ev.ID), ev.Kind, hex.Enc(ev.ID), ev.Kind,
) )
},
)
log.T.C( log.T.C(
func() string { func() string {
return fmt.Sprintf("event:\n%s\n", ev.Serialize()) return fmt.Sprintf("event:\n%s\n", ev.Serialize())

12
pkg/database/export.go

@ -43,14 +43,16 @@ func (d *D) Export(c context.Context, w io.Writer, pubkeys ...[]byte) {
continue continue
} }
// Serialize the event to JSON and write it to the output // Serialize the event to JSON and write it to the output
defer func(ev *event.E) {
ev.Free()
evBuf.Reset()
}(ev)
if _, err = w.Write(ev.Serialize()); chk.E(err) { if _, err = w.Write(ev.Serialize()); chk.E(err) {
return return
} }
if _, err = w.Write([]byte{'\n'}); chk.E(err) { if _, err = w.Write([]byte{'\n'}); chk.E(err) {
return return
} }
ev.Free()
evBuf.Reset()
} }
return return
}, },
@ -88,14 +90,16 @@ func (d *D) Export(c context.Context, w io.Writer, pubkeys ...[]byte) {
continue continue
} }
// Serialize the event to JSON and write it to the output // Serialize the event to JSON and write it to the output
defer func(ev *event.E) {
ev.Free()
evBuf.Reset()
}(ev)
if _, err = w.Write(ev.Serialize()); chk.E(err) { if _, err = w.Write(ev.Serialize()); chk.E(err) {
continue continue
} }
if _, err = w.Write([]byte{'\n'}); chk.E(err) { if _, err = w.Write([]byte{'\n'}); chk.E(err) {
continue continue
} }
ev.Free()
evBuf.Reset()
} }
return return
}, },

3
pkg/encoders/event/binary_test.go

@ -48,6 +48,9 @@ func TestTMarshalBinary_UnmarshalBinary(t *testing.T) {
// Marshal unmarshaled binary event back to JSON // Marshal unmarshaled binary event back to JSON
unmarshaledJSON := eb.Serialize() unmarshaledJSON := eb.Serialize()
defer func(ev *E) {
eb.Free()
}(eb)
// Compare the two JSON representations // Compare the two JSON representations
if !utils.FastEqual(b, unmarshaledJSON) { if !utils.FastEqual(b, unmarshaledJSON) {

2
pkg/version/version

@ -1 +1 @@
v0.4.2 v0.4.3
Loading…
Cancel
Save