I have two functions with similar functionality that I use to test concurrency. However, FetchUserForAuthV1 starts throwing errors with fewer requests compared to FetchUserForAuth. I’m sharing code snippets for both functions and would appreciate any suggestions for improvement.
Problem Description:
The function FetchUserForAuthV1 fails sooner under concurrent load compared to FetchUserForAuth. In FetchUserForAuthV1, I used a struct to pass the query and its FetchRows method to retrieve rows from the database. The intention was to utilize common functions to minimize code duplication.
Here’s the relevant error message:
context deadline exceeded
The error occurs in the following code block (refer common_db_operations.go):
tx, err := dbConnection.BeginTx(ctx, pgx.TxOptions{AccessMode: pgx.ReadWrite})
if err != nil {
logger.Logger.Error("MODELS :: Error while begin transaction", zap.Error(err), zap.String("requestId", uuidString))
return id, err
}
Code Snippets:
Function FetchUserForAuth:
func FetchUserForAuth(email string) UserSchema {
logger.Logger.Info("MODELS :: Will fetch user details for auth", zap.String("email", email))
var userData UserSchema
dbConnection := DbPool()
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
// ctx := context.Background()
tx, err := dbConnection.BeginTx(ctx, pgx.TxOptions{AccessMode: pgx.ReadOnly})
if err != nil {
logger.Logger.Error("MODELS :: Error while begin transaction", zap.Error(err))
return userData
}
defer func() {
if err != nil {
tx.Rollback(ctx)
} else {
tx.Commit(ctx)
}
}()
query := fmt.Sprintf(`SELECT
u.id,
u.first_name,
u.last_name,
u.email,
u.password
FROM users u
WHERE u.email='%s' LIMIT 1`, email)
logger.Logger.Info("MODELS :: Query", zap.String("query", query))
err = tx.QueryRow(ctx, query).Scan(
&userData.Id,
&userData.FirstName,
&userData.LastName,
&userData.Email,
&userData.Password,
)
if err != nil {
if err == pgx.ErrNoRows {
logger.Logger.Info("MODELS :: Query - No rows found. ", zap.String("query", query))
return userData
}
logger.Logger.Error("MODELS :: Error while executing query.",
zap.Error(err),
)
return userData
}
return userData
}
Function FetchUserForAuthV1:
func FetchUserForAuthV1(email string) UserSchema {
logger.Logger.Info("MODELS :: Will fetch user details for auth v1", zap.String("email", email))
var userData UserSchema
query := fmt.Sprintf(`SELECT
u.id,
u.first_name,
u.last_name,
u.email,
u.password
FROM users u
WHERE u.email='%s' LIMIT 1`, email)
logger.Logger.Info("MODELS :: Query", zap.String("query", query))
queryToExecute := QueryStructToExecute{Query: query}
rows, _, err := queryToExecute.FetchRows("")
logger.Logger.Info("user models : ", zap.Any("rows ", rows), zap.Error(err))
if err != nil {
return userData
}
if len(rows) == 0 {
return userData
}
singleRow := rows[0]
jsonbody, err := json.Marshal(singleRow)
if err != nil {
// do error check
fmt.Println(err)
}
if err := json.Unmarshal(jsonbody, &userData); err != nil {
// do error check
fmt.Println(err)
}
logger.Logger.Info("MODELS :: before sending dat a", zap.Any("data", userData), zap.Any("id", userData.Id))
return userData
}
Additional Information
Reference Code: common_db_operations.go
GitHub Discussion: Link to discussion
GitHub Repo: prismatic-be
Request for Help
Could you please provide any insights or suggestions on how to resolve the issue with FetchUserForAuthV1?
4