Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kyc/quiz: remove ErrSessionIsAlreadyRunning #98

Merged
merged 2 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion cmd/eskimo-hut/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ const (

noPendingLoginSessionErrorCode = "NO_PENDING_LOGIN_SESSION"

quizAlreadyRunningErrorCode = "QUIZ_ALREADY_RUNNING"
quizUnknownQuestionNumErrorCode = "QUIZ_UNKNOWN_QUESTION_NUM"

socialKYCStepAlreadyCompletedSuccessfullyErrorCode = "SOCIAL_KYC_STEP_ALREADY_COMPLETED_SUCCESSFULLY"
Expand Down
3 changes: 0 additions & 3 deletions cmd/eskimo-hut/kyc.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,6 @@ func (s *service) StartOrContinueKYCStep4Session( //nolint:gocritic,funlen // .
case errors.Is(err, kycquiz.ErrUnknownUser):
return nil, server.NotFound(err, userNotFoundErrorCode)

case errors.Is(err, kycquiz.ErrSessionIsAlreadyRunning):
return nil, server.ForbiddenWithCode(errors.Errorf("another quiz session is already running"), quizAlreadyRunningErrorCode)

case errors.Is(err, kycquiz.ErrSessionFinished), errors.Is(err, kycquiz.ErrSessionFinishedWithError), errors.Is(err, kycquiz.ErrInvalidKYCState): //nolint:lll // .
return nil, server.BadRequest(err, raceConditionErrorCode)

Expand Down
1 change: 0 additions & 1 deletion kyc/quiz/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ var (
ErrUnknownLanguage = newError("unknown language")
ErrInvalidKYCState = newError("invalid KYC state")
ErrUnknownUser = newError("unknown user")
ErrSessionIsAlreadyRunning = newError("another session is already running")
ErrSessionFinished = newError("session closed")
ErrSessionFinishedWithError = newError("session closed with error")
ErrUnknownQuestionNumber = newError("unknown question number")
Expand Down
23 changes: 8 additions & 15 deletions kyc/quiz/quiz.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,14 @@ func wrapErrorInTx(err error) error {
return err
}

func (r *repositoryImpl) finishExpiredSession( //nolint:funlen //.
func (r *repositoryImpl) finishUnfinishedSession( //nolint:funlen //.
ctx context.Context,
userID UserID,
now *time.Time,
tx storage.QueryExecer,
) (*time.Time, error) {
// $1: user_id.
// $2: max session duration (seconds).
// $3: session cool down (seconds).
// $2: session cool down (seconds).
const stmt = `
with result as (
update quiz_sessions
Expand All @@ -207,8 +206,7 @@ func (r *repositoryImpl) finishExpiredSession( //nolint:funlen //.
ended_successfully = false
where
user_id = $1 and
ended_at is null and
started_at + make_interval(secs => $2) < now()
ended_at is null
returning *
)
insert into failed_quiz_sessions (started_at, ended_at, questions, answers, language, user_id, skipped)
Expand All @@ -223,11 +221,11 @@ func (r *repositoryImpl) finishExpiredSession( //nolint:funlen //.
from
result
returning
ended_at + make_interval(secs => $3) as cooldown_at
ended_at + make_interval(secs => $2) as cooldown_at
`
data, err := storage.ExecOne[struct {
CooldownAt *time.Time `db:"cooldown_at"`
}](ctx, tx, stmt, userID, r.config.MaxSessionDurationSeconds, r.config.SessionCoolDownSeconds)
}](ctx, tx, stmt, userID, r.config.SessionCoolDownSeconds)
if err != nil {
if errors.Is(err, storage.ErrNotFound) {
err = nil
Expand All @@ -239,10 +237,9 @@ func (r *repositoryImpl) finishExpiredSession( //nolint:funlen //.
return data.CooldownAt, errors.Wrapf(r.modifyUser(ctx, false, now, userID), "failed to modifyUser")
}

func (r *repositoryImpl) startNewSession( //nolint:funlen,revive //.
func (r *repositoryImpl) startNewSession( //nolint:funlen //.
ctx context.Context,
userID UserID,
now *time.Time,
tx storage.QueryExecer,
lang string,
questions []*Question,
Expand Down Expand Up @@ -354,10 +351,6 @@ func (r *repositoryImpl) startNewSession( //nolint:funlen,revive //.
return nil, ErrSessionFinishedWithError
}

if data.ActiveDeadline.After(*now.Time) {
return nil, errors.Wrapf(ErrSessionIsAlreadyRunning, "wait %s before next session", data.ActiveDeadline.Sub(*now.Time))
}

case data.UpsertStartedAt != nil: // New session is started.
return &Quiz{
Progress: &Progress{
Expand All @@ -379,7 +372,7 @@ func (r *repositoryImpl) StartQuizSession(ctx context.Context, userID UserID, la

err = storage.DoInTransaction(ctx, r.DB, func(tx storage.QueryExecer) error {
now := time.Now()
cooldown, fErr := r.finishExpiredSession(ctx, userID, now, tx)
cooldown, fErr := r.finishUnfinishedSession(ctx, userID, now, tx)
if fErr != nil {
return wrapErrorInTx(fErr)
} else if cooldown != nil {
Expand All @@ -391,7 +384,7 @@ func (r *repositoryImpl) StartQuizSession(ctx context.Context, userID UserID, la
return wrapErrorInTx(err)
}

quiz, err = r.startNewSession(ctx, userID, now, tx, lang, questions)
quiz, err = r.startNewSession(ctx, userID, tx, lang, questions)

return wrapErrorInTx(err)
})
Expand Down
2 changes: 1 addition & 1 deletion kyc/quiz/quiz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func testManagerSessionStart(ctx context.Context, t *testing.T, r *repositoryImp
})
t.Run("AlreadyExists", func(t *testing.T) {
_, err := r.StartQuizSession(ctx, "bogus", "en")
require.ErrorIs(t, err, ErrSessionIsAlreadyRunning)
require.ErrorIs(t, err, ErrSessionFinishedWithError)
})
t.Run("Finished", func(t *testing.T) {
t.Run("Success", func(t *testing.T) {
Expand Down
Loading