我有连接到 Cosmos Db 来执行一些工作的 Azure 函数(触发函数)。
我想通过在 ComsosClient 上调用
CreateAndInitializeAsync
来预热这些操作,这样第一个请求就不会很慢。
但是我正在努力思考该放哪里
CreateAndInitializeAsync
。
一方面,它不能放入 DI 初始化中,因为它是一个长时间运行的任务。
另一方面,没有通用的 StartUp 或 Initialize 方法可以作为放置此类初始化代码的好地方。
我应该如何以及在哪里放置它?
CreateAndInitializeAsync 方法。它在下面代码的初始化方法中使用。在此,它检查 Cosmos DB 客户端是否已初始化。如果没有,那么它会获取锁以确保线程安全。
在锁内,它会再次检查是否仍需要初始化,以避免冗余初始化。如果需要初始化,它会调用
CreateAndInitializeAsync
方法来初始化 Cosmos DB 客户端。
在下面的代码中创建了一个示例文档,并使用
CreateItemAsync
方法将该文档保存到第二个和第三个容器中。
按照MS DOC
CreateAndInitializeAsync
方法在下面的代码中使用,它由connectionString
和containers
作为参数组成。
public static class HttpFunction
{
private static bool isInitialized = false;
private static readonly object initializationLock = new object();
private static CosmosClient cosmosClient;
[FunctionName("HttpFunction")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
Initialize();
try
{
await PerformCosmosDbOperation(log);
return new OkObjectResult("Cosmos DB operation completed successfully.");
}
catch (Exception ex)
{
log.LogError("Function execution failed: {ex.Message}");
return new ObjectResult("Internal Server Error") { StatusCode = StatusCodes.Status500InternalServerError };
}
}
private static void Initialize()
{
if (!isInitialized)
{
lock (initializationLock)
{
if (!isInitialized)
{
var connectionString = "*****";
var containers = new List<(string databaseId, string containerId)>
{
("newDb", "secondCont"),
("newDb","thirdContainer")
};
CreateAndInitializeAsync(connectionString, containers).GetAwaiter().GetResult();
isInitialized = true;
}
}
}
}
private static async Task CreateAndInitializeAsync(
string connectionString,
IReadOnlyList<(string databaseId, string containerId)> containers)
{
cosmosClient = new CosmosClient(connectionString);
foreach (var (databaseId, containerId) in containers)
{
await cosmosClient.CreateDatabaseIfNotExistsAsync(databaseId);
await cosmosClient.GetDatabase(databaseId).CreateContainerIfNotExistsAsync(containerId, "/id", 400);
}
await Task.Delay(5000);
}
private static async Task PerformCosmosDbOperation(ILogger log)
{
var secondContainerId = "secondCont";
var thirdContainerId = "thirdContainer";
var secondContainer = cosmosClient.GetContainer("newDb", secondContainerId);
var thirdContainer = cosmosClient.GetContainer("newDb", thirdContainerId);
var document = new { id = Guid.NewGuid(), name = "Example Document" };
await secondContainer.CreateItemAsync(document);
await thirdContainer.CreateItemAsync(document);
log.LogInformation("Cosmos DB operation completed.");
}
}
输出: 在浏览器中: Cosmos DB 操作成功完成。
在 Azure Cosmos DB 容器中:
secondCont:
{
"id": "d279d070-8e4d-4b71-8ccb-658024e66c38",
"name": "Example Document"
}
thirdContainer:
{
"id": "d279d070-8e4d-4b71-8ccb-658024e66c38",
"name": "Example Document"
}