Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSami Hiltunen <shiltunen@gitlab.com>2022-07-26 15:31:07 +0300
committerSami Hiltunen <shiltunen@gitlab.com>2022-07-26 15:38:02 +0300
commit7ba3b6e0f795216ef36b29563d312650bbd81073 (patch)
tree0572ea90e422a420c49819807347903aea899b2e
parent26515cc70a94c2dee3235fd447940a200ce1399d (diff)
Return context error from requestFinalizersmh-fix-wrong-status-code
Praefect runs the request finalizer even if the request deadline was exceeded in order to ensure the required metadata updates are made. If the context deadline is exceeded in the request finalizer, no error is returned as the metadata updates don't see it. This causes Praefect to return, log and observe a status OK for requests that exceeded the deadline or were canceled while running the request finalizer. This commit returns the error from the original context if no other errors are raised from the requestFinalizer to ensure the status gets correctly set. desc field is added to the tests as they currently abuse the change field as the test name. Changelog: fixed
-rw-r--r--internal/praefect/coordinator.go15
-rw-r--r--internal/praefect/coordinator_test.go21
2 files changed, 27 insertions, 9 deletions
diff --git a/internal/praefect/coordinator.go b/internal/praefect/coordinator.go
index 6f6d439b6..db3fef0b5 100644
--- a/internal/praefect/coordinator.go
+++ b/internal/praefect/coordinator.go
@@ -989,7 +989,7 @@ func routerNodesToStorages(nodes []RouterNode) []string {
}
func (c *Coordinator) newRequestFinalizer(
- ctx context.Context,
+ originalCtx context.Context,
repositoryID int64,
virtualStorage string,
targetRepo *gitalypb.Repository,
@@ -1006,7 +1006,7 @@ func (c *Coordinator) newRequestFinalizer(
// canceled. We need to perform the database updates regardless whether the request was canceled or not as
// the primary replica could have been dirtied and secondaries become outdated. Otherwise we'd have no idea of
// the possible changes performed on the disk.
- ctx, cancel := context.WithTimeout(helper.SuppressCancellation(ctx), 30*time.Second)
+ ctx, cancel := context.WithTimeout(helper.SuppressCancellation(originalCtx), 30*time.Second)
defer cancel()
log := ctxlogrus.Extract(ctx).WithFields(logrus.Fields{
@@ -1090,7 +1090,16 @@ func (c *Coordinator) newRequestFinalizer(
return nil
})
}
- return g.Wait()
+
+ if err := g.Wait(); err != nil {
+ return err
+ }
+
+ // The cancellation signal is suppressed in the beginning, so we'd return no error if the
+ // orignal context exceeded its deadline while running the request finalizer. If there were
+ // no other errors, return the possible error from the context so we don't return OK code for
+ // failed requests.
+ return originalCtx.Err()
}
}
diff --git a/internal/praefect/coordinator_test.go b/internal/praefect/coordinator_test.go
index caf2ad28f..19486f40c 100644
--- a/internal/praefect/coordinator_test.go
+++ b/internal/praefect/coordinator_test.go
@@ -2627,29 +2627,38 @@ func TestNewRequestFinalizer_contextIsDisjointedFromTheRPC(t *testing.T) {
err := errors.New("error")
for _, tc := range []struct {
- change datastore.ChangeType
- errMsg string
+ desc string
+ change datastore.ChangeType
+ errMsg string
+ enqueueError error
}{
{
+ desc: "increment generation receives suppressed cancellation",
change: datastore.UpdateRepo,
errMsg: "increment generation: error",
},
{
+ desc: "rename repository receives suppressed cancellation",
change: datastore.RenameRepo,
errMsg: "rename repository: error",
},
{
- change: "replication jobs only",
- errMsg: "enqueue replication event: error",
+ desc: "enqueue receives suppressed cancellation",
+ errMsg: "enqueue replication event: error",
+ enqueueError: err,
+ },
+ {
+ desc: "original context error is returned",
+ errMsg: context.DeadlineExceeded.Error(),
},
} {
- t.Run(string(tc.change), func(t *testing.T) {
+ t.Run(tc.desc, func(t *testing.T) {
require.EqualError(t,
NewCoordinator(
&datastore.MockReplicationEventQueue{
EnqueueFunc: func(ctx context.Context, _ datastore.ReplicationEvent) (datastore.ReplicationEvent, error) {
requireSuppressedCancellation(t, ctx)
- return datastore.ReplicationEvent{}, err
+ return datastore.ReplicationEvent{}, tc.enqueueError
},
},
datastore.MockRepositoryStore{