-
Notifications
You must be signed in to change notification settings - Fork 2
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
Make sure the HTTP call is never made inside a database transaction. #1099
Open
GeoffreyHuck
wants to merge
18
commits into
master
Choose a base branch
from
1081
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
1e4c869
Make sure `SchedulePropagation` is never called inside a transaction …
GeoffreyHuck acd5bf0
Inject the endpoint in the request context and allow to access the co…
GeoffreyHuck 2b87da4
This constant is only used in this file, so it doesn't have to be pub…
GeoffreyHuck faf2c9f
Rename the function into `StartAsyncPropagation`, it's clearer what i…
GeoffreyHuck 3e53ee0
The propagation is now called after the current transaction. Update t…
GeoffreyHuck 4ecc6bf
`SchedulePropagation`: make sure the types of propagation are unique …
GeoffreyHuck d4ecc20
Fix lint order of imports.
GeoffreyHuck 469b28f
Fix lint cyclomatic complexity: schedule propagation in `updateChildr…
GeoffreyHuck 354d2e5
Update test: we have one more middleware to inject the endpoint confi…
GeoffreyHuck dd140bf
Cleanup: function not used anymore.
GeoffreyHuck f74233d
All the propagations are now async.
GeoffreyHuck 46b8a27
Fix typo.
GeoffreyHuck 3c34f0e
In the migrate command, we need to call the propagation now and not s…
GeoffreyHuck 2626486
In the unit tests, the propagation endpoint hasn't been injected. Thi…
GeoffreyHuck 460f923
The group propagation, when scheduled, should be run before the async…
GeoffreyHuck bd079a0
Fix test. Since we run all propagations async, and the system does al…
GeoffreyHuck 27d5a62
Fix test. Since we run all propagations async, and the system does al…
GeoffreyHuck 0415b3b
Merge pull request #1100 from France-ioi/1047
GeoffreyHuck File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,8 @@ import ( | |
"context" | ||
"time" | ||
|
||
"github.com/France-ioi/AlgoreaBackend/app/utils" | ||
|
||
"github.com/France-ioi/AlgoreaBackend/app/rand" | ||
) | ||
|
||
|
@@ -176,10 +178,11 @@ func (s *DataStore) NewID() int64 { | |
} | ||
|
||
type awaitingTriggers struct { | ||
ItemAncestors bool | ||
GroupAncestors bool | ||
Permissions bool | ||
Results bool | ||
ItemAncestors bool | ||
GroupAncestors bool | ||
Permissions bool | ||
Results bool | ||
SchedulePropagationTypes []string | ||
} | ||
type dbContextKey string | ||
|
||
|
@@ -206,6 +209,16 @@ func (s *DataStore) InTransaction(txFunc func(*DataStore) error) error { | |
triggersToRun.GroupAncestors = false | ||
s.createNewAncestors("groups", "group") | ||
} | ||
if len(triggersToRun.SchedulePropagationTypes) > 0 { | ||
types := triggersToRun.SchedulePropagationTypes | ||
triggersToRun.SchedulePropagationTypes = []string{} | ||
|
||
propagationEndpoint := "" | ||
if s.Context().Value("propagation_endpoint") != nil { | ||
propagationEndpoint = s.Context().Value("propagation_endpoint").(string) | ||
} | ||
StartAsyncPropagation(s, propagationEndpoint, types) | ||
} | ||
if triggersToRun.ItemAncestors { | ||
triggersToRun.ItemAncestors = false | ||
s.createNewAncestors("items", "item") | ||
|
@@ -222,6 +235,14 @@ func (s *DataStore) InTransaction(txFunc func(*DataStore) error) error { | |
return err | ||
} | ||
|
||
// SchedulePropagation schedules a run of the propagation for the given types after the transaction commit. | ||
func (s *DataStore) SchedulePropagation(types []string) { | ||
s.mustBeInTransaction() | ||
|
||
triggersToRun := s.DB.ctx.Value(triggersContextKey).(*awaitingTriggers) | ||
triggersToRun.SchedulePropagationTypes = utils.UniqueStrings(append(triggersToRun.SchedulePropagationTypes, types...)) | ||
} | ||
|
||
// ScheduleResultsPropagation schedules a run of ResultStore::propagate() after the transaction commit. | ||
func (s *DataStore) ScheduleResultsPropagation() { | ||
s.mustBeInTransaction() | ||
|
@@ -262,10 +283,6 @@ func (s *DataStore) WithForeignKeyChecksDisabled(blockFunc func(*DataStore) erro | |
}) | ||
} | ||
|
||
func (s *DataStore) IsInTransaction() bool { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was a nice useful method. |
||
return s.DB.isInTransaction() | ||
} | ||
|
||
// WithNamedLock wraps the given function in GET_LOCK/RELEASE_LOCK. | ||
func (s *DataStore) WithNamedLock(lockName string, timeout time.Duration, txFunc func(*DataStore) error) error { | ||
return s.withNamedLock(lockName, timeout, func(db *DB) error { | ||
|
@@ -327,3 +344,8 @@ func (s *DataStore) InsertOrUpdateMap(dataMap map[string]interface{}, updateColu | |
func (s *DataStore) InsertOrUpdateMaps(dataMap []map[string]interface{}, updateColumns []string) error { | ||
return s.DB.insertOrUpdateMaps(s.tableName, dataMap, updateColumns) | ||
} | ||
|
||
// MustNotBeInTransaction panics if the store is in a transaction. | ||
func (s *DataStore) MustNotBeInTransaction() { | ||
s.DB.mustNotBeInTransaction() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
If the order of types doesn't matter, it would be much cleaner to store map[string]struct{} in triggersToRun.SchedulePropagationTypes instead of creating utils.UniqueStrings() and tests for it. Also, the map works faster. But a struct containing all the possible values as boolean fields (like 'awaitingTriggers') would be even better than the map: it would store only several booleans while the map stores strings. Also, the struct provides immediate access to its fields, while the map uses hashing. Also, with the struct, it is not possible to mistype a value which is an often issue with maps/slices.
If the order of types matters, UniqueString() breaks it anyway since maps don't preserve the order of keys.