feat(post): add idempotency support for post creation with client request ID
Add client_request_id field to post creation endpoints (CreateVotePost and CreatePostWithSegments). When provided, the server uses Redis SetNX-based idempotency to prevent duplicate posts from double-clicks or network retries within a 24-hour TTL. Duplicate requests return the originally created post; concurrent in-flight requests return 429 "正在发布中,请稍候".
This commit is contained in:
21
internal/cache/keys.go
vendored
21
internal/cache/keys.go
vendored
@@ -38,12 +38,15 @@ const (
|
||||
PrefixChannelsAllList = "channels:all_list"
|
||||
|
||||
// 消息缓存相关
|
||||
keyPrefixMsgHash = "msg_hash" // 消息详情 Hash
|
||||
keyPrefixMsgIndex = "msg_index" // 消息索引 Sorted Set
|
||||
keyPrefixMsgCount = "msg_count" // 消息计数
|
||||
keyPrefixMsgSeq = "msg_seq" // Seq 计数器
|
||||
keyPrefixMsgPage = "msg_page" // 分页缓存
|
||||
keyPrefixMsgIdempotent = "msg_idem" // 消息幂等键
|
||||
keyPrefixMsgHash = "msg_hash" // 消息详情 Hash
|
||||
keyPrefixMsgIndex = "msg_index" // 消息索引 Sorted Set
|
||||
keyPrefixMsgCount = "msg_count" // 消息计数
|
||||
keyPrefixMsgSeq = "msg_seq" // Seq 计数器
|
||||
keyPrefixMsgPage = "msg_page" // 分页缓存
|
||||
keyPrefixMsgIdempotent = "msg_idem" // 消息幂等键
|
||||
|
||||
// 帖子创建幂等键前缀(clientRequestID -> 已创建的 postID)
|
||||
keyPrefixPostIdempotent = "post_idem"
|
||||
)
|
||||
|
||||
// PostListKey 生成帖子列表缓存键
|
||||
@@ -197,6 +200,12 @@ func MessageIdempotentKey(senderID, clientMsgID string) string {
|
||||
return fmt.Sprintf("%s:%s:%s", keyPrefixMsgIdempotent, senderID, clientMsgID)
|
||||
}
|
||||
|
||||
// PostCreateIdempotentKey 帖子创建幂等键 (userID + clientRequestID -> postID)
|
||||
// 用于在 SetNX 原子抢占期间识别同一客户端请求的重试,避免重复发帖。
|
||||
func PostCreateIdempotentKey(userID, clientRequestID string) string {
|
||||
return fmt.Sprintf("%s:%s:%s", keyPrefixPostIdempotent, userID, clientRequestID)
|
||||
}
|
||||
|
||||
// UserReadSeqKey 用户已读位置缓存键(OpenIM 风格 SEQ_USER_READ:{convID}:{userID})
|
||||
func UserReadSeqKey(convID, userID string) string {
|
||||
return fmt.Sprintf("%s:%s:%s", PrefixUserReadSeq, convID, userID)
|
||||
|
||||
Reference in New Issue
Block a user