Skip to content

Instantly share code, notes, and snippets.

@noriyukitakei
Last active April 19, 2019 12:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noriyukitakei/24317538ffc4d2b76f5276dfcf17ed52 to your computer and use it in GitHub Desktop.
Save noriyukitakei/24317538ffc4d2b76f5276dfcf17ed52 to your computer and use it in GitHub Desktop.
多分わかりやすいDurable Functios【Durable Functionsを使う場合】
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Xml.Linq;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
namespace CalcurateBlogTaggedByAzureByDurableFunctions
{
public static class Function1
{
// クライアント関数
// オーケストレータ関数を起動します。これは単なるHTTPトリガーのAzure Functionsです。
// キュートリガーでもなんでも構いません。大切なのはこのメソッドの中のStartNewAsyncです。
// これでDurable Functionsのキモであるオーケストレーター関数を呼び出します。
// なので、クライアント関数のトリガーは、StartNewAsyncでオーケストレーター関数を起動すれば、
// HTTPでもキューでもBlobでもなんでもOKです。
[FunctionName("OrchestrationClient")]
public static async Task<HttpResponseMessage> HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous, "get")]HttpRequestMessage req,
[OrchestrationClient]DurableOrchestrationClient starter,
ILogger log)
{
// オーケストレーター関数を起動します。第1引数には後に定義するオーケストレーター関数の名前、
// 第2引数には、オーケストレーター関数に渡したい引数を渡します。ここでは何もないのでnullとしています。
// 戻り値のインスタンスIDはオーケストレーター関数が起動する度に一意に発行されるIDです。
// オーケストレーター関数に何か操作したいときに使用します。例えば、オーケストレーター関数内で
// タイマーでwaitをかけておき、外部からのイベントで処理を復帰したい場合、このインスタンスIDを使います。
string instanceId = await starter.StartNewAsync("Orchestrator", null);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
return starter.CreateCheckStatusResponse(req, instanceId);
}
// オーケストレータ関数
[FunctionName("Orchestrator")]
public static async Task RunOrchestrator(
[OrchestrationTrigger] DurableOrchestrationContext context, ILogger log)
{
// 対象のWebサイトのRSSのURLを定義する。
string[] urls = new string[] {
"https://tech-lab.sios.jp/feed/",
"https://satonaoki.wordpress.com/feed/"
};
// 上で定義した、集計対象のWebサイトのRSSのURLを読み込み、
// azureというタグが含まれるの記事の数をカウントするアクティビティ関数を呼び出す。
var tasks = new Task<int>[urls.Length];
for (int i = 0; i < urls.Length; i++)
{
tasks[i] = context.CallActivityAsync<int>("CountBlogTaggedByAzure", urls[i]);
}
// この記述をすると、上で定義したタスクがすべて終了するまで待つことができます。
// つまり集計対象のWebサイトにて、Azureというタグが含まれる記事数を算出する
// 全てのアクティビティ関数の終了を待つことができます。
await Task.WhenAll(tasks);
// アクティビティ関数がすべて終了したら、その結果らか記事の数を取得して、合計する。
int totalCount = tasks.Sum(t => t.Result);
log.LogInformation("result:" + totalCount);
}
// アクティビティ関数
// 集計対象のWebサイトのRSSのURLを読み込み、azureというカテゴリの記事の数をカウントする
[FunctionName("CountBlogTaggedByAzure")]
public static int CountBlogTaggedByAzure([ActivityTrigger] string url, ILogger log)
{
// 集計対象のWebサイトのRSSのURLを読み込み、azureというカテゴリの記事の数をカウントする。
XDocument xml = XDocument.Load(url);
XElement rss = xml.Element("rss");
XElement channel = rss.Element("channel");
var items = channel.Elements("item");
int count = 0;
foreach (XElement item in items)
{
var categories = item.Elements("category");
foreach (XElement category in categories)
{
if (category.Value.ToLower().Contains("azure"))
{
count++;
break;
}
}
}
return count;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment