/// <summary> /// Scan the database for changes to tenants (their servers and / or databases). /// </summary> /// <returns> /// A <see cref="Task"/> representing the operation. /// </returns> async Task ScanTenants() { Log.Debug("Scanning tenants..."); using (IAsyncDocumentSession session = DocumentStore.OpenAsyncSession()) { List <DatabaseServer> servers = await session.Query <DatabaseServer>().ToListAsync(); foreach (DatabaseServer server in servers) { Log.Debug("Discovered database server {ServerId} (Name:{ServerName}) owned by tenant {TenantId}.", server.Id, server.Name, server.TenantId ); IActorRef serverManager; if (!_serverManagers.TryGetValue(server.Id, out serverManager)) { serverManager = Context.ActorOf( Context.DI().Props <TenantServerManager>() .WithSupervisorStrategy(StandardSupervision.Default), name: TenantServerManager.ActorName(server.Id) ); Context.Watch(serverManager); _serverManagers.Add(server.Id, serverManager); serverManager.Tell(new TenantServerManager.Initialize( initialState: server, dataAccess: Self )); Log.Info("Created TenantServerManager {ActorName} for server {ServerId} (Tenant:{TenantId}).", serverManager.Path.Name, server.Id, server.TenantId ); } else { Log.Debug("Notifying TenantServerManager {ActorName} of current configuration for server {ServerId}.", serverManager.Path.Name, server.Id); serverManager.Tell( server.Clone() ); } Dictionary <string, DatabaseInstance> databases = await session.LoadAsync <DatabaseInstance>(server.DatabaseIds); foreach (string databaseId in databases.Keys) { DatabaseInstance database = databases[databaseId]; if (database == null) { Log.Warning("Server {ServerId} in management database refers to non-existent database {DatabaseId}.", server.Id, databaseId ); continue; } Log.Debug("Notifying TenantServerManager {ActorName} of current configuration for database {DatabaseId} in server {ServerId}.", serverManager.Path.Name, database.Id, server.Id ); serverManager.Tell( database.Clone() ); } } } Log.Debug("Tenant scan complete."); }