Add semaphore example to PerformanceBenchmarks. (#242)
This commit is contained in:
Родитель
985cf72e2b
Коммит
0d504ab2fc
|
@ -0,0 +1,49 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
namespace PerformanceTests.HelloCities
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Azure.WebJobs;
|
||||
using Microsoft.Azure.WebJobs.Extensions.Http;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
|
||||
using System.Linq;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
|
||||
/// <summary>
|
||||
/// A simple microbenchmark orchestration that some trivial activities in a sequence.
|
||||
/// </summary>
|
||||
public static class SemaphoreHttpTriggers
|
||||
{
|
||||
[FunctionName(nameof(SemaphoreOrchestration))]
|
||||
public static async Task<IActionResult> SemaphoreOrchestration(
|
||||
[HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req,
|
||||
[DurableClient] IDurableClient client,
|
||||
ILogger log)
|
||||
{
|
||||
// start the orchestration
|
||||
string orchestrationInstanceId = await client.StartNewAsync("OrchestrationWithSemaphore");
|
||||
|
||||
// wait for it to complete and return the result
|
||||
return await client.WaitForCompletionOrCreateCheckStatusResponseAsync(req, orchestrationInstanceId, TimeSpan.FromSeconds(400));
|
||||
}
|
||||
|
||||
[FunctionName(nameof(Semaphore))]
|
||||
public static async Task<IActionResult> Semaphore(
|
||||
[HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req,
|
||||
[DurableClient] IDurableClient client,
|
||||
ILogger log)
|
||||
{
|
||||
var response = await client.ReadEntityStateAsync<SemaphoreTest.SemaphoreEntity>(new EntityId("SemaphoreEntity", "MySemaphoreInstance"));
|
||||
return new OkObjectResult(response);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
namespace PerformanceTests.HelloCities
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using Microsoft.Azure.WebJobs;
|
||||
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// A simple microbenchmark orchestration that executes several simple "hello" activities in a sequence.
|
||||
/// </summary>
|
||||
public static partial class SemaphoreTest
|
||||
{
|
||||
[FunctionName("OrchestrationWithSemaphore")]
|
||||
public static async Task<string> OrchestrationWithSemaphore([OrchestrationTrigger] IDurableOrchestrationContext context)
|
||||
{
|
||||
EntityId semaphore = new EntityId("SemaphoreEntity", "MySemaphoreInstance");
|
||||
Guid requestId = context.NewGuid();
|
||||
DateTime startTime = context.CurrentUtcDateTime;
|
||||
TimeSpan timeOut = TimeSpan.FromMinutes(5);
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (await context.CallEntityAsync<bool>(semaphore, "TryAcquire", requestId))
|
||||
{
|
||||
break; // we have acquired the semaphore
|
||||
}
|
||||
if (context.CurrentUtcDateTime > startTime + timeOut)
|
||||
{
|
||||
throw new Exception("timed out while waiting for semaphore");
|
||||
}
|
||||
else
|
||||
{
|
||||
await context.CreateTimer(context.CurrentUtcDateTime + TimeSpan.FromSeconds(1), CancellationToken.None);
|
||||
}
|
||||
}
|
||||
await context.CallActivityAsync("ActivityThatRequiresSemaphore", null);
|
||||
|
||||
return "Completed successfully.";
|
||||
}
|
||||
finally
|
||||
{
|
||||
context.SignalEntity(semaphore, "Release", requestId);
|
||||
}
|
||||
}
|
||||
|
||||
[FunctionName("SemaphoreEntity")]
|
||||
public static Task Run([EntityTrigger] IDurableEntityContext ctx)
|
||||
=> ctx.DispatchAsync<SemaphoreEntity>();
|
||||
|
||||
public class SemaphoreEntity
|
||||
{
|
||||
public List<Guid> Requests { get; set; } = new List<Guid>();
|
||||
|
||||
public int MaxCount { get; set; } = 50;
|
||||
|
||||
public bool TryAcquire(Guid id)
|
||||
{
|
||||
int position = this.Requests.IndexOf(id);
|
||||
if (position == -1)
|
||||
{
|
||||
this.Requests.Add(id);
|
||||
position = this.Requests.Count - 1;
|
||||
}
|
||||
return (position < this.MaxCount);
|
||||
}
|
||||
|
||||
public void Release(Guid id)
|
||||
{
|
||||
this.Requests.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
[FunctionName("ActivityThatRequiresSemaphore")]
|
||||
public static Task ActivityThatRequiresSemaphore([ActivityTrigger] IDurableActivityContext context, ILogger logger)
|
||||
{
|
||||
logger.LogInformation("Entering");
|
||||
Thread.Sleep(100);
|
||||
logger.LogInformation("Exiting");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче