### Legacy Runtime Package Installation Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Instructions on installing the `Orleankka.Legacy.Runtime` NuGet package, which is necessary for projects referencing the `Actor` class or configuring the silo after upgrading to Orleankka 2.x. ```cs # Install Orleankka.Legacy.Runtime NuGet package # dotnet add package Orleankka.Legacy.Runtime ``` -------------------------------- ### Configuration Setup with SiloHostBuilder/ClientBuilder Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Describes the shift in Orleankka 2.x configuration, where it no longer wraps the Orleans configuration builder but acts as an extension. Setup is now done via native Orleans configuration APIs like `SiloHostBuilder` or `ClientBuilder`. ```cs // Configuration setup in 2.x uses native Orleans builders: // For Silo: // var host = new SiloHostBuilder() // .UseOrleankka() // .ConfigureServices(services => { /* ... */ }) // .Build(); // For Client: // var client = new ClientBuilder() // .UseOrleankka() // .ConfigureServices(services => { /* ... */ }) // .Build(); ``` -------------------------------- ### Orleans Client Setup (Before Orleans 2.0) Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Demonstrates the client configuration using `ActorSystem.Configure()` before the Orleans 2.0 changes, including setting up cluster options, local clustering, and message streams. ```cs /// BEFORE var system = ActorSystem.Configure() .Client() .Builder(b => b.Configure(options => { options.ClusterId = "test"; options.ServiceId = "test"; }) .UseLocalhostClustering() .AddSimpleMessageStreamProvider("sms")) .Assemblies(typeof(IMyActor).Assembly) .Done(); await system.Connect(); // <-- this piece of cheese is moved ``` -------------------------------- ### Orleans Client Setup (After Orleans 2.0) Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Illustrates the client configuration after Orleans 2.0, showing the use of `ClientBuilder`, `UseOrleankka()`, `UseOrleankkaLegacyFeatures()`, and a custom `Connect()` method for establishing a connection to the cluster. ```cs /// AFTER public static async Task Main() { var system = await Connect(retries: 2); ... } static async Task Connect(int retries = 0, TimeSpan? retryTimeout = null) { if (retryTimeout == null) retryTimeout = TimeSpan.FromSeconds(5); while (true) { try { var client = new ClientBuilder() .Configure(options => { options.ClusterId = DemoClusterId; options.ServiceId = DemoServiceId; }) .UseLocalhostClustering() .ConfigureApplicationParts(x => x .AddApplicationPart(typeof(IChatUser).Assembly) .WithCodeGeneration()) .UseOrleankka() .UseOrleankkaLegacyFeatures(o => o .AddSimpleMessageStreamProvider("sms")) .Build(); await client.Connect(); return client.ActorSystem(); // <- extension method to get actor system } catch (Exception ex) { if (retries-- == 0) { Console.WriteLine("Can't connect to cluster. Max retries reached."); throw; } Console.WriteLine( $"Can't connect to cluster: '{ex.Message}'." + $"Trying again in {(int)retryTimeout.Value.TotalSeconds} seconds ..."); await Task.Delay(retryTimeout.Value); } } } ``` -------------------------------- ### Install Orleankka and Orleans Packages Source: https://github.com/orleanscontrib/orleankka/blob/master/Docs/articles/intro/getting-started-csharp.md Installs the Orleankka.Runtime and Microsoft.Orleans.Server packages using the Package Manager Console in Visual Studio. These packages are essential for building Orleankka applications. ```powershell PM> Install-Package Orleankka.Runtime PM> Install-Package Microsoft.Orleans.Server ``` -------------------------------- ### Install Orleankka Client (NuGet) Source: https://github.com/orleanscontrib/orleankka/blob/master/README.md Installs the Orleankka client library using the NuGet package manager console. ```powershell PM> Install-Package Orleankka.Client ``` -------------------------------- ### Install Orleankka Runtime (NuGet) Source: https://github.com/orleanscontrib/orleankka/blob/master/README.md Installs the Orleankka server-side runtime library using the NuGet package manager console. ```powershell PM> Install-Package Orleankka.Runtime ``` -------------------------------- ### Logging Configuration with Microsoft.Extensions.Logging Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Demonstrates how to configure logging in Orleankka 2.0 using `Microsoft.Extensions.Logging.Console` and the `AddLogging` extension method. ```csharp services.AddLogging(configure => configure.AddConsole()); ``` -------------------------------- ### Orleans 2.0 Configuration Extensions Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Demonstrates how to use new `Builder` methods for configuring Orleankka with Orleans 2.0 extensions, such as registering the OrleansDashboard. ```csharp ClusterActorSystem.Builder(siloBuilder => siloBuilder.AddDashboard(options => { /* dashboard options */ })); ClientActorSystem.Builder(clientBuilder => clientBuilder.AddDashboard(options => { /* dashboard options */ })); ``` -------------------------------- ### Orleankka 1.x Server Configuration Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Illustrates the configuration of an Orleankka server host in version 1.x using ActorSystemConfigurator. ```cs /// BEFORE var system = ActorSystem.Configure() .Cluster() .Builder(b => b .Configure(options => { options.ClusterId = "test"; options.ServiceId = "test"; }) .UseLocalhostClustering() .AddSimpleMessageStreamProvider("sms") .AddMemoryGrainStorage("PubSubStore")) .Assemblies( typeof(Join).Assembly, Assembly.GetExecutingAssembly()) .Done(); system.Start().Wait(); ``` -------------------------------- ### Orleans Grain Type Code Logging Example Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 This snippet shows an example of Orleans logging output that displays grain type summaries, including grain class names, their computed type codes (both signed and hexadecimal), and the interfaces they implement. This information is crucial for applying `TypeCodeOverride`. ```log info: Orleans.Runtime.GrainTypeManager[101711] Loaded grain type summary for 12 types: Grain class Fun.Fun.Api [-1093717963 (0xBECF3035)] from Orleankka.Auto.Implementations.dll implementing interfaces: Orleans.IRemindable [-831689659 (0xCE6D6C45)], Fun.IApi [428485482 (0x198A2B6A)], Orleankka.Core.IActorEndpoint [-1771180915 (0x966DEC8D)], Orleans.IGrainWithStringKey [-1277021679 (0xB3E23211)] Grain class Fun.Demo.Fun.Demo.ITopic [348193966 (0x14C104AE)] from Orleankka.Auto.Implementations.dll implementing interfaces: Orleans.IRemindable [-831689659 (0xCE6D6C45)], Fun.Demo.IITopic [433931250 (0x19DD43F2)], Orleankka.Core.IActorEndpoint [-1771180915 (0x966DEC8D)], Orleans.IGrainWithStringKey [-1277021679 (0xB3E23211)] ``` -------------------------------- ### Enabling Orleankka Legacy Features Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Shows how to enable legacy Orleankka features, such as declarative stream subscriptions, in version 2.x. ```cs .UseOrleankka(x => x .ActorMiddleware(new LoggingMiddleware())) .UseOrleankkaLegacyFeatures(x => x // <--- enable Orleankka legacy features .AddSimpleMessageStreamProvider("sms") // <--- hook declarative stream subscriptions .RegisterPersistentStreamProviders("aqp")); // <--- hook declarative stream subscriptions .Build(); ``` -------------------------------- ### Actor Type Mapping Helper Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Provides a static class example for mapping string actor codes to their corresponding interface types, a common pattern after the removal of the [ActorType] attribute. This helper can be used for dynamic actor type selection or storage purposes. ```cs static class ActorTypeMap { static Dictionary byCode = new Dictionary(); static Dictionary byType = new Dictionary(); static ActorTypeMap() { Add("foo"); void Add(string code) where T : IActor { byCode.Add(code, typeof(T)); byType.Add(typeof(T), code); } } } ``` -------------------------------- ### In-Memory Grain Storage for Orleankka 2.0 Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Shows how to use the `UseInMemoryGrainStore` extension on `ClusterActorSystem` to replicate the functionality of `ClusterConfiguration.AddMemoryStorageProvider` from Orleankka 1.5. ```csharp var cluster = ClusterActorSystem.Builder() .UseInMemoryGrainStore() .Build(); ``` -------------------------------- ### Orleankka 2.x Server Configuration Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Demonstrates the updated server host configuration in Orleankka 2.x using SiloHostBuilder, including enabling Orleankka and code generation. ```cs /// AFTER var host = new SiloHostBuilder() .Configure(options => { options.ClusterId = "test"; options.ServiceId = "test"; }) .UseLocalhostClustering() .AddSimpleMessageStreamProvider("sms") .AddMemoryGrainStorage("PubSubStore") .ConfigureApplicationParts(x => x .AddApplicationPart(Assembly.GetExecutingAssembly()) .AddApplicationPart(typeof(IMyActor).Assembly) .AddApplicationPart(typeof(MemoryGrainStorage).Assembly) .WithCodeGeneration()) // <--- important .UseOrleankka(x => x // <--- enable Orleankka .ActorMiddleware(new LoggingMiddleware())) .Build(); await host.StartAsync(); ``` -------------------------------- ### Configuration and Registration Updates Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Illustrates how to register middleware using the `ClusterConfigurator` in Orleankka 2.x, contrasting with previous versions. This includes using `ActorRefMiddleware` and `ActorMiddleware` methods. ```cs // Example of registering middleware in ClusterConfigurator // For ActorRefMiddleware: // clusterConfigurator.ActorRefMiddleware(m => new MyActorRefMiddleware()); // For ActorMiddleware: // clusterConfigurator.ActorMiddleware(m => new MyActorMiddleware()); ``` -------------------------------- ### Persistent Stream Provider Registration (Native) Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Shows how to register native persistent stream providers (e.g., Azure Queue Streams) on `ISiloHostBuilder` or `IClientBuilder` and then register their names with the cluster actor system. ```csharp // Example for SiloHostBuilder siloBuilder.AddAzureQueueStreams(o => { o.ConfigureAzureQueueTransport( (\Action)(x => x.UseAzureQueueClient("connection-string", "queue-name")) ); }); // Registering the provider name with ClusterActorSystem var cluster = ClusterActorSystem.Builder() .RegisterPersistentStreamProviders("azure-queue") .Build(); ``` -------------------------------- ### Azure Blob Storage and Table Reminder Service Configuration Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Illustrates configuring Azure Blob Storage and Azure Table Reminder Service using extension methods available on `IServiceCollection` in Orleankka 2.0. ```csharp // For Azure Blob Storage services.AddAzureBlobGrainStorage("myStorage", options => { options.ConfigureBlobServiceClient("connection-string"); }); // For Azure Table Reminder Service services.AddAzureTableReminderService(options => { options.ConfigureTableServiceClient("connection-string"); }); ``` -------------------------------- ### Actor Code Fixes: Interface and Namespace Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Details the required code modifications for actors, specifically changing the `IActor` interface to `IActorGrain` and importing the `Orleankka.Legacy.Runtime` namespace. ```cs // Fix 1: Change interface // public interface IActor -> public interface IActorGrain // Fix 2: Import namespace // using Orleankka.Legacy.Runtime; ``` -------------------------------- ### Actor Activation with IGrainActivator Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Demonstrates the migration from IActorActivator to IGrainActivator for actor activation, including handling non-actor instances and integrating with dependency injection. This change is necessary for Orleankka's native actor activator API. ```cs /// BEFORE class DI : IActorActivator { ... public Actor Activate(Type type, string id, IActorRuntime runtime, Dispatcher dispatcher) { if (type == typeof(Api)) return new Api(new ObserverCollection(), ApiWorkerFactory.Create(id)); if (type == typeof(Topic)) return new Topic(storage); throw new InvalidOperationException($"Unknown actor type: {type}"); } } /// AFTER class DI : IGrainActivator { readonly IServiceProvider services; readonly DefaultGrainActivator activator; public DI(IServiceProvider services) { this.services = services; activator = new DefaultGrainActivator(services); } public object Create(IGrainActivationContext context) { var type = context.GrainType; var id = context.GrainIdentity.PrimaryKeyString; if (!typeof(Actor).IsAssignableFrom(type)) return activator.Create(context); if (type == typeof(Api)) return new Api(new ObserverCollection(), ApiWorkerFactory.Create(id)); if (type == typeof(Topic)) return new Topic(services.GetService()); throw new InvalidOperationException($"Unknown actor type: {type}"); } public void Release(IGrainActivationContext context, object grain) { if (!typeof(Actor).IsAssignableFrom(context.GrainType)) activator.Release(context, grain); } } ``` -------------------------------- ### TimerService Registration Update Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Highlights the change in `TimerService.Register` and `Unregister` methods, which now require a timer ID. This contrasts with the 1.x version where the callback function name could be used as the ID. ```cs // In 2.x, TimerService.Register requires a timer ID: // TimerService.Register(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), "MyTimerId", state); // TimerService.Unregister("MyTimerId"); ``` -------------------------------- ### API Changes: ActorPath and ActorSystem Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Illustrates the API modifications related to actor path management and actor system interactions. This includes the renaming of `ActorPath.Type` to `ActorPath.Interface` and the removal/replacement of methods for acquiring actor references. ```APIDOC ActorPath.Type Renamed to ActorPath.Interface - Description: The `Type` property of `ActorPath` has been renamed to `Interface`. It now stores the fully qualified name of the actor interface. ActorPath.From(string type, string id) Removed - Description: This method has been removed. Use `ActorPath.For(string id)` or `ActorPath.For(Type actorInterfaceType, string id)` instead. - Example: - Before: `ActorPath.From("Api", "facebook")` - After: `ActorPath.For("facebook")` or `ActorPath.For(typeof(IApi), "facebook")` ActorPathExtensions.ToActorPath Removed - Description: This extension method has been removed. Use `ActorPath.For()` directly. ActorSystem.ActorOf/WorkerOf/TypedActorOf Updates - Description: These methods now require the actor interface type to be specified as a generic constraint instead of a string type name. This is a consequence of the removal of the `[ActorType]` attribute and the reliance on native grain interfaces. - Example: - Before: `actorSystem.ActorOf("MyActor")` - After: `actorSystem.ActorOf()` ``` -------------------------------- ### Persistent Stream Provider Registration (TCP) Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Configures the Simple Message Stream (SMS) provider for TCP streaming in Orleankka 2.0, setting `FireAndForgetDelivery` to false. ```csharp var cluster = ClusterActorSystem.Builder() .UseSimpleMessageStreamProvider("sms", o => o.Configure(x => x.FireAndForgetDelivery = false)) .Build(); ``` -------------------------------- ### Sticky Actor Implementation using ActorInvoker Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Shows how to replicate the 'Sticky Actor' functionality using an ActorInvoker. This involves creating a handler that registers a reminder to keep the actor alive and applying the invoker to the desired actor class. ```cs /// interceptor public class StickyHandler : ActorInvoker { const string StickyReminderName = "##sticky##"; public StickyHandler(IActorInvoker next = null) : base(next) {} public override async Task OnActivate(Actor actor) { var period = TimeSpan.FromMinutes(1); await actor.Reminders.Register(StickyReminderName, period, period); await base.OnActivate(actor); } public override async Task OnReminder(Actor actor, string id) { if (id == StickyReminderName) return; await base.OnReminder(actor, id); } } /// apply to an actor [Invoker("sticky")] [TypeCodeOverride(-1483810351)] public class AccountingFeedPoller : Actor, IAccountingFeedPoller {} /// register invoker var config = ActorSystem.Configure() .Cluster .ActorInvoker("sticky", new StickyHandler()); ``` -------------------------------- ### FireSelf Method Replacement in Orleankka Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Provides a C# implementation for the `FireSelf` method, replacing the deprecated `ActorBehavior.Fire` functionality. This method handles sending messages to self, with a testing flag to route messages through `OnReceive`. ```cs public abstract class ProcessManager : Actor { public bool FireMessagesToSelfViaReceiveForTesting; public async Task FireSelf(object message) { if (FireMessagesToSelfViaReceiveForTesting) { await OnReceive(message); return; } var sender = Behavior.Current; try { await Self.Tell(message); } catch (UnhandledMessageException) when (sender != Behavior.Current) { Log.Warning( "Message `{message}` sent to the self from the behavior `{sender}` was unhandled. " + "Perhaps due to the current behavior `{current}` being different (ie switched). Ignoring ...", message.GetType(), sender, Behavior.Current); } } } ``` -------------------------------- ### TestKit Changes for Callback Timers Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Explains how to unit test callback-based timers in Orleankka 2.x. It requires casting the returned `RecordedTimer` to `RecordedCallbackTimer` and accessing the function pointer via the `Callback()` property. ```cs // To unit test callback-based timers in 2.x: // var recordedTimer = timerManager.RecordedTimers.Single(); // var callbackTimer = recordedTimer.CallbackTimer(); // var callback = callbackTimer.Callback(); // Get function pointer ``` -------------------------------- ### Actor Invoker to Middleware API Change Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Demonstrates the structural changes required when migrating from the older `IActorInvoker` interface to the new `IActorMiddleware` interface in Orleankka. This includes changes in method signatures and how lifecycle events and message handling are managed. ```cs /// BEFORE public interface IActorInvoker { Task OnReceive(Actor actor, object message); Task OnReminder(Actor actor, string id); Task OnActivate(Actor actor); Task OnDeactivate(Actor actor); } public class TestActorInterceptionInvoker : ActorInvoker { public override Task OnReceive(Actor actor, object message) { if (message is Foo) { Log.Error($"Intercepted poison message destined to {actor.GetType()}:{actor.Id}"); throw new InvalidOperationException("foo is not allowed"); } return base.OnReceive(actor, message); } public override async Task OnActivate(Actor actor) { await base.OnActivate(actor); Log.Info($"{actor.GetType()}:{actor.Id} activated"); } } ``` ```cs /// AFTER public interface IActorMiddleware { Task Receive(Actor actor, object message, Receive receiver); } public class TestActorMiddleware : ActorMiddleware { public override Task Receive(Actor actor, object message, Receive receiver) { switch (message) { case Foo _: Log.Error($"Intercepted poison message destined to {actor.GetType()}:{actor.Id}"); throw new InvalidOperationException("foo is not allowed"); case Bar _: Log.Warning($"Bailing out silently for Bar message destined to {actor.GetType()}:{actor.Id}"); return null; case Activate _: Log.Info($"{actor.GetType()}:{actor.Id} activated"); break; } return Next.Receive(actor, message, receiver); } } ``` -------------------------------- ### Orleankka 1.x Auto-Generated Interface Path Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 In Orleankka version 1.x, auto-generated interfaces and classes had paths like `Fun.X`, where `X` was either the actor type name or the full path of the actor's interface or class. This was crucial for message routing and external service compatibility. ```csharp namespace Fun { public interface MyActor : Orleans.IGrainWithGuidKey {} } ``` -------------------------------- ### MayInterleave Callback Signature Alignment Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Illustrates the change in the signature for callback methods specified with the `[MayInterleave]` attribute. The signature has been updated to align with Orleans native 2.x, changing the message parameter type from `object` to `InvokeMethodRequest`. ```cs /// BEFORE [MayInterleave(nameof(IsReentrant))] class TestActor : Actor, ITestActor { public static bool IsReentrant(object msg) => msg is ReentrantMessage; } /// AFTER [MayInterleave(nameof(IsReentrant))] class TestActor : Actor, ITestActor { public static bool IsReentrant(InvokeMethodRequest req) => req.Message(x => x is ReentrantMessage); } ``` -------------------------------- ### Attribute Change: Interleave to MayInterleave Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Demonstrates the refactoring required to replace the deprecated [Interleave] attribute with the native [MayInterleave] attribute. This involves defining a static predicate function to specify which message types can be interleaved. ```cs /// before [Interleave(typeof(Foo))] [Interleave(typeof(Bar))] public class MyActor : Actor, IMyActor { } /// 2.0.0-transitional-011 using Orleans.Concurrency; [MayInterleave(nameof(IsReentrant))] public class MyActor : Actor, IMyActor { public static bool IsReentrant(object msg) => msg is Foo || msg is Bar; } ``` -------------------------------- ### Applying TypeCodeOverride in C# Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Demonstrates how to use the `TypeCodeOverride` attribute in C# to explicitly set the type code for a grain interface and its corresponding actor class. This is necessary to resolve potential hash collisions or to manage type identities during upgrades. ```cs [TypeCodeOverride(428485482)] public interface IApi : IActor {} [TypeCodeOverride(-1093717963)] public class Api : Actor, IApi {} ``` -------------------------------- ### Orleankka Migration Workaround: TypeCodeOverride Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 To migrate live clusters from Orleankka 1.x to 2.0 without breaking message routing or external service integrations, the `TypeCodeOverride` mechanism can be used. This allows maintaining the original auto-generated interface/class names and paths during the transition. ```csharp // Example of how TypeCodeOverride might be used (conceptual) // This is not actual executable code but illustrates the concept. // Assuming 'MyActor' was the 1.x generated interface name public static class ActorTypeCodeOverrides { public static void RegisterOverrides() { // Register an override for a specific actor type or interface // This would map the new 2.x implementation to the old 1.x interface name // Example: Orleankka.TypeCodeOverride.Register(); } } ``` -------------------------------- ### Custom KeepAliveAttribute Implementation Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Provides a C# implementation for a custom KeepAliveAttribute and its integration with Orleans' silo host builder. This code dynamically finds actors with the attribute and configures their specific collection ages based on the attribute's properties. ```cs [AttributeUsage(AttributeTargets.Class)] public class KeepAliveAttribute : Attribute { public int Hours { get; set; } public int Minutes { get; set; } } // on ISiloHostBuilder builder.Configure(o => { var actors = Assembly.GetExecutingAssembly().GetTypes() .Where(x => typeof(Actor).IsAssignableFrom(x) && !x.IsAbstract); foreach (var each in actors) { var att = each.GetCustomAttribute(); if (att == null) continue; var hh = att.Hours; var mm = att.Minutes; var @interface = ActorInterface.Of(each); o.ClassSpecificCollectionAge[$"Fun.{@interface.FullName}"] = TimeSpan.FromMinutes(mm + hh * 60); } }); ``` -------------------------------- ### Orleankka Actor Attributes Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 This section details the `ActorType` attribute in Orleankka, which serves as an alias for actor interface types. It specifies that this attribute should now be placed on custom actor interfaces, not actor classes, as was previously allowed for interfaceless actors. ```APIDOC ActorType("foo") - Alias for actor interface types. - Must be placed on a custom actor interface. - Previously could be placed on actor classes for interfaceless actors. ``` -------------------------------- ### Configure Grain Collection Age with KeepAliveAttribute Source: https://github.com/orleanscontrib/orleankka/wiki/Migration-from-1.5-to-2.0 Demonstrates how to configure the grain collection age for specific actor types using a custom KeepAliveAttribute. This approach deviates from standard Orleans configuration by using the actor interface's full name and a 'Fun.' prefix. ```cs builder.Configure(o => o .ClassSpecificCollectionAge[$"Fun.{typeof(IMyActor).FullName}"] = TimeSpan.FromMinutes(2)); ``` -------------------------------- ### Configure and Run Orleankka Application Source: https://github.com/orleanscontrib/orleankka/blob/master/Docs/articles/intro/getting-started-csharp.md Sets up the Orleans Silo and Client, registers the Orleankka extension, and demonstrates actor interaction (Ask and Tell). ```csharp using System; using Orleankka; using Orleankka.Playground; namespace ConsoleApplication11 { [Serializable] public class Greet { public string Who { get; set; } } [Serializable] public class Sleep {} public class Greeter : ActorGrain, IGreeter { public override Task Receive(object message) { switch (message) { case Greet greet: return Result("Hello, {msg.Who}!"); case Sleep _: Console.WriteLine("Sleeeeping ..."); return TaskResult.Done; default: return Unhandled; } } } class Program { const string DemoClusterId = "localhost-demo"; const string DemoServiceId = "localhost-demo-service"; const int LocalhostSiloPort = 11111; const int LocalhostGatewayPort = 30000; static readonly IPAddress LocalhostSiloAddress = IPAddress.Loopback; static void Main(string[] args) { var host = await new SiloHostBuilder() .Configure(options => { options.ClusterId = DemoClusterId; options.ServiceId = DemoServiceId; }) .UseDevelopmentClustering(options => options.PrimarySiloEndpoint = new IPEndPoint(LocalhostSiloAddress, LocalhostSiloPort)) .ConfigureEndpoints(LocalhostSiloAddress, LocalhostSiloPort, LocalhostGatewayPort) .ConfigureApplicationParts(x => x .AddApplicationPart(Assembly.GetExecutingAssembly()) .WithCodeGeneration()) .UseOrleankka() // register Orleankka extension .Build(); // start Orleans server (silo) await host.StartAsync(); var client = new ClientBuilder() .ConfigureCluster(options => { options.ClusterId = DemoClusterId; options.ServiceId = DemoServiceId }) .UseStaticClustering(options => options.Gateways.Add(new IPEndPoint(LocalhostSiloAddress, LocalhostSiloPort).ToGatewayUri())) .ConfigureApplicationParts(x => x .AddApplicationPart(Assembly.GetExecutingAssembly()) .WithCodeGeneration()) .UseOrleankka() .Build(); // start (connect) Orleans client await client.Connect(); // get reference to ActorSystem var system = client.ActorSystem(); // get proxy reference for IGreeter actor var greeter = system.ActorOf("id"); // send query to actor (ie Ask) Console.WriteLine(await greeter.Ask(new Greet {Who = "world"})); // send command to actor (ie Tell) await greeter.Tell(new Sleep()); Console.Write("\n\nPress any key to terminate ..."); Console.ReadKey(true); } } } ``` -------------------------------- ### Build Orleankka Sources (Windows) Source: https://github.com/orleanscontrib/orleankka/blob/master/README.md Builds the Orleankka project on Windows using Nake.bat. Restores dependencies and builds in debug mode. Use '-T' for available commands. ```powershell PM> Nake.bat ``` -------------------------------- ### Implement an Actor Source: https://github.com/orleanscontrib/orleankka/blob/master/Docs/articles/intro/getting-started-csharp.md Implements a Greeter actor by inheriting from ActorGrain and handling incoming messages using pattern matching. ```csharp using System; using Orleankka; namespace ConsoleApplication11 { // Create custom actor interface and implement IActorGrain public interface IGreeter : IActorGrain {} // Create actor class by inheriting from ActorGrain and implementing custom actor interface public class Greeter : ActorGrain, IGreeter { // Implement receive function (use pattern matching or any other message matching approach) public override Task Receive(object message) { switch (message) { case Greet greet: return Result("Hello, {msg.Who}!"); case Sleep _: Console.WriteLine("Sleeeeping ..."); return TaskResult.Done; break; default: return Unhandled; } } } } ``` -------------------------------- ### Build Orleankka Sources (MacOS/Linux) Source: https://github.com/orleanscontrib/orleankka/blob/master/README.md Builds, packages, or runs tests for Orleankka on MacOS/Linux using a shell script. ```bash $> ./nake.sh ``` -------------------------------- ### Open Iconic with Foundation Source: https://github.com/orleanscontrib/orleankka/blob/master/Samples/CSharp/FSM/ProcessManager/wwwroot/css/open-iconic/README.md Demonstrates integration with the Foundation framework. Similar to Bootstrap, this requires linking the Foundation-specific stylesheet and using the `fi-icon-name` class for icons. Accessibility attributes are also included. ```html ``` -------------------------------- ### Apache License 2.0 Boilerplate Source: https://github.com/orleanscontrib/orleankka/blob/master/LICENSE.txt This snippet provides the standard boilerplate text for applying the Apache License, Version 2.0 to a project. It includes placeholders for copyright year and owner, and the full license text. ```text Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` -------------------------------- ### Apache License 2.0 Source: https://github.com/orleanscontrib/orleankka/blob/master/LICENSE.txt The Apache License, Version 2.0, provides a legal framework for the use, modification, and distribution of software. It grants users broad permissions while requiring attribution and adherence to specific terms. ```APIDOC Apache License, Version 2.0 (January 2004) http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions: - License: Terms and conditions for use, reproduction, and distribution. - Licensor: Copyright owner granting the License. - Legal Entity: Entity and those controlling it. - You: Individual or Legal Entity exercising permissions. - Source form: Preferred form for modifications (code, docs, config). - Object form: Result of mechanical transformation (compiled code, etc.). - Work: Authorship made available under the License. - Derivative Works: Works based on the Work with original authorship. - Contribution: Authorship intentionally submitted to Licensor. - Contributor: Licensor and those whose Contributions are incorporated. 2. Grant of Copyright License: - Grants a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license. - Permissions include reproduction, preparation of Derivative Works, public display, performance, sublicensing, and distribution. 3. Grant of Patent License: - Grants a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable patent license. - Applies to patent claims necessarily infringed by the Contribution alone or with the Work. - License terminates if You initiate patent litigation against any entity concerning the Work or Contribution. 4. Redistribution: - You may reproduce and distribute copies of the Work. ``` -------------------------------- ### Using Open Iconic SVG Sprite Source: https://github.com/orleanscontrib/orleankka/blob/master/Samples/CSharp/FSM/ProcessManager/wwwroot/css/open-iconic/README.md Illustrates the usage of Open Iconic's SVG sprite for efficient icon display. This method allows all icons to be loaded in a single request. It involves using the `` tag with `xlink:href` to reference specific icons within the sprite. Styling and coloring are achieved through CSS. ```html ``` ```css .icon { width: 16px; height: 16px; } .icon-account-login { fill: #f00; } ``` -------------------------------- ### Using Open Iconic SVGs Source: https://github.com/orleanscontrib/orleankka/blob/master/Samples/CSharp/FSM/ProcessManager/wwwroot/css/open-iconic/README.md Demonstrates how to use individual SVG files from Open Iconic. This method involves referencing the SVG file directly in an `` tag. Ensure to include an `alt` attribute for accessibility. ```html icon name ``` -------------------------------- ### Open Iconic Standalone Usage Source: https://github.com/orleanscontrib/orleankka/blob/master/Samples/CSharp/FSM/ProcessManager/wwwroot/css/open-iconic/README.md Provides instructions for using Open Iconic's icon font independently. This involves linking the default stylesheet and using the `oi` class with the `data-glyph` attribute to specify the icon. Accessibility attributes are also recommended. ```html ``` -------------------------------- ### Open Iconic with Bootstrap Source: https://github.com/orleanscontrib/orleankka/blob/master/Samples/CSharp/FSM/ProcessManager/wwwroot/css/open-iconic/README.md Shows how to integrate Open Iconic with Bootstrap. This involves linking the Bootstrap-specific stylesheet and using the `oi` and `oi-icon-name` classes for icon display. The `title` and `aria-hidden` attributes are recommended for accessibility and tooltips. ```html ``` -------------------------------- ### Define Actor Message Types Source: https://github.com/orleanscontrib/orleankka/blob/master/Docs/articles/intro/getting-started-csharp.md Defines serializable message types for actor communication. These classes represent the data exchanged between actors. ```csharp namespace ConsoleApplication11 { // Create a message types that your actor will respond to // and mark them with [Serializable] attribute. This is smilar to // object-oriented interface signatures (eg Greet(string who)) but with classes [Serializable] public class Greet { public string Who { get; set; } } [Serializable] public class Sleep {} } ``` -------------------------------- ### Api Actor Behavior Source: https://github.com/orleanscontrib/orleankka/blob/master/Samples/CSharp/Demo/Demo.App/README.txt Describes the behavior of the Api actor, which acts as a singleton per search provider. It performs search requests, implements the Circuit Breaker pattern to handle API unavailability, and can notify about availability changes. Management of search provider request limits is noted as out of scope for the sample project. ```APIDOC Api: - Singleton actor per search provider. - Performs search requests against search provider APIs. - Implements Circuit Breaker pattern: - Locks itself to prevent 'real' search requests during API unavailability. - Notifies about availability changes. - Manages search provider request limits (out of scope for sample project). ``` -------------------------------- ### SystemConsole Actor Behavior Source: https://github.com/orleanscontrib/orleankka/blob/master/Samples/CSharp/Demo/Demo.App/README.txt Outlines the role of the SystemConsole actor, an external client that monitors the availability of Api actors. It subscribes to notifications from Api actors and allows administrators to re-enable searches for specific APIs. ```APIDOC SystemConsole: - External client monitoring Api availability. - Subscribes to notifications from Api. - Allows administrators to re-enable searches for particular Api. ``` -------------------------------- ### Topic Retry Scenarios Source: https://github.com/orleanscontrib/orleankka/blob/master/Samples/CSharp/Demo/Demo.App/README.txt Documents the scenarios for how a Topic actor handles failures and retries when communicating with an Api actor. This includes scheduling local timers for retries, disabling searches after consecutive failures, and canceling timers when the Api becomes available again. ```APIDOC Scenarios: Topic first-time failure handling: - On first failed reply from Api, schedule local timer to retry every 5 seconds. Topic consecutive failure handling: - If Api unavailable for 3 consecutive retries: - Disable search for that Api (delete persistent reminder). - Cancel local retry timer. Topic recovery handling: - If Api becomes available during retries: - Cancel local retry timer. - Allow scheduled searches. Topic scheduled search handling: - If Topic receives scheduled search request (from persistent reminder): - Ignore if in retry state. - Issue search request to Api otherwise. ``` -------------------------------- ### Topic Actor Behavior Source: https://github.com/orleanscontrib/orleankka/blob/master/Samples/CSharp/Demo/Demo.App/README.txt Details the responsibilities of the Topic actor, which executes user-specified queries against Api actors on a recurrent schedule. It aggregates results, stores them in a BLOB, and manages its schedule via persistent reminders. The storage and restoration of the schedule are out of scope for the sample project. ```APIDOC Topic: - Executes user-specified queries against Api actors on a recurrent schedule. - Aggregates results from Api. - Stores aggregated total in a BLOB. - Stores configured schedule in another BLOB. - Restores its schedule upon activation (updates persistent reminders) (out of scope for sample project). ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.