Skip to content
This repository was archived by the owner on Oct 8, 2022. It is now read-only.

Conversation

@c1-ra
Copy link

@c1-ra c1-ra commented Mar 8, 2022

Description

Enable to store computed stats in a pgsql database.

Changes

Add a StatsService with connection to the database
Add a Create() method to this service computed stats in database.

Notes

/

@c1-ra c1-ra force-pushed the feat/store-processed-stats-in-pgsql-database branch from 57d8238 to 0521bf3 Compare March 8, 2022 23:43
@c1-ra c1-ra linked an issue Mar 8, 2022 that may be closed by this pull request
2 tasks
@c1-ra c1-ra force-pushed the feat/store-processed-stats-in-pgsql-database branch 4 times, most recently from 84d2784 to 6758db7 Compare March 9, 2022 11:29
@c1-ra c1-ra marked this pull request as ready for review March 9, 2022 11:48
@c1-ra
Copy link
Author

c1-ra commented Mar 9, 2022

I have prepared the insertCodestats statement to add to Create(), using #8 current work.
It works when I test it, but waiting for #8 to be merged to change some imports before adding the commit.
Feel free to review meanwhile though, since the action of inserting codestats will be almost like the previous ones (except for the statement).

@c1-ra c1-ra force-pushed the feat/store-processed-stats-in-pgsql-database branch from c84cf7a to e25a58f Compare March 9, 2022 11:57
Comment on lines 7 to 29
var (
// ErrEnvironmentVariable is returned when the worker fails to find
// the environment variables necessary to connect to the database.
ErrEnvironmentVariable = errors.New("could not find all necessary environment variables")
// ErrDatabaseConnection is returned when the worker fails to connect to
// the database.
ErrDatabaseConnection = errors.New("database connection error")
// ErrDatabasePing is returned when the worker fails to ping the
// database.
ErrDatabasePing = errors.New("database ping error")
// ErrPreparingStmt is returned when the worker fails to prepare
// a prepared statement.
ErrPreparingStmt = errors.New("error executing prepared statement")
// ErrExecutingPreparedStmt is returned when the worker fails to execute
// a query with a prepared statement.
ErrExecutingPreparedStmt = errors.New("error executing prepared statement")
// ErrScanningRows is returned when the worker fails to scan the rows
// returned by a query.
ErrScanningRows = errors.New("error trying to scan result rows")
// ErrExecutingRollback is returned when the worker fails to rollback
// in a transaction.
ErrExecutingRollback = errors.New("error trying to rollback a transaction in database")
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] I'd skip error handling on this repo and always return raw errors: they'll be logged for us (not users) so let's not obfuscate them

Suggested change
var (
// ErrEnvironmentVariable is returned when the worker fails to find
// the environment variables necessary to connect to the database.
ErrEnvironmentVariable = errors.New("could not find all necessary environment variables")
// ErrDatabaseConnection is returned when the worker fails to connect to
// the database.
ErrDatabaseConnection = errors.New("database connection error")
// ErrDatabasePing is returned when the worker fails to ping the
// database.
ErrDatabasePing = errors.New("database ping error")
// ErrPreparingStmt is returned when the worker fails to prepare
// a prepared statement.
ErrPreparingStmt = errors.New("error executing prepared statement")
// ErrExecutingPreparedStmt is returned when the worker fails to execute
// a query with a prepared statement.
ErrExecutingPreparedStmt = errors.New("error executing prepared statement")
// ErrScanningRows is returned when the worker fails to scan the rows
// returned by a query.
ErrScanningRows = errors.New("error trying to scan result rows")
// ErrExecutingRollback is returned when the worker fails to rollback
// in a transaction.
ErrExecutingRollback = errors.New("error trying to rollback a transaction in database")
)

Comment on lines 49 to 37
func GetConfigFromEnvVariables() (Config, error) {
var config Config

err := godotenv.Load(".env")
// no error returned here because .env is not deployed
if err != nil {
fmt.Println("no .env file found")
}

config.Host = os.Getenv("PSQL_HOST")
if config.Host == "" {
return config, ErrEnvironmentVariable
}

config.User = os.Getenv("PSQL_USER")
if config.User == "" {
return config, ErrEnvironmentVariable
}

config.Password = os.Getenv("PSQL_PASSWORD")
if config.Password == "" {
return config, ErrEnvironmentVariable
}

config.DBName = os.Getenv("PSQL_NAME")
if config.DBName == "" {
return config, ErrEnvironmentVariable
}

config.IdleConn = 10
config.MaxConn = 25

return config, nil
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] I'd rather do this in the main function:

cfg, err := envConfig() // very early in the function
statsService, err := postgresql.NewStatsService(cfg)

// connection is ok, compute stuff and store to db

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by main function? In a main package? There is none at the moment.
I thought we could only connect when the computing of the stats has ended 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here the "main" function is worker.Digest.
Why compute all the data if in the end we cannot connect to the database? That's why I suggest to make all the necessary checks upstream

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the opposite, I was thinking why bother connecting to the database if we fail to compute the data? 😅

Copy link
Member

@GregoryAlbouy GregoryAlbouy Mar 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say because the computing part is supposed to be the heavier and longer task (that's the reason we have a worker after all) 😛
It's debatable for the connection part I agree, however I'm convinced the params checking at least should be done before anything. Connecting to the db right after getting the config also allows to gather related logics by using the config closer to where it's retrieved.
But maybe we'll want to keep that connection as short as possible (i.e. closed during processing), in which case we'd better do it at the end.
🤷‍♂️

Copy link
Author

@c1-ra c1-ra Mar 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, you've convinced me, let's do it at the beginning of worker.Digestsince worker should indeed be heavier!

@c1-ra c1-ra force-pushed the feat/store-processed-stats-in-pgsql-database branch from cbb51a7 to 5f43e4d Compare March 9, 2022 14:42
@c1-ra c1-ra force-pushed the feat/store-processed-stats-in-pgsql-database branch 2 times, most recently from 25a0da7 to 635a7c4 Compare March 9, 2022 19:09
+ slight refactor of Insert() method to use less parameters
@c1-ra c1-ra force-pushed the feat/store-processed-stats-in-pgsql-database branch from 635a7c4 to 035836a Compare March 9, 2022 19:12
Copy link
Member

@moreirathomas moreirathomas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion regarding Config location.

Do we want to wait for auth flow for UserID before merging ?


// Config contains the information needed to connect to the database
// and set max idle connections and open connections number.
type Config struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Config of postgresql db does not belong to benchttp package I think.

Simply move it to postegresql and we're fine :)

Comment on lines 18 to +20
// Digest is a Cloud Function triggered by a Firestore create document
// event to extract, compute and store statistics of a Benchttp run.
// It also stores the computed data in a SQL database.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Digest is a Cloud Function triggered by a Firestore create document
// event to extract, compute and store statistics of a Benchttp run.
// It also stores the computed data in a SQL database.
// Digest is a Cloud Function triggered by a Firestore create document
// event to extract, compute and store statistics of a Benchttp run
// database a SQL database.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Store processed stats in sql database

4 participants