# Azure Function
有 2 個模式,以未來性來說,Isolated 比較好,因為可以支援後續的 .Net 7, .Net 8,只需要升級 .Net Version 就好了。
* Isolated Process (Out of Process)
* In Process
[In-Process vs. Isolated Process](https://docs.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide#differences-with-net-class-library-functions)

Ref: https://markheath.net/post/azure-functions-isolated
**本機開發前須要先安裝以下工具:**
1. [Azure Functions Core Tools](https://docs.microsoft.com/zh-tw/azure/azure-functions/functions-run-local?tabs=v4%2Cwindows%2Ccsharp%2Cportal%2Cbash)
2. [.Net Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/6.0), version up than 6.0.6
**Command Line:**
``` cmd
func init {project_name} #建立一個可以用 Visual Studio Code 開啟的 Azure Function專案
func new #建立一個Function Class
```
**Duration Function:**
Ref: https://docs.microsoft.com/zh-tw/azure/azure-functions/durable/durable-functions-overview?tabs=csharp
**Trigger Type:**
Ref: https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings?tabs=csharp#supported-bindings
**Request Body Example:**
Ref: https://stackoverflow.com/questions/66911660/httprequestdata-wraps-body-in-json
**HttpTrigger Authorization Level:**
Ref: https://vincentlauzon.com/2017/12/04/azure-functions-http-authorization-levels/
**Cold Start**
Ref. https://azure.microsoft.com/zh-tw/blog/understanding-serverless-cold-start/
**Azure Function Timeout:**
**functionTimeout:** 整個 Function Timeout 的時間
**maxAutoLockRenewalDuration:** Function 過多久之內沒有結束的話,ServiceBus 會重打一次 Azure Function 的時間
Ref: https://build5nines.com/azure-functions-extend-execution-timeout-past-5-minutes/
Ref. https://docs.microsoft.com/en-us/azure/azure-functions/functions-host-json#functiontimeout
Ref. https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus?tabs=in-process%2Cextensionv5%2Cextensionv3&pivots=programming-language-csharp#hostjson-settings
**HealthCheck Monitor**
Ref: https://github.com/Azure/azure-functions-host/wiki/Host-Health-Monitor
**Output Binding:**
Function Return 時在 Response Model 的 Property 加上對應的 Output Attribute,就會自動轉發到對應的 ServiceBus 上了
```csharp
[Function("ServiceBusProducerBindOutput")]
public async Task<Output> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
FunctionContext executionContext)
{
var queueBody = new QueueBody
{
ProcessId = Guid.NewGuid(),
Content = "ConsumerWithBind"
};
await _stepRepository.AddStep(queueBody.ProcessId, 0, queueBody.Content, "Queue");
var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteAsJsonAsync<object>(new {result = true});
return new Output
{
Body = queueBody,
result = response
};
}
public class Output
{
[ServiceBusOutput(queueOrTopicName: "mainqueue", Connection = "ServiceBus")]
public QueueBody Body { get; set; }
public HttpResponseData result { get; set; }
}
```
ServiceBusTrigger 可以只接用 Class 來接收 Input,不需特別用 String 接下來再轉成 Json
```csharp
[Function("ServiceBusConsumer")]
public async Task Run([ServiceBusTrigger("mainqueue", Connection = "ServiceBus")] QueueBody body, FunctionContext context)
{
await _stepRepository.AddStep(body.ProcessId, 1, body.Content, "Queue");
}
```
### ServiceBusTrigger
ServiceBus 有 2 種類型,Queue 跟 Topic:
**Queue:**
* Queue 是一對一的,不會同時發送給多個 Consumer

:::info
Queue 只能有一個 Consumer,如果刻意綁定多個的話,只會有一個 Consumer 收到 Message

:::
**Topic:**
* 一個 Topic 裡面可以設定好幾個 Subscriptions,每個 Subscription 都會有一個 Consumer,只要發送一個 Message 到這個 Topic,Topic 中的所有 Subscriptions 都會收到同樣的訊息。
* Topic 可以透過在 Subscription 設定 EnabledSession 來保證 Message 是以 FIFO 的方式消耗的,但需要在程式中指定一個 SessionId 來讓 Subscription 辨認他們是同一批的,如果沒有設定 SessionId 的話,設定為 EnabledSession 的 Subsciption 不會將訊息轉發給 Consumer

:::info
2 個 Subscription 同時都收到 Message

:::
###### tags: `Azure`