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

Fix request scoped transactions #3103

Merged
merged 4 commits into from
Sep 6, 2022
Merged

Fix request scoped transactions #3103

merged 4 commits into from
Sep 6, 2022

Conversation

dnephin
Copy link
Contributor

@dnephin dnephin commented Sep 1, 2022

Summary

Branched from #3028 this PR cleans up the commits from #3032 to fix both #2697 and #3076

We had two problems with our request scoped transactions:

  1. the transaction was never rolled back on error, it was always comitted
  2. we never reported a failure to commit a transaction to the user

This PR addresses the problems by:

  • moving the transaction to wrapRoute, which has access to the error from both the middleware and the handlers
  • in wrapRoute add a defer which will rollback if commit has not happened
  • and respond with a 500 response code if the transaction fails to commit

Related Issues

Resolves #2697
Resolves #3076

@dnephin dnephin force-pushed the dnephin/fix-request-txn branch 2 times, most recently from a40b397 to ab282d5 Compare September 1, 2022 21:18
"github.com/infrahq/infra/internal/access"
"github.com/infrahq/infra/internal/server/models"
)

func pprofHandler(c *gin.Context) {
func pprofHandler(c *gin.Context, _ *api.EmptyRequest) (*api.EmptyResponse, error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now that the database transaction comes from wrapRoute this handler had to be updated to fit the interface required by wrapRoute.

@@ -108,30 +108,6 @@ func TestBindsEmptyRequest(t *testing.T) {
assert.NilError(t, err)
}

func TestGetRoute(t *testing.T) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this test was probably useful before, but now it does not really do much. We have good test coverage for all of our real production routes, so we don't need to test an artificial route.

@@ -70,40 +70,31 @@ func handleInfraDestinationHeader(c *gin.Context) error {
// authenticatedMiddleware is applied to all routes that require authentication.
// It validates the access key, and updates the lastSeenAt of the user, and
// possibly also of the destination.
func authenticatedMiddleware(srv *Server) gin.HandlerFunc {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the name "authenticatedMiddleware" is confusing here where this is just an auth check and scope now, it doesnt actually pass the request through any middleware

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Very true, I'll rename this to remove "middlware", and I should also update the godoc at the same time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I pushed a commit that renames these to authenticateRequest, and validateRequestOrganization. What do you think of those names?

bindRoute(a, group.RouterGroup, route.method, route.path, handler)
}

func wrapRoute[Req, Res any](a *API, route route[Req, Res]) func(*gin.Context) error {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would like to see a comment explaining that wrapRoute effectively functions as a middleware for requests, there is a lot going on in here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call, there is a lot going on here. #3104 is a follow up PR that reduces it a bit.

More godoc here would be better. I'll add that now.

@dnephin dnephin force-pushed the dnephin/fix-request-txn branch 2 times, most recently from d3984ae to b1171c9 Compare September 2, 2022 19:50
Base automatically changed from dnephin/data-txn-metadata to main September 6, 2022 15:52
And handle sendAPIError once, instead of on every error.
To store the behaviour of different routes. This is temporary until
we can set these on the route definition directly.
This commit fixes two bugs related to request scoped transactions.
Now that they are no longer middleware.

Also document wrapRoute.
@dnephin dnephin merged commit 08417c5 into main Sep 6, 2022
@dnephin dnephin deleted the dnephin/fix-request-txn branch September 6, 2022 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants