asyncDatabaseOnline waits for async initialization to complete (based on doneChan). On successful completion, brings the database online. Checks to ensure the database config hasn't been updated while waiting for init to complete - if that happens, doesn't attempt to bring db online (it may have be
(nonCancelCtx base.NonCancellableContext, dbc *db.DatabaseContext, doneChan chan error, version string)
| 1096 | // Checks to ensure the database config hasn't been updated while waiting for init to complete - if that happens, doesn't attempt to bring |
| 1097 | // db online (it may have been set to offline=true) |
| 1098 | func (sc *ServerContext) asyncDatabaseOnline(nonCancelCtx base.NonCancellableContext, dbc *db.DatabaseContext, doneChan chan error, version string) { |
| 1099 | |
| 1100 | ctx := nonCancelCtx.Ctx |
| 1101 | if doneChan != nil { |
| 1102 | initError := <-doneChan |
| 1103 | if initError != nil { |
| 1104 | dbc.DbStats.DatabaseStats.TotalInitFatalErrors.Add(1) |
| 1105 | base.WarnfCtx(ctx, "Async database init returned error: %v", initError) |
| 1106 | dbc.DatabaseStartupError = db.NewDatabaseError(db.DatabaseInitializationIndexError) |
| 1107 | atomic.CompareAndSwapUint32(&dbc.State, db.DBStarting, db.DBOffline) |
| 1108 | return |
| 1109 | } |
| 1110 | } |
| 1111 | |
| 1112 | // Before bringing the database online, ensure that the database hasn't been modified while we waited for initialization to complete |
| 1113 | currentDbVersion := sc.GetDbVersion(dbc.Name) |
| 1114 | if currentDbVersion != version { |
| 1115 | base.InfofCtx(ctx, base.KeyConfig, "Database version changed while waiting for async init - cancelling obsolete online request. Old version: %s New version: %s", version, currentDbVersion) |
| 1116 | atomic.CompareAndSwapUint32(&dbc.State, db.DBStarting, db.DBOffline) |
| 1117 | return |
| 1118 | } |
| 1119 | |
| 1120 | base.InfofCtx(ctx, base.KeyAll, "Async database initialization complete, starting online processes...") |
| 1121 | err := dbc.StartOnlineProcesses(ctx) |
| 1122 | if err != nil { |
| 1123 | dbc.DbStats.DatabaseStats.TotalOnlineFatalErrors.Add(1) |
| 1124 | base.ErrorfCtx(ctx, "Error starting online processes after async initialization: %v", err) |
| 1125 | atomic.CompareAndSwapUint32(&dbc.State, db.DBStarting, db.DBOffline) |
| 1126 | return |
| 1127 | } |
| 1128 | |
| 1129 | if !atomic.CompareAndSwapUint32(&dbc.State, db.DBStarting, db.DBOnline) { |
| 1130 | // 2nd atomic might end up being Starting here if there's a legitimate race, but it's the most we can do for CAS |
| 1131 | base.PanicfCtx(ctx, "database state wasn't Starting during asyncDatabaseOnline Online transition... now %q", db.RunStateString[atomic.LoadUint32(&dbc.State)]) |
| 1132 | } |
| 1133 | |
| 1134 | _ = dbc.EventMgr.RaiseDBStateChangeEvent(ctx, dbc.Name, "online", dbLoadedStateChangeMsg, &sc.Config.API.AdminInterface) |
| 1135 | } |
| 1136 | |
| 1137 | func (sc *ServerContext) GetDbVersion(dbName string) string { |
| 1138 | sc._databasesLock.RLock() |