Skip to content
18 changes: 10 additions & 8 deletions go/logic/migrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,16 @@ type Migrator struct {

func NewMigrator(context *base.MigrationContext, appVersion string) *Migrator {
migrator := &Migrator{
appVersion: appVersion,
hooksExecutor: NewHooksExecutor(context),
migrationContext: context,
parser: sql.NewAlterTableParser(),
ghostTableMigrated: make(chan bool),
firstThrottlingCollected: make(chan bool, 3),
rowCopyComplete: make(chan error),
allEventsUpToLockProcessed: make(chan *lockProcessedStruct),
appVersion: appVersion,
hooksExecutor: NewHooksExecutor(context),
migrationContext: context,
parser: sql.NewAlterTableParser(),
ghostTableMigrated: make(chan bool),
firstThrottlingCollected: make(chan bool, 3),
rowCopyComplete: make(chan error),
// Buffered to MaxRetries() to prevent a deadlock when waitForEventsUpToLock times out.
// (see https://github.com/github/gh-ost/pull/1637)
allEventsUpToLockProcessed: make(chan *lockProcessedStruct, context.MaxRetries()),
Comment on lines +114 to +116
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

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

make(chan *lockProcessedStruct, context.MaxRetries()) won’t compile because the channel buffer size parameter must be of type int, but MigrationContext.MaxRetries() returns int64 (go/base/context.go:495). Convert to int (and consider guarding against overflow if you want to be extra defensive).

Copilot uses AI. Check for mistakes.
Comment on lines +114 to +116
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

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

This change is meant to prevent a specific deadlock scenario, but there’s no regression test exercising the “timeout then applier executes stale sentinel” behavior. Consider adding a unit test that constructs a Migrator, performs a non-blocking send on allEventsUpToLockProcessed without any receiver, and/or asserts the channel has the expected buffering based on MaxRetries() so future refactors don’t reintroduce the unbuffered-channel deadlock.

Copilot uses AI. Check for mistakes.

copyRowsQueue: make(chan tableWriteFunc),
applyEventsQueue: make(chan *applyEventStruct, base.MaxEventsBatchSize),
Expand Down
Loading