| 267 | const serverContextStopMaxWait = 30 * time.Second |
| 268 | |
| 269 | func (sc *ServerContext) Close(ctx context.Context) { |
| 270 | // stop HTTP servers - prevents any further requests from coming in before we continue with tearing down everything else |
| 271 | sc.stopHTTPServers(ctx) |
| 272 | |
| 273 | // stop the config polling |
| 274 | if err := base.TerminateAndWaitForClose(sc.BootstrapContext.terminator, sc.BootstrapContext.doneChan, serverContextStopMaxWait); err != nil { |
| 275 | base.InfofCtx(ctx, base.KeyAll, "Couldn't stop background config update worker: %v", err) |
| 276 | } |
| 277 | |
| 278 | // close cached bootstrap bucket connections for config polling |
| 279 | if sc.BootstrapContext != nil && sc.BootstrapContext.Connection != nil { |
| 280 | sc.BootstrapContext.Connection.Close() |
| 281 | } |
| 282 | |
| 283 | if agent := sc.GoCBAgent; agent != nil { |
| 284 | if err := agent.Close(); err != nil { |
| 285 | base.WarnfCtx(ctx, "Error closing agent connection: %v", err) |
| 286 | } |
| 287 | } |
| 288 | |
| 289 | if err := base.TerminateAndWaitForClose(sc.statsContext.terminator, sc.statsContext.doneChan, serverContextStopMaxWait); err != nil { |
| 290 | base.InfofCtx(ctx, base.KeyAll, "Couldn't stop stats logger: %v", err) |
| 291 | } |
| 292 | |
| 293 | // close all databases |
| 294 | sc._databasesLock.Lock() |
| 295 | defer sc._databasesLock.Unlock() |
| 296 | for _, db := range sc._databases { |
| 297 | db.Close(ctx) |
| 298 | _ = db.EventMgr.RaiseDBStateChangeEvent(ctx, db.Name, "offline", "Database context closed", &sc.Config.API.AdminInterface) |
| 299 | } |
| 300 | sc._databases = nil |
| 301 | sc.invalidDatabaseConfigTracking.dbNames = nil |
| 302 | } |
| 303 | |
| 304 | func (sc *ServerContext) stopHTTPServers(ctx context.Context) { |
| 305 | sc._httpServersLock.Lock() |