()
| 246 | } |
| 247 | |
| 248 | func (w *DatabaseInitWorker) Run() { |
| 249 | // Ensure cancelFunc resources are released on normal completion |
| 250 | defer func() { |
| 251 | if w.cancelFunc != nil { |
| 252 | w.cancelFunc(errors.New("database initialization finished normally")) |
| 253 | } |
| 254 | }() |
| 255 | |
| 256 | if w.collectionStatusCallback != nil { |
| 257 | for scName := range w.collections { |
| 258 | w.collectionStatusCallback(w.dbName, scName, db.CollectionIndexStatusQueued) |
| 259 | } |
| 260 | } |
| 261 | |
| 262 | var indexErr error |
| 263 | for scName, indexSet := range w.collections { |
| 264 | if w.collectionStatusCallback != nil { |
| 265 | w.collectionStatusCallback(w.dbName, scName, db.CollectionIndexStatusInProgress) |
| 266 | } |
| 267 | |
| 268 | // Add the index set to the common indexOptions |
| 269 | collectionIndexOptions := w.options.indexOptions |
| 270 | collectionIndexOptions.MetadataIndexes = indexSet |
| 271 | |
| 272 | // Set the scope and collection name on the cluster n1ql store for use by initializeIndexes |
| 273 | w.n1qlStore.SetScopeAndCollection(scName) |
| 274 | keyspaceCtx := base.KeyspaceLogCtx(w.ctx, w.n1qlStore.BucketName(), scName.ScopeName(), scName.CollectionName()) |
| 275 | indexErr = db.InitializeIndexes(keyspaceCtx, w.n1qlStore, collectionIndexOptions) |
| 276 | if w.collectionStatusCallback != nil { |
| 277 | if indexErr != nil { |
| 278 | w.collectionStatusCallback(w.dbName, scName, db.CollectionIndexStatusError) |
| 279 | break |
| 280 | } |
| 281 | w.collectionStatusCallback(w.dbName, scName, db.CollectionIndexStatusReady) |
| 282 | } |
| 283 | |
| 284 | // Check for context cancellation after each collection is processed - if cancelled, return cancellation error |
| 285 | // to all watchers end exit |
| 286 | if err := w.ctx.Err(); err != nil { |
| 287 | indexErr = fmt.Errorf("Database initialization cancelled: %w", err) |
| 288 | break |
| 289 | } |
| 290 | } |
| 291 | |
| 292 | // On completion (success or error), notify watchers |
| 293 | w.watcherLock.Lock() |
| 294 | defer w.watcherLock.Unlock() |
| 295 | w.lastError = indexErr |
| 296 | for _, doneChan := range w.watchers { |
| 297 | if indexErr != nil { |
| 298 | doneChan <- indexErr |
| 299 | } |
| 300 | close(doneChan) |
| 301 | } |
| 302 | w.completed = true |
| 303 | } |
| 304 | |
| 305 | // Adds a watcher for the current worker. Creates a new notification channel for completion and adds |
no test coverage detected