init
This commit is contained in:
99
cmd/internal/peer/persist.go
Normal file
99
cmd/internal/peer/persist.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package peer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"omnisocketgo/cmd/internal/latencylog"
|
||||
"omnisocketgo/cmd/internal/protocol"
|
||||
)
|
||||
|
||||
const textInboxFileName = "messages.log"
|
||||
|
||||
type textInboxRecord struct {
|
||||
MessageType protocol.MessageType `json:"message_type"`
|
||||
MessageID uint64 `json:"message_id"`
|
||||
From string `json:"from"`
|
||||
To string `json:"to"`
|
||||
Body string `json:"body"`
|
||||
}
|
||||
|
||||
// PersistMessage 将收到的业务消息写入本地磁盘,并记录处理完成节点。
|
||||
func (c *Client) PersistMessage(msg protocol.Message, inboxDir string) (string, error) {
|
||||
if !latencylog.IsBusinessMessage(msg) {
|
||||
return "", fmt.Errorf("peer: cannot persist message type %s", msg.Type)
|
||||
}
|
||||
if inboxDir == "" {
|
||||
return "", fmt.Errorf("peer: inbox directory is required")
|
||||
}
|
||||
|
||||
latencylog.LogMessageEvent(c.logger, latencylog.NodeRolePeer, c.id, latencylog.EventBPersistBegin, msg)
|
||||
|
||||
if err := os.MkdirAll(inboxDir, 0o755); err != nil {
|
||||
return "", fmt.Errorf("peer: create inbox dir %s: %w", inboxDir, err)
|
||||
}
|
||||
|
||||
path, err := persistMessageToDisk(msg, inboxDir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
latencylog.LogMessageEvent(c.logger, latencylog.NodeRolePeer, c.id, latencylog.EventBPersistEnd, msg)
|
||||
|
||||
return path, nil
|
||||
}
|
||||
|
||||
// persistMessageToDisk 根据消息类型将消息内容写入磁盘,文本消息追加到文本日志文件,文件消息写成独立文件。
|
||||
func persistMessageToDisk(msg protocol.Message, inboxDir string) (string, error) {
|
||||
switch msg.Type {
|
||||
case protocol.MessageTypeText:
|
||||
return persistTextMessage(msg, inboxDir)
|
||||
case protocol.MessageTypeFile:
|
||||
return persistFileMessage(msg, inboxDir)
|
||||
default:
|
||||
return "", fmt.Errorf("peer: cannot persist unsupported message type %s", msg.Type)
|
||||
}
|
||||
}
|
||||
|
||||
// registerPeer 验证 peer ID 的合法性和唯一性,并将其与连接关联起来。
|
||||
func persistTextMessage(msg protocol.Message, inboxDir string) (string, error) {
|
||||
record := textInboxRecord{
|
||||
MessageType: msg.Type,
|
||||
MessageID: msg.ID,
|
||||
From: msg.From,
|
||||
To: msg.To,
|
||||
Body: string(msg.Body),
|
||||
}
|
||||
|
||||
line, err := json.Marshal(record)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("peer: encode text inbox record: %w", err)
|
||||
}
|
||||
|
||||
path := filepath.Join(inboxDir, textInboxFileName)
|
||||
file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o644)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("peer: open text inbox %s: %w", path, err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
if _, err := file.Write(append(line, '\n')); err != nil {
|
||||
return "", fmt.Errorf("peer: append text inbox %s: %w", path, err)
|
||||
}
|
||||
|
||||
return path, nil
|
||||
}
|
||||
|
||||
// persistFileMessage 将文件消息的内容写成独立文件,文件名包含发送方、消息 ID 和原始文件名,保证唯一性和可读性。
|
||||
func persistFileMessage(msg protocol.Message, inboxDir string) (string, error) {
|
||||
fileName := filepath.Base(msg.FileName)
|
||||
path := filepath.Join(inboxDir, fmt.Sprintf("%s-%d-%s", msg.From, msg.ID, fileName))
|
||||
|
||||
if err := os.WriteFile(path, msg.Body, 0o644); err != nil {
|
||||
return "", fmt.Errorf("peer: write received file %s: %w", path, err)
|
||||
}
|
||||
|
||||
return path, nil
|
||||
}
|
||||
Reference in New Issue
Block a user