2026-04-27 02:29:42 +08:00

65 lines
1.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"context"
"google.golang.org/protobuf/proto"
roomv1 "hyapp/api/proto/room/v1"
"hyapp/services/room-service/internal/room/cell"
"hyapp/services/room-service/internal/room/rank"
)
func (s *Service) currentSnapshot(ctx context.Context, roomID string) (*roomv1.RoomSnapshot, error) {
if roomCell := s.loadCell(roomID); roomCell != nil {
// 内存 Cell 是最新状态来源guard 查询优先读它。
currentState, _, err := roomCell.Snapshot(ctx)
if err != nil {
return nil, err
}
return currentState.ToProto(), nil
}
// 没有内存 Cell 时从 meta + snapshot + command log 恢复,避免守卫读到落后于 command log 的旧快照。
roomMeta, exists, err := s.repository.GetRoomMeta(ctx, roomID)
if err != nil || !exists {
return nil, err
}
restoredState, err := s.recoverRoom(ctx, roomMeta)
if err != nil {
// 恢复失败说明持久化状态不可用,不能让外部 IM 入口自行放行。
return nil, err
}
roomCell := cell.New(restoredState, rank.FromState(restoredState.GiftRank, s.rankLimit))
s.installCell(roomID, roomCell)
return restoredState.ToProto(), nil
}
func (s *Service) persistSnapshot(ctx context.Context, snapshot *roomv1.RoomSnapshot) error {
// 快照统一使用 protobuf保持和跨服务契约一致。
payload, err := proto.Marshal(snapshot)
if err != nil {
return err
}
return s.repository.SaveSnapshot(ctx, SnapshotRecord{
RoomID: snapshot.GetRoomId(),
RoomVersion: snapshot.GetVersion(),
Payload: payload,
CreatedAt: s.clock.Now(),
})
}
func shouldSnapshot(snapshot *roomv1.RoomSnapshot, every int64) bool {
if snapshot == nil || every <= 1 {
// every<=1 表示每次有快照结果都保存nil 快照永远不保存。
return snapshot != nil
}
// 按房间版本取模做简单采样,避免引入额外计数状态。
return snapshot.GetVersion()%every == 0
}