group chat: handle events synchronously in select, drop goroutine and mutex

This commit is contained in:
Yasuhiro Matsumoto
2026-06-04 15:05:59 -03:00
committed by fiatjaf
parent 52cf03d423
commit f7a00cec10
+12 -48
View File
@@ -276,68 +276,32 @@ var group = &cli.Command{
return err return err
} }
// stored events arrive newest-first before EOSE, so we buffer them
// from the end and print them in chronological order once EOSE
// arrives; live events are printed as they come.
eosed := false eosed := false
var mu sync.Mutex messages := make([]string, 200)
messages := make([]struct {
message string
rendered bool
}, 200)
base := len(messages) base := len(messages)
// must be called with mu held
tryRender := func(i int) {
// if all messages before these are loaded we can render this,
// otherwise we render whatever we can and stop
for m, msg := range messages[base:] {
if msg.rendered {
continue
}
if msg.message == "" {
break
}
messages[base+m].rendered = true
stdout(msg.message)
}
}
for { for {
select { select {
case evt := <-sub.Events: case evt := <-sub.Events:
mu.Lock() meta := sys.FetchProfileMetadata(ctx, evt.PubKey)
var i int line := color.HiBlueString(meta.ShortName()) + " " + color.HiCyanString(evt.CreatedAt.Time().Format(time.DateTime)) + ": " + evt.Content
if eosed { if eosed {
i = len(messages) stdout(line)
messages = append(messages, struct {
message string
rendered bool
}{})
} else if base > 0 { } else if base > 0 {
base-- base--
i = base messages[base] = line
} else {
// pre-EOSE buffer is full (relay returned more than the limit); drop.
mu.Unlock()
continue
} }
mu.Unlock() // else: pre-EOSE buffer is full (relay returned more than the limit); drop.
go func() {
meta := sys.FetchProfileMetadata(ctx, evt.PubKey)
line := color.HiBlueString(meta.ShortName()) + " " + color.HiCyanString(evt.CreatedAt.Time().Format(time.DateTime)) + ": " + evt.Content
mu.Lock()
messages[i].message = line
if eosed {
tryRender(i)
}
mu.Unlock()
}()
case reason := <-sub.ClosedReason: case reason := <-sub.ClosedReason:
stdout("closed:" + color.YellowString(reason)) stdout("closed:" + color.YellowString(reason))
case <-sub.EndOfStoredEvents: case <-sub.EndOfStoredEvents:
mu.Lock()
eosed = true eosed = true
tryRender(len(messages) - 1) for _, msg := range messages[base:] {
mu.Unlock() stdout(msg)
}
case <-sub.Context.Done(): case <-sub.Context.Done():
return fmt.Errorf("subscription ended: %w", context.Cause(sub.Context)) return fmt.Errorf("subscription ended: %w", context.Cause(sub.Context))
} }