Skip to content

Commit e1df472

Browse files
committed
fix: clean up code
1 parent 3c670b0 commit e1df472

File tree

1 file changed

+60
-59
lines changed

1 file changed

+60
-59
lines changed

pkg/models/room.go

Lines changed: 60 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ const (
3232
backoffJitter = 0.2
3333
)
3434

35+
var timeoutErr = errors.New("timeout reached")
36+
3537
type RoomModel struct {
3638
ctx context.Context
3739
app *config.AppConfig
@@ -82,39 +84,32 @@ func (m *RoomModel) SetBreakoutRoomModel(bm *BreakoutRoomModel) {
8284
m.breakoutModel = bm
8385
}
8486

85-
func acquireRoomCreationLockWithRetry(ctx context.Context, rs *redisservice.RedisService, roomID string, log *logrus.Entry) (string, error) {
86-
maxWaitTime := defaultRoomCreationMaxWaitTime
87-
lockTTL := defaultRoomCreationLockTTL
87+
// performWithBackoff is a helper that executes a function with an exponential backoff retry strategy.
88+
func performWithBackoff(ctx context.Context, maxWaitTime time.Duration, log *logrus.Entry, action func() (bool, error)) error {
8889
currentInterval := backoffInitialInterval
89-
9090
loopStartTime := time.Now()
91-
log.Info("attempting to acquire room creation lock")
9291

9392
for {
9493
select {
9594
case <-ctx.Done():
96-
log.WithError(ctx.Err()).Warn("Context cancelled while waiting for room creation lock")
97-
return "", fmt.Errorf("lock acquisition cancelled for room '%s': %w", roomID, ctx.Err())
95+
log.WithError(ctx.Err()).Warn("Context cancelled during backoff")
96+
return ctx.Err()
9897
default:
9998
}
10099

101-
acquired, lockValue, errLock := rs.LockRoomCreation(ctx, roomID, lockTTL)
102-
if errLock != nil {
103-
log.WithError(errLock).Error("Redis error while attempting to acquire room creation lock")
104-
return "", fmt.Errorf("redis communication error for room '%s' lock: %w", roomID, errLock)
100+
done, err := action()
101+
if err != nil {
102+
log.WithError(err).Error("Error during backoff action")
103+
return err
105104
}
106105

107-
if acquired {
108-
log.WithFields(logrus.Fields{
109-
"lockValue": lockValue,
110-
"duration": time.Since(loopStartTime),
111-
}).Info("successfully acquired room creation lock")
112-
return lockValue, nil
106+
if done {
107+
return nil
113108
}
114109

115110
if time.Since(loopStartTime) >= maxWaitTime {
116-
log.WithField("maxWaitTime", maxWaitTime).Warn("Timeout while waiting for room creation lock")
117-
return "", errors.New("timeout waiting to acquire lock for room " + roomID + ", operation is currently locked")
111+
log.WithField("maxWaitTime", maxWaitTime).Warn("Timeout during backoff")
112+
return timeoutErr
118113
}
119114

120115
// Calculate next interval with jitter
@@ -124,12 +119,12 @@ func acquireRoomCreationLockWithRetry(ctx context.Context, rs *redisservice.Redi
124119
log.WithFields(logrus.Fields{
125120
"waitDuration": waitDuration,
126121
"elapsed": time.Since(loopStartTime),
127-
}).Debug("Room creation lock not acquired. Waiting.")
122+
}).Debug("Action not complete. Waiting.")
128123
select {
129124
case <-time.After(waitDuration):
130125
case <-ctx.Done():
131-
log.WithError(ctx.Err()).Warn("Context cancelled while polling for room creation lock")
132-
return "", fmt.Errorf("lock acquisition polling cancelled for room '%s': %w", roomID, ctx.Err())
126+
log.WithError(ctx.Err()).Warn("Context cancelled while waiting for next backoff attempt")
127+
return ctx.Err()
133128
}
134129
currentInterval = time.Duration(float64(currentInterval) * backoffMultiplier)
135130
if currentInterval > backoffMaxInterval {
@@ -138,52 +133,58 @@ func acquireRoomCreationLockWithRetry(ctx context.Context, rs *redisservice.Redi
138133
}
139134
}
140135

141-
// waitUntilRoomCreationCompletes waits until the room creation lock for the given roomID is released.
142-
func waitUntilRoomCreationCompletes(ctx context.Context, rs *redisservice.RedisService, roomID string, log *logrus.Entry) error {
143-
maxWaitTime := defaultWaitForRoomCreationMaxWaitTime
144-
currentInterval := backoffInitialInterval
145-
loopStartTime := time.Now()
136+
func acquireRoomCreationLockWithRetry(ctx context.Context, rs *redisservice.RedisService, roomID string, log *logrus.Entry) (string, error) {
137+
maxWaitTime := defaultRoomCreationMaxWaitTime
138+
lockTTL := defaultRoomCreationLockTTL
139+
var lockValue string
146140

147-
for {
148-
select {
149-
case <-ctx.Done():
150-
log.WithError(ctx.Err()).Warn("Context cancelled while waiting for room creation to complete")
151-
return fmt.Errorf("waiting for room creation to complete cancelled for room '%s': %w", roomID, ctx.Err())
152-
default:
153-
}
141+
log.Info("Attempting to acquire room creation lock")
154142

155-
isLocked, errCheck := rs.IsRoomCreationLock(ctx, roomID)
156-
if errCheck != nil {
157-
log.WithError(errCheck).Error("Redis error while checking room creation lock")
158-
return fmt.Errorf("redis communication error while checking room '%s' creation lock: %w", roomID, errCheck)
143+
action := func() (bool, error) {
144+
acquired, val, err := rs.LockRoomCreation(ctx, roomID, lockTTL)
145+
if err != nil {
146+
return false, fmt.Errorf("redis communication error for room '%s' lock: %w", roomID, err)
159147
}
160-
161-
if !isLocked {
162-
return nil
148+
if acquired {
149+
lockValue = val
150+
return true, nil
163151
}
152+
return false, nil
153+
}
164154

165-
if time.Since(loopStartTime) >= maxWaitTime {
166-
log.WithField("maxWaitTime", maxWaitTime).Warn("Timeout while waiting for room creation to complete")
167-
return fmt.Errorf("timeout waiting for room creation of room '%s' to complete", roomID)
155+
err := performWithBackoff(ctx, maxWaitTime, log, action)
156+
if err != nil {
157+
if errors.Is(err, timeoutErr) {
158+
return "", errors.New("timeout waiting to acquire lock for room " + roomID + ", operation is currently locked")
168159
}
160+
return "", fmt.Errorf("lock acquisition cancelled for room '%s': %w", roomID, err)
161+
}
169162

170-
// Calculate next interval with jitter
171-
jitter := time.Duration(rand.Float64() * backoffJitter * float64(currentInterval))
172-
waitDuration := currentInterval + jitter
163+
log.WithFields(logrus.Fields{
164+
"lockValue": lockValue,
165+
}).Info("Successfully acquired room creation lock")
166+
return lockValue, nil
167+
}
173168

174-
log.WithFields(logrus.Fields{
175-
"waitDuration": waitDuration,
176-
"elapsed": time.Since(loopStartTime),
177-
}).Debug("Room creation is still in progress. Waiting.")
178-
select {
179-
case <-time.After(waitDuration):
180-
case <-ctx.Done():
181-
log.WithError(ctx.Err()).Warn("Context cancelled while polling for room creation to complete")
182-
return fmt.Errorf("polling for room creation to complete cancelled for room '%s': %w", roomID, ctx.Err())
169+
// waitUntilRoomCreationCompletes waits until the room creation lock for the given roomID is released.
170+
func waitUntilRoomCreationCompletes(ctx context.Context, rs *redisservice.RedisService, roomID string, log *logrus.Entry) error {
171+
maxWaitTime := defaultWaitForRoomCreationMaxWaitTime
172+
173+
action := func() (bool, error) {
174+
isLocked, err := rs.IsRoomCreationLock(ctx, roomID)
175+
if err != nil {
176+
return false, fmt.Errorf("redis communication error while checking room '%s' creation lock: %w", roomID, err)
183177
}
184-
currentInterval = time.Duration(float64(currentInterval) * backoffMultiplier)
185-
if currentInterval > backoffMaxInterval {
186-
currentInterval = backoffMaxInterval
178+
return !isLocked, nil
179+
}
180+
181+
err := performWithBackoff(ctx, maxWaitTime, log, action)
182+
if err != nil {
183+
if errors.Is(err, timeoutErr) {
184+
return fmt.Errorf("timeout waiting for room creation of room '%s' to complete", roomID)
187185
}
186+
return fmt.Errorf("waiting for room creation to complete cancelled for room '%s': %w", roomID, err)
188187
}
188+
189+
return nil
189190
}

0 commit comments

Comments
 (0)