fix: 좀비 슬롯 정리 및 보상 실패 상태 추적
- RequestEntry() 시 CheckStaleSlots() 호출하여 좀비 슬롯 자동 정리 - 블록체인 보상 실패 시 BossRoom 상태를 reward_failed로 업데이트 - UpdateRoomStatus() 레포지토리 메서드 추가 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ const (
|
|||||||
StatusInProgress RoomStatus = "in_progress"
|
StatusInProgress RoomStatus = "in_progress"
|
||||||
StatusCompleted RoomStatus = "completed"
|
StatusCompleted RoomStatus = "completed"
|
||||||
StatusFailed RoomStatus = "failed"
|
StatusFailed RoomStatus = "failed"
|
||||||
|
StatusRewardFailed RoomStatus = "reward_failed"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BossRoom represents a boss raid session room.
|
// BossRoom represents a boss raid session room.
|
||||||
|
|||||||
@@ -219,6 +219,17 @@ func (r *Repository) ResetStaleSlots(threshold time.Time) (int64, error) {
|
|||||||
return result.RowsAffected, result.Error
|
return result.RowsAffected, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateRoomStatus updates only the status of a boss room by session name.
|
||||||
|
func (r *Repository) UpdateRoomStatus(sessionName string, status RoomStatus) error {
|
||||||
|
result := r.db.Model(&BossRoom{}).
|
||||||
|
Where("session_name = ?", sessionName).
|
||||||
|
Update("status", status)
|
||||||
|
if result.RowsAffected == 0 {
|
||||||
|
return fmt.Errorf("방을 찾을 수 없습니다: %s", sessionName)
|
||||||
|
}
|
||||||
|
return result.Error
|
||||||
|
}
|
||||||
|
|
||||||
// GetRoomSlotsByServer returns all room slots for a given server.
|
// GetRoomSlotsByServer returns all room slots for a given server.
|
||||||
func (r *Repository) GetRoomSlotsByServer(serverID uint) ([]RoomSlot, error) {
|
func (r *Repository) GetRoomSlotsByServer(serverID uint) ([]RoomSlot, error) {
|
||||||
var slots []RoomSlot
|
var slots []RoomSlot
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ func (s *Service) SetExpGranter(fn func(username string, exp int) error) {
|
|||||||
// Allocates an idle room slot from a registered dedicated server.
|
// Allocates an idle room slot from a registered dedicated server.
|
||||||
// Returns the room with assigned session name.
|
// Returns the room with assigned session name.
|
||||||
func (s *Service) RequestEntry(usernames []string, bossID int) (*BossRoom, error) {
|
func (s *Service) RequestEntry(usernames []string, bossID int) (*BossRoom, error) {
|
||||||
|
// 좀비 슬롯 정리 — idle 슬롯 검색 전에 stale 인스턴스를 리셋
|
||||||
|
s.CheckStaleSlots()
|
||||||
|
|
||||||
if len(usernames) == 0 {
|
if len(usernames) == 0 {
|
||||||
return nil, fmt.Errorf("플레이어 목록이 비어있습니다")
|
return nil, fmt.Errorf("플레이어 목록이 비어있습니다")
|
||||||
}
|
}
|
||||||
@@ -222,6 +225,7 @@ func (s *Service) CompleteRaid(sessionName string, rewards []PlayerReward) (*Bos
|
|||||||
|
|
||||||
// Grant rewards outside the transaction to avoid holding the lock during RPC calls
|
// Grant rewards outside the transaction to avoid holding the lock during RPC calls
|
||||||
resultRewards = make([]RewardResult, 0, len(rewards))
|
resultRewards = make([]RewardResult, 0, len(rewards))
|
||||||
|
hasRewardFailure := false
|
||||||
if s.rewardGrant != nil {
|
if s.rewardGrant != nil {
|
||||||
for _, r := range rewards {
|
for _, r := range rewards {
|
||||||
grantErr := s.rewardGrant(r.Username, r.TokenAmount, r.Assets)
|
grantErr := s.rewardGrant(r.Username, r.TokenAmount, r.Assets)
|
||||||
@@ -229,11 +233,19 @@ func (s *Service) CompleteRaid(sessionName string, rewards []PlayerReward) (*Bos
|
|||||||
if grantErr != nil {
|
if grantErr != nil {
|
||||||
result.Error = grantErr.Error()
|
result.Error = grantErr.Error()
|
||||||
log.Printf("보상 지급 실패: %s: %v", r.Username, grantErr)
|
log.Printf("보상 지급 실패: %s: %v", r.Username, grantErr)
|
||||||
|
hasRewardFailure = true
|
||||||
}
|
}
|
||||||
resultRewards = append(resultRewards, result)
|
resultRewards = append(resultRewards, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 보상 실패가 있으면 상태를 reward_failed로 업데이트
|
||||||
|
if hasRewardFailure {
|
||||||
|
if err := s.repo.UpdateRoomStatus(sessionName, StatusRewardFailed); err != nil {
|
||||||
|
log.Printf("보상 실패 상태 업데이트 실패: %s: %v", sessionName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Grant experience to players
|
// Grant experience to players
|
||||||
if s.expGrant != nil {
|
if s.expGrant != nil {
|
||||||
for _, r := range rewards {
|
for _, r := range rewards {
|
||||||
|
|||||||
Reference in New Issue
Block a user