Skip to content

Instantly share code, notes, and snippets.

@johnazariah
Last active July 30, 2018 16:55
Show Gist options
  • Save johnazariah/b976ee1ae69544dfcd18fe56e0d66692 to your computer and use it in GitHub Desktop.
Save johnazariah/b976ee1ae69544dfcd18fe56e0d66692 to your computer and use it in GitHub Desktop.
Getting Started with Orleans 2.0 on .NET Core
using Microsoft.Extensions.Logging;
using Orleans;
using Orleans.Configuration;
using Orleans.Hosting;
using System;
using System.Threading.Tasks;
namespace Orleans2GettingStarted
{
internal static class ClientDevelopmentHelpers
{
public static Task RunInNewClient(Func<IClusterClient, Task> doSomething) => new ClientBuilder()
.UseLocalhostClustering()
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "Orleans2GettingStarted";
})
.ConfigureLogging(logging => logging.AddConsole())
.Build()
.Run(doSomething);
private static async Task Run(this IClusterClient client, Func<IClusterClient, Task> doSomething)
{
try
{
await client.Connect();
await doSomething(client);
}
finally
{
await client.Close();
}
}
}
}
using Microsoft.Extensions.Logging;
using Orleans;
using Orleans.Configuration;
using Orleans.Hosting;
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace Orleans2GettingStarted
{
internal static class SiloDevelopmentHelpers
{
public static (ISiloHost, ManualResetEvent) BuildNewSilo() => new SiloHostBuilder()
.UseDevelopmentClustering(options => options.PrimarySiloEndpoint = new IPEndPoint(IPAddress.Loopback, 11111))
.UseDashboard(options => { })
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "Orleans2GettingStarted";
})
/// Prevent the silo from automatically stopping itself when the cancel key is pressed.
.Configure<ProcessExitHandlingOptions>(options => options.FastKillOnProcessExit = false)
.ConfigureLogging(b => b.SetMinimumLevel(LogLevel.Debug).AddConsole())
.Configure<EndpointOptions>(options => options.AdvertisedIPAddress = IPAddress.Loopback)
.ConfigureLogging(logging => logging.AddConsole())
.Build()
.RegisterForSafeShutdown();
private static (ISiloHost, ManualResetEvent) RegisterForSafeShutdown(this ISiloHost silo)
{
var siloIsStopping = false;
var syncLock = new object();
var resetEvent = new ManualResetEvent(false);
void CancelKeyPressHandler(object _, ConsoleCancelEventArgs e)
{
/// Prevent the application from crashing ungracefully.
e.Cancel = true;
/// Don't allow the following code to repeat if the user presses Ctrl+C repeatedly.
lock (syncLock)
{
if (!siloIsStopping)
{
siloIsStopping = true;
Task.Run(async () => { await silo.StopAsync(); resetEvent.Set(); }).Ignore();
}
}
/// Event handler execution exits immediately, leaving the silo shutdown running on a background thread,
/// but the app doesn't crash because e.Cancel has been set = true
}
/// Capture the user pressing Ctrl+C
Console.CancelKeyPress += CancelKeyPressHandler;
return (silo, resetEvent);
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.1" />
<PackageReference Include="Microsoft.Orleans.Client" Version="2.0.3" />
<PackageReference Include="Microsoft.Orleans.OrleansCodeGenerator.Build" Version="2.0.3" />
<PackageReference Include="Microsoft.Orleans.OrleansTelemetryConsumers.Counters" Version="2.0.0" />
<PackageReference Include="Microsoft.Orleans.Server" Version="2.0.3" />
<PackageReference Include="OrleansDashboard" Version="2.0.7" />
</ItemGroup>
</Project>
using Orleans;
using System;
using System.Threading.Tasks;
namespace Orleans2GettingStarted
{
class Program
{
private async static Task ForeverSendRandomTemperatureReadings(IClusterClient c)
{
var random = new Random();
while (true)
{
var grainId = random.Next(0, 500);
var temperature = random.NextDouble() * 40;
var sensor = c.GetGrain<ITemperatureSensorGrain>(grainId);
await sensor.SubmitTemperatureAsync((float)temperature);
}
}
static async Task Main(string[] args)
{
var (silo, shutdownEvent) = SiloDevelopmentHelpers.BuildNewSilo();
/// Start the silo
await silo.StartAsync();
/// Start and run the client
await ClientDevelopmentHelpers.RunInNewClient(ForeverSendRandomTemperatureReadings);
/// Wait for the silo to completely shutdown before exiting.
shutdownEvent.WaitOne();
}
}
}
using Orleans;
using System.Threading.Tasks;
namespace Orleans2GettingStarted
{
public interface ITemperatureSensorGrain : IGrainWithIntegerKey
{
Task SubmitTemperatureAsync(float temperature);
}
}
using Orleans;
using System;
using System.Threading.Tasks;
namespace Orleans2GettingStarted
{
public class TemperatureSensorGrain : Grain, ITemperatureSensorGrain
{
public Task SubmitTemperatureAsync(float temperature)
{
var grainId = this.GetPrimaryKeyLong();
Console.WriteLine($"{grainId} received temperature: {temperature}");
return Task.CompletedTask;
}
}
}
@Porges
Copy link

Porges commented Jul 6, 2018

You're going to want LangVersion in an unconditional PropertyGroup 🙂

@johnazariah
Copy link
Author

@Porges thank you. fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment