当前位置: 首页 > 知识库问答 >
问题:

模式匹配blob名称到具有输入绑定的函数变量

邢英奕
2023-03-14

根据Azure Functions留档的Azure Blob存储绑定,在配置Blob触发器时,可以利用Blob名称上的模式匹配将部分路径映射到函数中的变量,例如。

[FunctionName("BlobTriggered")]        
public static void BlobTriggered(
    [BlobTrigger("myContainer/{name}.{extension}")] Stream myBlob,
    string name,
    string extension,
    TraceWriter log)
{
    // Given the blob path "myContainer/myBlob.png":
    // name == "myBlob"
    // extension == "png"
}

我已经测试过了,它在我的用例中运行得很好,但是由于< code>BlobTrigger触发的大延迟(通常超过5分钟),它不是一个可行的选项。因此,根据Azure Functions scale和托管文档的建议,我希望将它变成一个事件网格触发器:

当您在消费计划中使用blob触发器时,处理新的blob可能会延迟10分钟。此延迟发生在功能应用程序空闲时。函数应用程序运行后,将立即处理blob。要避免这种冷启动延迟,请使用始终启用的应用程序服务计划,或使用事件网格触发器。

是否有任何方法可以从输入绑定而不是触发器获得相同的模式匹配行为?

在我的具体情况下,我已经为blob创建设置了一个< code>EventGrid订阅,它运行一个orchestrator函数,调用一个activity函数来读取和解析blob:

[FunctionName("NewBlobCreated")]
public static async Task NewBlobCreated(
    [EventGridTrigger]EventGridEvent eventGridEvent,
    [OrchestrationClient]DurableOrchestrationClient starter,
    ILogger log)
{
    // Start our orchestrator function to read the file
    string instanceId = await starter.StartNewAsync(
        "OrchestrateBlobReader",
        eventGridEvent);
}

// Orchestrator function
[FunctionName("OrchestrateBlobReader")]
public static async Task OrchestrateBlobReader(
    [OrchestrationTrigger] DurableOrchestrationContext context,
    ILogger log)
{
    var eventGridEvent = context.GetInput<EventGridEvent>();
    var parsedBlob = await context.CallActivityAsync<string>("ReadBlob", eventGridEvent.Data);        
    ...
}

[FunctionName("ReadBlob")]
public static async Task<string> ReadBlob(
    [ActivityTrigger] JObject eventData,
    [Blob("{data.url}", FileAccess.Read)]CloudBlockBlob blob,
    ILogger log)
{
    using (var blobStream = await blob.OpenReadAsync())
    {
        // Blob is able to be read from blobStream here
        ...
    }
}

理想情况下,我希望我的 ReadBlob 函数的行为类似于上面第一个示例中的 BlobTriggered 函数,以便执行如下操作:

[FunctionName("ReadBlob")]
public static async Task<string> ReadBlob(
    [ActivityTrigger] JObject eventData,
    [Blob("{data.url}", FileAccess.Read)]CloudBlockBlob blob,
    string extension,
    ILogger log)
{
    if (extension.Equals("txt", StringComparison.OrdinalIgnoreCase))
    { ... }
    else if (extension.Equals("png", StringComparison.OrdinalIgnoreCase)
    { ... }
    else
    { ... }
}

问题是我看不到任何方法可以将扩展参数绑定到Blob输入绑定,就像我为BlobTrigger所做的那样 - 特别是将路径绑定到EventGridEventeventData JObject形式提供的URL。

在这种情况下,是否有可能实现相同的模式匹配功能?还是我必须自己解析路径字符串以提取相关信息?

共有1个答案

暨正真
2023-03-14

在查看了 blob 触发器绑定的源代码之后 - 我的“快速和肮脏”解决方案是利用触发器用于映射路径的基础 BindingTemplateSource

更新后的< code>ReadBlob函数如下:

// So we can access the BindingTemplateSource class
using Microsoft.Azure.WebJobs.Host.Bindings.Path;

[FunctionName("ReadBlob")]
public static async Task<string> ReadBlob(
    [ActivityTrigger] JObject eventData,
    [Blob("{data.url}", FileAccess.Read)]CloudBlockBlob blob,
    ILogger log)
{
    // Define the pattern to match
    var blobPattern = "myContainer/{name}.{extension}";
    // Create a BindingTemplateSource from the pattern string
    var patternTemplate = BindingTemplateSource.FromString(blobPattern);
    // Use this BindingTemplateSource to create the binding data
    // This returns a IReadOnlyDictionary<string, object> with the parameters mapped
    var parameters = patternTemplate.CreateBindingData($"{blob.Container.Name}/{blob.Name}");
    // Assuming blob path was "myContainer/myBlob.png":
    // Parameters are objects so we need to ToString() them
    var name = parameters["name"].ToString(); // name == "myBlob"
    var extension = parameters["extension"].ToString(); // extension == "png"

    if (extension.Equals("txt", StringComparison.OrdinalIgnoreCase))
    { ... }
    else if (extension.Equals("png", StringComparison.OrdinalIgnoreCase))
    { 
        // This executes now!
    }
    else
    { ... }
}

然后,该功能可能会包装在自定义绑定中,其中参数映射到函数上的输出绑定,就像<code>BlobTrigger</code>为最优雅的解决方案所做的那样,但像这样将其破解到函数中可以实现我短期所需的功能

 类似资料:
  • 本文向大家介绍Rust 绑定模式匹配,包括了Rust 绑定模式匹配的使用技巧和注意事项,需要的朋友参考一下 示例 可以使用@以下方式将值绑定到名称: 这将打印:            

  • 模式匹配与匿名函数 上一章总结了模式在 Scala 中的几种用法,最后提到了匿名函数。 这一章,我们具体的去学习如何在匿名函数中使用模式。 如果你参与过 Coursera 上的 那门 Scala 课程 , 或者写过 Scala 代码,那很可能你已经熟悉匿名函数。 比如说,将一组歌名转换成小写格式,你可能会定义一个匿名函数传递给 map 方法: val songTitles = List("The

  • 问题内容: 我的问题是为什么我不能再次调用该函数?或者,如何做到这一点? 假设我有这个功能: 我称之为: 我得到4。 但是,假设我声明了一个与该函数同名的变量(错误): 现在,如果我尝试这样做: 要么: 我将收到此错误:“ TypeError:’int’对象不可调用” 无法将变量“ a”分配给函数? 问题答案: 完成此操作后: 不再是一个 函数 ,而只是一个 整数 (您已将其重新分配!)。因此,很

  • 问题内容: 我使用Java中的正则表达式来捕获组,即使我知道表达式匹配,它也会不断抛出一个。 这是我的代码: 我期待是因为在正则表达式的捕获组拍摄的,而是我得到: IllegalStateException:找不到匹配项 我也尝试过,但发生相同的错误。 根据该文件,并: 捕获组从左到右从一个索引开始。零组表示整个模式,因此表达式等于。 我究竟做错了什么? 问题答案: 是帮助程序类,它处理数据迭代以

  • 我有一个带有servicebus触发器和blob输入绑定的python函数。blob的名称与队列消息的内容匹配。我的function.json文件如下所示: 它就像一种魅力。 Id创建一个具有相同绑定的C#函数,但它似乎不起作用。我使用了相同的文件。

  • 我正在尝试将我的消息驱动bean与Weblogic 10.3.5上的Oracle JCA文件适配器(包含在SOA套件中)绑定。这样我的MDB可以在有任何问题时得到通知。txt文件被移动到特定目录。 启动支持SOA功能的Weblogic域后,将自动部署文件适配器。在Weblogic控制台上,我可以看到文件适配器部署为“资源适配器”,运行状况为“OK”,状态为“Active”,如下所示: 我还运行了文