-
Notifications
You must be signed in to change notification settings - Fork 16
BCDA-9314: refactor API db connection globals #1171
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
Conversation
bcda/bcdacli/cli.go
Outdated
| app.Before = func(c *cli.Context) error { | ||
| db = database.Connection | ||
| r = postgres.NewRepository(db) | ||
| connection = database.GetConnection() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is an entrypoint at which we can create the database connection and pass it as a dependency to the routers and services that need it.
bcda/api/v1/api.go
Outdated
| } | ||
|
|
||
| func init() { | ||
| func NewApiV1(connection *sql.DB, pool *pgxv5Pool.Pool) *ApiV1 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following the example of the tech spec, we create a new struct for the API that clearly defines its dependencies (including the database connections!) with a constructor.
| app.Version = constants.Version | ||
| app.Before = func(c *cli.Context) error { | ||
| db = database.Connection | ||
| db = database.Connect() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Construct connections and provider at code entrypoint to be passed down to APIs, routers, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because we are no longer using the *cli.App for command line usage, it would be nice to eventually move away from this since this is where top level DI would occur. just a thought - way too big of a lift for this PR.
oversimplification, but something like:
type App {
api http.server
auth http.server
data http.server
pool sql.db/pgx
c config
s service
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a great idea, and I would vote to do this in a separate tech debt ticket that would remove the cli, if that works for you.
| river.WorkerDefaults[worker_types.CleanupJobArgs] | ||
| cleanupJob func(time.Time, models.JobStatus, models.JobStatus, ...string) error | ||
| archiveExpiring func(time.Time) error | ||
| cleanupJob func(*sql.DB, time.Time, models.JobStatus, models.JobStatus, ...string) error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably not suited for changes in this PR, but if we are updating the DB depenedencies, would cleanupJob and archiveExpiring be better suited as methods with CleanupJobWorker being the receiver? they would have access to db via CleanupJobWorker.db instead of having to pass it in. Thoughts on maybe leaving a comment on here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely, I actually thought the same thing and wondered why they were in separate files.
I left a comment for now but I'm open to changing it if folks feel strongly about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can leave a TODO + a ticket for this one for future work to minimize risk?
|
|
||
| func NewAuthRouter(middlewares ...func(http.Handler) http.Handler) http.Handler { | ||
| func NewAuthRouter(provider Provider, middlewares ...func(http.Handler) http.Handler) http.Handler { | ||
| baseApi := NewBaseApi(provider) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am certain this is user error, but I don't see the definition for this anywhere with cmd+f - does this func definition exist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, which function are we talking about? If it's NewBaseApi, I created that in bcda/auth/api.go
|
The two failing CI checks likely just need to update to latest changes on main. |
these failing on the aurora name? |
laurenkrugen-navapbc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super happy to remove these inits from the codebase - thanks so much for knocking this out! 🎉
🎫 Ticket
https://jira.cms.gov/browse/BCDA-9314
https://jira.cms.gov/browse/BCDA-9287
🛠 Changes
connectfunctions, which establish new connections to the database and replace init and global connection variablesconnectfunctions with separate health checksauth/Provider.goto not be a global, either, and instead be configured at setup and passed down like the database connectionsTo-Do:
ℹ️ Context
This PR demonstrates a strategy to refactor the database Connection -- specifically, to remove the global Connection variables defined in /database/connection.go which are created in an init() function, and instead do the following:
As a result, many other files needed to be changed to store the db connection within its state, including the API files and middleware. Notably, the Provider, which also depends on the db connection, was also being used as a global across many files, so it too had to be updated to a stateful type which is constructed at entrypoints.
Finally, many tests were updated to account for these changes. The majority of the test updates were completely innocuous -- replacing references to a global connection with references to a constructed connection -- but others involved untangling hidden dependencies on the database, provider, etc. that became very obvious after they were refactored.
🧪 Validation