fix(feishu): add message cache for fetchMessageByID to avoid repeated downloads
- Add messageCache (sync.Map) to FeishuChannel struct - Cache fetched messages with 30s TTL to avoid re-downloading attachments when multiple users reply to the same parent message in a thread - Cleanup expired entries on read access (no background goroutine needed)
This commit is contained in:
parent
a149761022
commit
9627846e5b
2 changed files with 21 additions and 2 deletions
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/sipeed/picoclaw/pkg/bus"
|
"github.com/sipeed/picoclaw/pkg/bus"
|
||||||
"github.com/sipeed/picoclaw/pkg/channels"
|
"github.com/sipeed/picoclaw/pkg/channels"
|
||||||
|
|
@ -42,11 +43,17 @@ type FeishuChannel struct {
|
||||||
tokenCache *tokenCache // custom cache that supports invalidation
|
tokenCache *tokenCache // custom cache that supports invalidation
|
||||||
|
|
||||||
botOpenID atomic.Value // stores string; populated lazily for @mention detection
|
botOpenID atomic.Value // stores string; populated lazily for @mention detection
|
||||||
|
messageCache sync.Map // caches fetched messages (messageID -> *larkim.Message)
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type cachedMessage struct {
|
||||||
|
msg *larkim.Message
|
||||||
|
expiry time.Time
|
||||||
|
}
|
||||||
|
|
||||||
func NewFeishuChannel(cfg config.FeishuConfig, bus *bus.MessageBus) (*FeishuChannel, error) {
|
func NewFeishuChannel(cfg config.FeishuConfig, bus *bus.MessageBus) (*FeishuChannel, error) {
|
||||||
base := channels.NewBaseChannel("feishu", cfg, bus, cfg.AllowFrom,
|
base := channels.NewBaseChannel("feishu", cfg, bus, cfg.AllowFrom,
|
||||||
channels.WithGroupTrigger(cfg.GroupTrigger),
|
channels.WithGroupTrigger(cfg.GroupTrigger),
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ import (
|
||||||
"github.com/sipeed/picoclaw/pkg/utils"
|
"github.com/sipeed/picoclaw/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const messageCacheTTL = 30 * time.Second
|
||||||
|
|
||||||
const (
|
const (
|
||||||
maxReplyContextLen = 600
|
maxReplyContextLen = 600
|
||||||
)
|
)
|
||||||
|
|
@ -122,6 +124,14 @@ func (c *FeishuChannel) resolveReplyTargetMessageID(ctx context.Context, message
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FeishuChannel) fetchMessageByID(ctx context.Context, messageID string) (*larkim.Message, error) {
|
func (c *FeishuChannel) fetchMessageByID(ctx context.Context, messageID string) (*larkim.Message, error) {
|
||||||
|
if cached, ok := c.messageCache.Load(messageID); ok {
|
||||||
|
cm := cached.(*cachedMessage)
|
||||||
|
if time.Now().Before(cm.expiry) {
|
||||||
|
return cm.msg, nil
|
||||||
|
}
|
||||||
|
c.messageCache.Delete(messageID)
|
||||||
|
}
|
||||||
|
|
||||||
req := larkim.NewGetMessageReqBuilder().
|
req := larkim.NewGetMessageReqBuilder().
|
||||||
MessageId(messageID).
|
MessageId(messageID).
|
||||||
Build()
|
Build()
|
||||||
|
|
@ -138,7 +148,9 @@ func (c *FeishuChannel) fetchMessageByID(ctx context.Context, messageID string)
|
||||||
return nil, fmt.Errorf("feishu get message: empty response")
|
return nil, fmt.Errorf("feishu get message: empty response")
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp.Data.Items[0], nil
|
msg := resp.Data.Items[0]
|
||||||
|
c.messageCache.Store(messageID, &cachedMessage{msg: msg, expiry: time.Now().Add(messageCacheTTL)})
|
||||||
|
return msg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func replyTargetID(message *larkim.EventMessage) string {
|
func replyTargetID(message *larkim.EventMessage) string {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue