feat: 完整游戏运维功能

This commit is contained in:
npc0-hue
2026-07-18 09:04:01 +08:00
parent f3b14b7945
commit 48b8ad8d6c
187 changed files with 16607 additions and 1140 deletions
+22 -14
View File
@@ -86,6 +86,18 @@ func (store *MemoryLogBodyStore) Query(streamID string, afterSeq uint64, limit i
return selected, nextSeq, nil
}
func (store *MemoryLogBodyStore) LatestSeq(streamID string) (uint64, error) {
store.mu.Lock()
defer store.mu.Unlock()
var latest uint64
for _, entry := range store.entries[streamID] {
if entry.Seq > latest {
latest = entry.Seq
}
}
return latest, nil
}
type FileLogBodyStore struct {
mu sync.Mutex
rootDir string
@@ -101,7 +113,7 @@ func NewFileLogBodyStore(rootDir string) (*FileLogBodyStore, error) {
rootDir: rootDir,
memory: NewMemoryLogBodyStore(),
}
if err := os.MkdirAll(rootDir, 0o755); err != nil {
if err := os.MkdirAll(rootDir, 0o700); err != nil {
return nil, fmt.Errorf("create log directory: %w", err)
}
if err := store.load(); err != nil {
@@ -124,7 +136,7 @@ func (store *FileLogBodyStore) AppendBatch(streamID string, record domain.LogBat
return store.memory.AppendBatch(streamID, record)
}
streamDir := store.streamDir(streamID)
if err := os.MkdirAll(streamDir, 0o755); err != nil {
if err := os.MkdirAll(streamDir, 0o700); err != nil {
return fmt.Errorf("create log stream directory: %w", err)
}
segmentPath := store.segmentPath(streamID, record.FirstSeq)
@@ -133,23 +145,15 @@ func (store *FileLogBodyStore) AppendBatch(streamID string, record domain.LogBat
} else if !os.IsNotExist(err) {
return fmt.Errorf("stat log segment: %w", err)
}
tmpPath := segmentPath + ".tmp"
file, err := os.OpenFile(tmpPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0o600)
if err != nil {
return fmt.Errorf("open log segment: %w", err)
}
encoder := json.NewEncoder(file)
var body strings.Builder
encoder := json.NewEncoder(&body)
for _, entry := range record.Entries {
if err := encoder.Encode(domain.CopyLogEntry(entry)); err != nil {
_ = file.Close()
return fmt.Errorf("write log segment: %w", err)
}
}
if err := file.Close(); err != nil {
return fmt.Errorf("close log segment: %w", err)
}
if err := os.Rename(tmpPath, segmentPath); err != nil {
return fmt.Errorf("replace log segment: %w", err)
if err := writeAtomicFile(segmentPath, []byte(body.String()), 0o600); err != nil {
return fmt.Errorf("persist log segment: %w", err)
}
return store.memory.AppendBatch(streamID, record)
}
@@ -162,6 +166,10 @@ func (store *FileLogBodyStore) Query(streamID string, afterSeq uint64, limit int
return store.memory.Query(streamID, afterSeq, limit)
}
func (store *FileLogBodyStore) LatestSeq(streamID string) (uint64, error) {
return store.memory.LatestSeq(streamID)
}
func (store *FileLogBodyStore) load() error {
entries, err := os.ReadDir(store.rootDir)
if err != nil {