github.com/matrixorigin/matrixone@v1.2.0/pkg/frontend/migrate.go (about)

     1  // Copyright 2021 - 2024 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  // http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package frontend
    16  
    17  import "sync"
    18  
    19  // migrateController is created in Routine and used to:
    20  //  1. wait migration finished before close the routine.
    21  //  2. check routine if closed before do the migration.
    22  type migrateController struct {
    23  	sync.Mutex
    24  	migrateOnce sync.Once
    25  	// closed indicates if the session has been closed.
    26  	closed bool
    27  	// inProgress indicates if the migration is in progress.
    28  	inProgress bool
    29  	// c is the channel which is used to wait for the migration
    30  	// finished when close the routine.
    31  	c chan struct{}
    32  }
    33  
    34  func newMigrateController() *migrateController {
    35  	return &migrateController{
    36  		closed:     false,
    37  		inProgress: false,
    38  		c:          make(chan struct{}, 1),
    39  	}
    40  }
    41  
    42  // waitAndClose is called in the routine before the routine is cleaned up.
    43  // if the migration is in progress, wait for it finished and set the closed to true.
    44  func (mc *migrateController) waitAndClose() {
    45  	mc.Lock()
    46  	defer mc.Unlock()
    47  	if mc.inProgress {
    48  		<-mc.c
    49  	}
    50  	mc.closed = true
    51  }
    52  
    53  // beginMigrate is called before the migration started. It check if the routine
    54  // has been closed.
    55  func (mc *migrateController) beginMigrate() bool {
    56  	mc.Lock()
    57  	defer mc.Unlock()
    58  	if mc.closed {
    59  		return false
    60  	}
    61  	mc.inProgress = true
    62  	return true
    63  }
    64  
    65  // endMigrate is called after the migration finished. It notifies the routine that
    66  // it could clean up and set in progress to false.
    67  func (mc *migrateController) endMigrate() {
    68  	select {
    69  	case mc.c <- struct{}{}:
    70  	default:
    71  	}
    72  	mc.Lock()
    73  	defer mc.Unlock()
    74  	mc.inProgress = false
    75  }