在 Azure 函数中使用 CosmosClient 的 `CreateAndInitializeAsync` 应该放在哪里?

问题描述 投票:0回答:1

我有连接到 Cosmos Db 来执行一些工作的 Azure 函数(触发函数)。

我想通过在 ComsosClient 上调用

CreateAndInitializeAsync
来预热这些操作,这样第一个请求就不会很慢。

但是我正在努力思考该放哪里

CreateAndInitializeAsync
。 一方面,它不能放入 DI 初始化中,因为它是一个长时间运行的任务。

另一方面,没有通用的 StartUp 或 Initialize 方法可以作为放置此类初始化代码的好地方。

我应该如何以及在哪里放置它?

.net azure-functions azure-cosmosdb
1个回答
0
投票
当您想要在 Azure Functions 中执行操作之前设置 Cosmos DB 环境时,请使用

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"
}
© www.soinside.com 2019 - 2024. All rights reserved.