Skip to content

Commit 9032c5b

Browse files
committed
create changestream with timeout
1 parent 7750d86 commit 9032c5b

1 file changed

Lines changed: 15 additions & 4 deletions

File tree

flow/connectors/mongo/cdc.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ func (c *MongoConnector) SetupReplication(ctx context.Context, input *protos.Set
8787
if err != nil {
8888
return model.SetupReplicationResult{}, fmt.Errorf("failed to create changestream pipeline: %w", err)
8989
}
90-
changeStream, err := c.client.Watch(ctx, pipeline, changeStreamOpts)
90+
91+
changeStream, err := createChangeStream(c.client, ctx, pipeline, changeStreamOpts)
9192
if err != nil {
9293
return model.SetupReplicationResult{}, fmt.Errorf("failed to start change stream for storing initial resume token: %w", err)
9394
}
@@ -156,7 +157,7 @@ func (c *MongoConnector) PullRecords(
156157
return err
157158
}
158159

159-
changeStream, err := c.client.Watch(ctx, pipeline, changeStreamOpts)
160+
changeStream, err := createChangeStream(c.client, ctx, pipeline, changeStreamOpts)
160161
if err != nil {
161162
if isResumeTokenNotFoundError(err) && resumeToken != nil {
162163
timestamp, err := decodeTimestampFromResumeToken(resumeToken)
@@ -165,7 +166,7 @@ func (c *MongoConnector) PullRecords(
165166
}
166167
changeStreamOpts.SetStartAtOperationTime(&timestamp)
167168
changeStreamOpts.SetResumeAfter(nil)
168-
changeStream, err = c.client.Watch(ctx, pipeline, changeStreamOpts)
169+
changeStream, err = createChangeStream(c.client, ctx, pipeline, changeStreamOpts)
169170
if err != nil {
170171
return fmt.Errorf("failed to recreate change stream: %w", err)
171172
}
@@ -299,7 +300,7 @@ func (c *MongoConnector) PullRecords(
299300
changeStreamOpts.SetStartAtOperationTime(nil)
300301
}
301302

302-
changeStream, err = c.client.Watch(ctx, pipeline, changeStreamOpts)
303+
changeStream, err = createChangeStream(c.client, ctx, pipeline, changeStreamOpts)
303304
if err != nil {
304305
return err
305306
}
@@ -461,6 +462,16 @@ func createPipeline(tableNameMapping map[string]model.NameAndExclude) (mongo.Pip
461462
return pipeline, nil
462463
}
463464

465+
// createChangeStream calls client.Watch with a 5 minute context deadline
466+
// so the driver sends it as maxTimeMS over the wire. Otherwise server-
467+
// side default maxTimeMS is used which can sometimes be too short.
468+
func createChangeStream(client *mongo.Client, parent context.Context, pipeline mongo.Pipeline, opts *options.ChangeStreamOptionsBuilder,
469+
) (*mongo.ChangeStream, error) {
470+
watchCtx, cancel := context.WithTimeout(parent, 5*time.Minute)
471+
defer cancel()
472+
return client.Watch(watchCtx, pipeline, opts)
473+
}
474+
464475
// This can happen if the resumeToken we are attempting to `ResumeAfter` refers to a table that has been
465476
// filtered out of the change stream pipeline (for example, if a user pauses and edits a mirror). If
466477
// this happens, we decode the resumeToken and extract its operation time, and start a new changeStream

0 commit comments

Comments
 (0)