Skip to content

Commit

Permalink
Update samples with new packages (#211)
Browse files Browse the repository at this point in the history
  • Loading branch information
jviau authored Oct 11, 2023
1 parent c20c600 commit ac5eb32
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 160 deletions.
1 change: 0 additions & 1 deletion nuget.config
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@
<add key="durabletask" value="https://pkgs.dev.azure.com/durabletaskframework/734e7913-2fab-4624-a174-bc57fe96f95d/_packaging/durabletask/nuget/v3/index.json" />
<add key="AzureFunctionsTempStaging" value="https://pkgs.dev.azure.com/azfunc/e6a70c92-4128-439f-8012-382fe78d6396/_packaging/AzureFunctionsTempStaging/nuget/v3/index.json" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="durabletask" value="https://pkgs.dev.azure.com/durabletaskframework/734e7913-2fab-4624-a174-bc57fe96f95d/_packaging/durabletask/nuget/v3/index.json" />
</packageSources>
</configuration>
4 changes: 2 additions & 2 deletions samples/AzureFunctionsApp/AzureFunctionsApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.19.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.1.0-entities-preview.1" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.1.0-entities-preview.3" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.13" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.0-preview1" OutputItemType="Analyzer" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.0-preview2" OutputItemType="Analyzer" />
<PackageReference Include="Microsoft.DurableTask.Generators" Version="1.0.0-preview.1" OutputItemType="Analyzer" />
</ItemGroup>

Expand Down
89 changes: 0 additions & 89 deletions samples/AzureFunctionsApp/Entities/Counter.Entity.cs

This file was deleted.

65 changes: 0 additions & 65 deletions samples/AzureFunctionsApp/Entities/Counter.State.cs

This file was deleted.

157 changes: 157 additions & 0 deletions samples/AzureFunctionsApp/Entities/Counter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.DurableTask;
using Microsoft.DurableTask.Client;
using Microsoft.DurableTask.Entities;
using Microsoft.Extensions.Logging;

namespace AzureFunctionsApp.Entities;

/// <summary>
/// Example on how to dispatch to an entity which directly implements TaskEntity<TState>. Using TaskEntity<TState> gives
/// the added benefit of being able to use DI. When using TaskEntity<TState>, state is deserialized to the "State"
/// property. No other properties on this type will be serialized/deserialized.
/// </summary>
public class Counter : TaskEntity<int>
{
readonly ILogger logger;

public Counter(ILogger<Counter> logger)
{
this.logger = logger;
}

public int Add(int input)
{
this.logger.LogInformation("Adding {Input} to {State}", input, this.State);
return this.State += input;
}

public int OperationWithContext(int input, TaskEntityContext context)
{
// Get access to TaskEntityContext by adding it as a parameter. Can be with or without an input parameter.
// Order does not matter.
context.ScheduleNewOrchestration("SomeOrchestration", "SomeInput");

// When using TaskEntity<TState>, the TaskEntityContext can also be accessed via this.Context.
this.Context.ScheduleNewOrchestration("SomeOrchestration", "SomeInput");
return this.Add(input);
}

public int Get() => this.State;

[Function("Counter")]
public Task RunEntityAsync([EntityTrigger] TaskEntityDispatcher dispatcher)
{
// Can dispatch to a TaskEntity<TState> by passing a instance.
return dispatcher.DispatchAsync(this);
}

[Function("Counter_Alt")]
public static Task RunEntityStaticAsync([EntityTrigger] TaskEntityDispatcher dispatcher)
{
// Can also dispatch to a TaskEntity<TState> by using a static method.
return dispatcher.DispatchAsync<Counter>();
}

protected override int InitializeState(TaskEntityOperation operation)
{
// Optional method to override to customize initialization of state for a new instance.
return base.InitializeState(operation);
}
}

/// <summary>
/// Example on how to dispatch to a POCO as the entity implementation. When using POCO, the entire object is serialized
/// and deserialized.
/// </summary>
/// <remarks>
/// Note there is a structural difference between <see cref="Counter"/> and <see cref="StateCounter"/>. In the former,
/// the state is declared as <see cref="int"/>. In the later, state is the type itself (<see cref="StateCounter"/>).
/// This means they have a different state serialization structure. The former is just "int", while the later is
/// "{ \"Value\": int }".
/// </remarks>
public class StateCounter
{
public int Value { get; set; }

public int Add(int input) => this.Value += input;

public int OperationWithContext(int input, TaskEntityContext context)
{
// Get access to TaskEntityContext by adding it as a parameter. Can be with or without an input parameter.
// Order does not matter.
context.ScheduleNewOrchestration("SomeOrchestration", "SomeInput");
return this.Add(input);
}

public int Get() => this.Value;

[Function("StateCounter")]
public static Task RunEntityAsync([EntityTrigger] TaskEntityDispatcher dispatcher)
{
// Using the dispatch to a state object will deserialize the state directly to that instance and dispatch to an
// appropriate method.
// Can only dispatch to a state object via generic argument.
return dispatcher.DispatchAsync<StateCounter>();
}
}

public static class CounterHelpers
{
/// <summary>
/// Usage:
/// Add to <see cref="Counter"/>:
/// POST /api/counter/{id}?value={value-to-add}
/// POST /api/counter/{id}?value={value-to-add}&mode=0
/// POST /api/counter/{id}?value={value-to-add}&mode=entity
///
/// Add to <see cref="StateCounter"/>
/// POST /api/counter/{id}?value={value-to-add}&mode=1
/// POST /api/counter/{id}?value={value-to-add}&mode=state
/// </summary>
/// <param name="request"></param>
/// <param name="client"></param>
/// <param name="id"></param>
/// <returns></returns>
[Function("StartCounter")]
public static async Task<HttpResponseData> StartAsync(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "counter/{id}")] HttpRequestData request,
[DurableClient] DurableTaskClient client,
string id)
{
_ = int.TryParse(request.Query["value"], out int value);

string name = "counter";

// switch to StateCounter if ?mode=1 or ?mode=state is supplied.
string? mode = request.Query["mode"];
if (int.TryParse(mode, out int m) && m == 1)
{
name = "state";
}
else if (mode == "state")
{
name = "statecounter";
}

string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
"CounterOrchestration", new Payload(new EntityInstanceId(name, id), value));
return client.CreateCheckStatusResponse(request, instanceId);
}

[Function("CounterOrchestration")]
public static async Task<int> RunOrchestrationAsync(
[OrchestrationTrigger] TaskOrchestrationContext context, Payload input)
{
ILogger logger = context.CreateReplaySafeLogger<Counter>();
int result = await context.Entities.CallEntityAsync<int>(input.Id, "add", input.Add);
logger.LogInformation("Counter value: {Value}", result);
return result;
}

public record Payload(EntityInstanceId Id, int Add);
}
2 changes: 1 addition & 1 deletion samples/AzureFunctionsApp/Entities/StateManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public void Delete()
this.State = null!;
}

protected override MyState InitializeState()
protected override MyState InitializeState(TaskEntityOperation operation)
{
// This method allows for customizing the default state value for a new entity.
return new("Default", 10);
Expand Down
4 changes: 2 additions & 2 deletions src/Worker/Core/DurableTaskWorkerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public DataConverter DataConverter
}

/// <summary>
/// Gets or sets a value indicating whether this client should support entities. If true, all instance ids starting with '@' are reserved for entities,
/// and validation checks are performed where appropriate.
/// Gets or sets a value indicating whether this client should support entities. If true, all instance ids starting
/// with '@' are reserved for entities, and validation checks are performed where appropriate.
/// </summary>
public bool EnableEntitySupport { get; set; }

Expand Down

0 comments on commit ac5eb32

Please sign in to comment.