And*_*ter 3 c# infinite-loop azure azure-functions azure-cosmosdb
当插入/更新 CosmosDB 文档时,我尝试更新 Azure Functions 中的文档。
但是,当我更新函数内的文档时,该函数会再次触发并导致无限循环。
private static DocumentClient _documentClient = new DocumentClient(new Uri(serviceEndpoint), key);
[FunctionName(nameof(MyFunction))]
public static async Task RunAsync([CosmosDBTrigger(
databaseName: "MyDatabase",
collectionName: "MyCollection",
ConnectionStringSetting = "MyDbConnectionString",
LeaseCollectionName = "leases",
CreateLeaseCollectionIfNotExists = true,
LeaseCollectionPrefix = nameof(MyFunction))]IReadOnlyList<Document> input,
ILogger log)
{
var replacementsTasks = new List<Task>();
foreach (var item in input)
{
item.SetPropertyValue("Updated", true);
replacementsTasks.Add(_documentClient.ReplaceDocumentAsync(item));
}
await Task.WhenAll(replacementsTasks);
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能防止这种情况发生?我可以将 CosmosDB 输出结果与触发器中修改后的文档一起使用吗?
我不想使用另一个集合。这将使 CosmosDB 的定价翻倍。我使用 CosmosDB 输入和输出尝试了以下操作。但是我得到了相同的结果。无限循环。
[FunctionName(nameof(DownloadImages))]
public static void Run(
[CosmosDBTrigger(
databaseName: database,
collectionName: collection,
ConnectionStringSetting = connectionStringName,
LeaseCollectionName = "leases",
CreateLeaseCollectionIfNotExists = true,
LeaseCollectionPrefix = nameof(MyFunction))]IReadOnlyList<Document> input,
[CosmosDB(database, collection, Id = "id", ConnectionStringSetting = connectionStringName)] out dynamic document,
ILogger log)
{
if(input.Count != 1) throw new ArgumentException();
document = input.Single();
document.myValue = true;
}
Run Code Online (Sandbox Code Playgroud)
如果您无法使用其他集合,那么确实没有其他选择。当插入或更新新文档时,触发器会有效地触发。如果您的触发器在它正在监视的同一集合中更新/插入文档,它将有效地创建一个循环。
这就像使用 QueueTrigger 并在同一个 Queue 中插入消息一样,无限循环适用于任何 Trigger 机制。
不过,您可以做的一件事是过滤那些已经更新的内容:
private static DocumentClient _documentClient = new DocumentClient(new Uri(serviceEndpoint), key);
[FunctionName(nameof(MyFunction))]
public static async Task RunAsync([CosmosDBTrigger(
databaseName: "MyDatabase",
collectionName: "MyCollection",
ConnectionStringSetting = "MyDbConnectionString",
LeaseCollectionName = "leases",
CreateLeaseCollectionIfNotExists = true,
LeaseCollectionPrefix = nameof(MyFunction))]IReadOnlyList<Document> input,
ILogger log)
{
var replacementsTasks = new List<Task>();
foreach (var item in input)
{
if (!item.GetPropertyValue<bool>("Updated")) {
item.SetPropertyValue("Updated", true);
replacementsTasks.Add(_documentClient.ReplaceDocumentAsync(item));
}
}
await Task.WhenAll(replacementsTasks);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2421 次 |
| 最近记录: |