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 }