Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Akka.NET v1.0 official release #829

Merged
merged 339 commits into from
Apr 9, 2015
Merged

Conversation

Aaronontheweb
Copy link
Member

1.0.0 Apr 09 2015

Akka.NET is officially no longer in beta status. The APIs introduced in Akka.NET v1.0 will enjoy long-term support from the Akka.NET development team and all of its professional support partners.

Many breaking changes were introduced between v0.8 and v1.0 in order to provide better future extensibility and flexibility for Akka.NET, and we will outline the major changes in detail in these release notes.

However, if you want full API documentation we recommend going to the following:


Updated Packages with 1.0 Stable Release

All of the following NuGet packages have been upgraded to 1.0 for stable release:

  • Akka.NET Core
  • Akka.FSharp
  • Akka.Remote
  • Akka.TestKit
  • Akka.DI (dependency injection)
  • Akka.Loggers (logging)

The following packages (and modules dependent on them) are still in pre-release status:

  • Akka.Cluster
  • Akka.Persistence

Introducing Full Mono Support for Akka.NET

One of the biggest changes in Akka.NET v1.0 is the introduction of full Mono support across all modules; we even have Raspberry PI machines talking to laptops over Akka.Remote!

We've tested everything using Mono v3.12.1 across OS X and Ubuntu.

Please let us know how well Akka.NET + Mono runs on your environment!


API Changes in v1.0

All methods returning an ActorRef now return IActorRef
This is the most significant breaking change introduced in AKka.NET v1.0. Rather than returning the ActorRef abstract base class from all of the ActorOf, Sender and other methods we now return an instance of the IActorRef interface instead.

This was done in order to guarantee greater future extensibility without additional breaking changes, so we decided to pay off that technical debt now that we're supporting these APIs long-term.

Here's the set of breaking changes you need to be aware of:

  • Renamed:
    • ActorRef --> IActorRef
    • ActorRef.Nobody --> ActorRefs.Nobody
    • ActorRef.NoSender --> ActorRefs.NoSender
  • ActorRef's operators == and != has been removed. This means all expressions like actorRef1 == actorRef2 must be replaced with Equals(actorRef1, actorRef2)
  • Tell(object message), i.e. the implicit sender overload, has been moved
    to an extension method, and requires using Akka.Actor; to be accessible.
  • Implicit cast from ActorRef to Routee has been replaced with Routee.FromActorRef(actorRef)

async / await Support

ReceiveActors now support Async/Await out of the box.

public class MyActor : ReceiveActor
{
       public MyActor()
       {
             Receive<SomeMessage>(async some => {
                    //we can now safely use await inside this receive handler
                    await SomeAsyncIO(some.Data);
                    Sender.Tell(new EverythingIsAllOK());                   
             });
       }
}

It is also possible to specify the behavior for the async handler, using AsyncBehavior.Suspend and AsyncBehavior.Reentrant as the first argument.
When using Suspend the normal actor semantics will be preserved, the actor will not be able to process any new messages until the current async operation is completed.
While using Reentrant will allow the actor to multiplex messages during the await period.
This does not mean that messages are processed in parallel, we still stay true to "one message at a time", but each await continuation will be piped back to the actor as a message and continue under the actors concurrency constraint.

However, PipeTo pattern is still the preferred way to perform async operations inside an actor, as it is more explicit and clearly states what is going on.

Switchable Behaviors
In order to make the switchable behavior APIs more understandable for both UntypedActor and ReceiveActor we've updated the methods to the following:

Become(newHandler); // become newHandler, without adding previous behavior to the stack (default)
BecomeStacked(newHandler); // become newHandler, without adding previous behavior to the stack (default)
UnbecomeStacked(); //revert to the previous behavior in the stack

The underlying behavior-switching implementation hasn't changed at all - only the names of the methods.

Scheduler APIs
The Context.System.Scheduler API has been overhauled to be both more extensible and understandable going forward. All of the previous capabilities for the Scheduler are still available, only in different packaging than they were before.

Here are the new APIs:

Context.System.Scheduler
  .ScheduleTellOnce(TimeSpan delay, ICanTell receiver, object message, ActorRef sender);
  .ScheduleTellOnce(TimeSpan delay, ICanTell receiver, object message, ActorRef sender, ICancelable cancelable);
  .ScheduleTellRepeatedly(TimeSpan initialDelay, TimeSpan interval, ICanTell receiver, object message, ActorRef sender);
  .ScheduleTellRepeatedly(TimeSpan initialDelay, TimeSpan interval, ICanTell receiver, object message, ActorRef sender, ICancelable cancelable);

Context.System.Scheduler.Advanced
  .ScheduleOnce(TimeSpan delay, Action action);
  .ScheduleOnce(TimeSpan delay, Action action, ICancelable cancelable);
  .ScheduleRepeatedly(TimeSpan initialDelay, TimeSpan interval, Action action);
  .ScheduleRepeatedly(TimeSpan initialDelay, TimeSpan interval, Action action, ICancelable cancelable);

There's also a set of extension methods for specifying delays and intervals in milliseconds as well as methods for all four variants (ScheduleTellOnceCancelable, ScheduleTellRepeatedlyCancelable, ScheduleOnceCancelable, ScheduleRepeatedlyCancelable) that creates a cancelable, schedules, and returns the cancelable.

Akka.NET Config now loaded automatically from App.config and Web.config
In previous versions Akka.NET users had to do the following to load Akka.NET HOCON configuration sections from App.config or Web.config:

var section = (AkkaConfigurationSection)ConfigurationManager.GetSection("akka");
var config = section.AkkaConfig;
var actorSystem = ActorSystem.Create("MySystem", config);

As of Akka.NET v1.0 this is now done for you automatically:

var actorSystem = ActorSystem.Create("MySystem"); //automatically loads App/Web.config, if any

Dispatchers
Akka.NET v1.0 introduces the ForkJoinDispatcher as well as general purpose dispatcher re-use.

Using ForkJoinDispatcher
ForkJoinDispatcher is special - it uses Helios.Concurrency.DedicatedThreadPool to create a dedicated set of threads for the exclusive use of the actors configured to use a particular ForkJoinDispatcher instance. All of the remoting actors depend on the default-remote-dispatcher for instance.

Here's how you can create your own ForkJoinDispatcher instances via Config:

myapp{
  my-forkjoin-dispatcher{
    type = ForkJoinDispatcher
    throughput = 100
    dedicated-thread-pool{ #settings for Helios.DedicatedThreadPool
      thread-count = 3 #number of threads
      #deadlock-timeout = 3s #optional timeout for deadlock detection
      threadtype = background #values can be "background" or "foreground"
    }
  }
}
}

You can then use this specific ForkJoinDispatcher instance by configuring specific actors to use it, whether it's via config or the fluent interface on Props:

Config

akka.actor.deploy{
     /myActor1{
       dispatcher = myapp.my-forkjoin-dispatcher
     }
}

Props

var actor = Sys.ActorOf(Props.Create<Foo>().WithDispatcher("myapp.my-forkjoin-dispatcher"));

FluentConfiguration [REMOVED]
FluentConfig has been removed as we've decided to standardize on HOCON configuration, but if you still want to use the old FluentConfig bits you can find them here: https://github.com/rogeralsing/Akka.FluentConfig

F# API
The F# API has changed to reflect the other C# interface changes, as well as unique additions specific to F#.

In addition to updating the F# API, we've also fixed a long-standing bug with being able to serialize discriminated unions over the wire. This has been resolved.

Interface Renames
In order to comply with .NET naming conventions and standards, all of the following interfaces have been renamed with the I{InterfaceName} prefix.

The following interfaces have all been renamed to include the I prefix:

  • Akka.Actor.ActorRefProvider, Akka (Public)
  • Akka.Actor.ActorRefScope, Akka (Public)
  • Akka.Actor.AutoReceivedMessage, Akka (Public)
  • Akka.Actor.Cell, Akka (Public)
  • Akka.Actor.Inboxable, Akka (Public)
  • Akka.Actor.IndirectActorProducer, Akka (Public)
  • Akka.Actor.Internal.ChildrenContainer, Akka (Public)
  • Akka.Actor.Internal.ChildStats, Akka (Public)
  • Akka.Actor.Internal.InternalSupportsTestFSMRef2, Akka` (Public)
  • Akka.Actor.Internal.SuspendReason+WaitingForChildren, Akka
  • Akka.Actor.Internals.InitializableActor, Akka (Public)
  • Akka.Actor.LocalRef, Akka
  • Akka.Actor.LoggingFSM, Akka (Public)
  • Akka.Actor.NoSerializationVerificationNeeded, Akka (Public)
  • Akka.Actor.PossiblyHarmful, Akka (Public)
  • Akka.Actor.RepointableRef, Akka (Public)
  • Akka.Actor.WithBoundedStash, Akka (Public)
  • Akka.Actor.WithUnboundedStash, Akka (Public)
  • Akka.Dispatch.BlockingMessageQueueSemantics, Akka (Public)
  • Akka.Dispatch.BoundedDequeBasedMessageQueueSemantics, Akka (Public)
  • Akka.Dispatch.BoundedMessageQueueSemantics, Akka (Public)
  • Akka.Dispatch.DequeBasedMailbox, Akka (Public)
  • Akka.Dispatch.DequeBasedMessageQueueSemantics, Akka (Public)
  • Akka.Dispatch.MessageQueues.MessageQueue, Akka (Public)
  • Akka.Dispatch.MultipleConsumerSemantics, Akka (Public)
  • Akka.Dispatch.RequiresMessageQueue1, Akka` (Public)
  • Akka.Dispatch.Semantics, Akka (Public)
  • Akka.Dispatch.SysMsg.SystemMessage, Akka (Public)
  • Akka.Dispatch.UnboundedDequeBasedMessageQueueSemantics, Akka (Public)
  • Akka.Dispatch.UnboundedMessageQueueSemantics, Akka (Public)
  • Akka.Event.LoggingAdapter, Akka (Public)
  • Akka.FluentConfigInternals, Akka (Public)
  • Akka.Remote.InboundMessageDispatcher, Akka.Remote
  • Akka.Remote.RemoteRef, Akka.Remote
  • Akka.Routing.ConsistentHashable, Akka (Public)

ConsistentHashRouter and IConsistentHashable
Akka.NET v1.0 introduces the idea of virtual nodes to the ConsistentHashRouter, which are designed to provide more even distributions of hash ranges across a relatively small number of routees. You can take advantage of virtual nodes via configuration:

akka.actor.deployment {
    /router1 {
        router = consistent-hashing-pool
        nr-of-instances = 3
        virtual-nodes-factor = 17
    }
}

Or via code:

var router4 = Sys.ActorOf(Props.Empty.WithRouter(
    new ConsistentHashingGroup(new[]{c},hashMapping: hashMapping)
    .WithVirtualNodesFactor(5)), 
    "router4");

ConsistentHashMapping Delegate
There are three ways to instruct a router to hash a message:

  1. Wrap the message in a ConsistentHashableEnvelope;
  2. Implement the IConsistentHashable interface on your message types; or
  3. Or, write a ConsistentHashMapper delegate and pass it to a ConsistentHashingGroup or a ConsistentHashingPool programmatically at create time.

Here's an example, taken from the ConsistentHashSpecs:

ConsistentHashMapping hashMapping = msg =>
{
    if (msg is Msg2)
    {
        var m2 = msg as Msg2;
        return m2.Key;
    }

    return null;
};
var router2 =
    Sys.ActorOf(new ConsistentHashingPool(1, null, null, null, hashMapping: hashMapping)
    .Props(Props.Create<Echo>()), "router2");

Alternatively, you don't have to pass the ConsistentHashMapping into the constructor - you can use the WithHashMapping fluent interface built on top of both ConsistentHashingGroup and ConsistentHashingPool:

var router2 =
    Sys.ActorOf(new ConsistentHashingPool(1).WithHashMapping(hashMapping)
    .Props(Props.Create<Echo>()), "router2");

ConsistentHashable renamed to IConsistentHashable
Any objects you may have decorated with the ConsistentHashable interface to work with ConsistentHashRouter instances will need to implement IConsistentHashable going forward, as all interfaces have been renamed with the I- prefix per .NET naming conventions.

Akka.DI.Unity NuGet Package
Akka.NET now ships with dependency injection support for Unity.

You can install our Unity package via the following command in the NuGet package manager console:

PM> Install-Package Akka.DI.Unity

rogeralsing and others added 30 commits February 28, 2015 07:09
ActorCell already implements IActionContext via IUntypedActorContext
…stRestartPermission

Refactor childStats requestRestartPermission algorithm
Fixes whitespacing and unused references in ChildrenContainerBase.cs
This reverts commit a435803.

The previous version was optimized for the most common scenario, when exceptFor == null.
The LINQ expression introduced in akkadotnet#691 is creating a list every time and uses more enumerators.
Added meaningful ToString() to all system messages
…ing-requestRestartPermission

Revert "Refactor childStats requestRestartPermission algorithm"
Add info on Title and Description for a PR in CONTRIBUTING.md
Add documentation to Watch & Unwatch
Added support to the F# API for actor objects
helps resolve akkadotnet#673

Reimplemented Murmur3, ConsistentHashRouting to use virtual nodes
Added deploy and routerconfig fallback support
Rewrote ActorOf method to LocalActorRefProvider to match Akka
Rewrote ActorOf method to RemoteActorRefProvider to match Akka
Breaking change - renamed ConsistentHashable interface to IConsistentHashable (per akkadotnet#633)
Added MultiNodeTests for ClusterConsistentHashRouting
Implemented Pool routers for Akka.Cluster
Change ordering within ActorSelection to fix issue where /foo paths were...
SeanKilleen and others added 23 commits April 8, 2015 17:01
Reflects changes from conversation in akkadotnet#718.
Generated via the script in the tools directory. The only changes made
to any files in this commit are the additions of comments in the
beginning.

Solution builds and all tests pass.
Because clicking a dialog every time a file is opened is not fun for
most people.
Generated via the script in the tools directory. All CS / FS files now
contain this copyright language.

The only changes made to the files in this commit are the addition of
the comments.

The build still works and all expected tests pass.
Added LearnAkka.NET link in footer
…uris

API docs: changed URLs to hashed member names
Script to add Copyright headers & modify files to add header
Updated PR for fixing F# discriminated unions
@Aaronontheweb
Copy link
Member Author

cc @akkadotnet/contributors @akkadotnet/developers

Congratulations to the team and everyone else who helped make this possible.

It was a lot of hard work. More than a year's worth of effort from some of the best .NET developers on the planet.

But we did it - Akka.NET v1.0 is ready for the world.

8a65czr - imgur

Aaronontheweb added a commit that referenced this pull request Apr 9, 2015
Akka.NET v1.0 official release
@Aaronontheweb Aaronontheweb merged commit 21cb5c1 into akkadotnet:master Apr 9, 2015
@stefansedich
Copy link
Contributor

Yay

@skotzko
Copy link
Contributor

skotzko commented Apr 9, 2015

@stefansedich is that a young @rogeralsing I see?

@skotzko
Copy link
Contributor

skotzko commented Apr 9, 2015

dancing

@jcwrequests
Copy link

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.