Már*_*les 5 f# azure-functions
我正在尝试创建一个可以在Azure Functions中的请求中重用的已配置对象.以下示例位于C#中.我们的想法是避免DocumentClient为每个请求昂贵地创建自定义实例.该client字段是静态的,在本示例中可以从文档中重用:
using System;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
private static DocumentClient client = GetCustomClient();
private static DocumentClient GetCustomClient()
{
    DocumentClient customClient = new DocumentClient(
        new Uri(ConfigurationManager.AppSettings["CosmosDBAccountEndpoint"]), 
        ConfigurationManager.AppSettings["CosmosDBAccountKey"],
        new ConnectionPolicy
        {
            ConnectionMode = ConnectionMode.Direct,
            ConnectionProtocol = Protocol.Tcp,
            // Customize retry options for Throttled requests
            RetryOptions = new RetryOptions()
            {
                MaxRetryAttemptsOnThrottledRequests = 10,
                MaxRetryWaitTimeInSeconds = 30
            }
        });
    // Customize PreferredLocations
    customClient.ConnectionPolicy.PreferredLocations.Add(LocationNames.CentralUS);
    customClient.ConnectionPolicy.PreferredLocations.Add(LocationNames.NorthEurope);
    return customClient;
}
[FunctionName("CosmosDbSample")]
public static async Task<HttpResponseMessage> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "foo/{id}")] HttpRequestMessage req,
    string id,
    TraceWriter log)
{
    Uri documentUri = UriFactory.CreateDocumentUri("ToDoList", "Items", id);
    Document doc = await client.ReadDocumentAsync(documentUri);
    if (doc == null)
    {
        return req.CreateResponse(HttpStatusCode.NotFound);
    }
    return req.CreateResponse(HttpStatusCode.OK, doc);
}
Run Code Online (Sandbox Code Playgroud)
为了尝试使用更简单的示例进行模拟,我尝试了下面的代码.它正常工作:
namespace TransactionsAggregate
open Microsoft.AspNetCore.Http
open Microsoft.Azure.WebJobs
open Microsoft.Azure.WebJobs.Host
open Microsoft.Azure.WebJobs.Extensions.Http
open System.Net
open System.Net.Http
open System.Web.Http
open Newtonsoft.Json
open System.Text
module Ping =    
    type Name = {
        First: string
        Last: string
    }
    type Greeting = {
        Greeting: string
    }
    let jsonFormatter = System.Net.Http.Formatting.JsonMediaTypeFormatter()
    jsonFormatter.SerializerSettings.ContractResolver <- new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
    [<FunctionName("Ping1")>]
    let run([<HttpTrigger>] req: HttpRequest, log: TraceWriter) =
        async {
        log.Info("Chamando Ping 1")
        let! jsonContent = req.ReadAsStringAsync() |> Async.AwaitTask
        try
            let name = JsonConvert.DeserializeObject<Name>(jsonContent, jsonFormatter.SerializerSettings)
            let response = new HttpResponseMessage(HttpStatusCode.OK)
            let body = JsonConvert.SerializeObject( { Greeting = sprintf "Hello %s %s!" name.First name.Last })
            let content = new StringContent(body, Encoding.UTF8, "application/json")
            response.Content <- content
            return response
        with _ ->
            return new HttpResponseMessage(HttpStatusCode.BadRequest)
        } |> Async.StartAsTask
Run Code Online (Sandbox Code Playgroud)
在这个F#示例中,我们有一个Azure函数,它运行在V2版本上,并在.NET Core上编写.这是一个预编译函数(不是脚本).这是一个类库项目.这个例子只是回应了传递的参数.它jsonFormatter是在模块级别定义和配置的,并未标记为静态.有没有办法创建一个类似的静态字段,所以我可以缓存这个jsonFormatter或将来,一个更昂贵的对象?此外,是否可以保证应用程序中只有一个此值的实例?
文档:https://docs.microsoft.com/en-us/sandbox/functions-recipes/cosmos-db
提前致谢
你已经实现了目标.letF#模块中的绑定每个Azure Functions实例只执行一次,它类似于C#中的静态只读字段.
Azure Functions可以同时运行多个实例(服务器).每次配置新实例时,第一次执行都会很慢,并且会包含昂贵表达式的初始化.在同一个实例上的下一次执行将重用它们,因此它会更快.