-
Notifications
You must be signed in to change notification settings - Fork 1k
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
F# API changes #526
F# API changes #526
Conversation
Looks good as far as I can tell, but my F# skills is not enough to review this. |
I can't really review this either. I have one remark: let inline private loggerFor (context : IActorContext) : LoggingAdapter = Logging.GetLogger(context)
let log (level : LogLevel) (mailbox : Actor<'a>) (msg: string) : unit =
let logger = loggerFor mailbox.Context
logger.Log(level, msg)
let inline logDebug mailbox msg = log (LogLevel.DebugLevel) mailbox msg
Everytime one logs, |
Thx @HCanber . Indeed |
Yeah, that's what we recommended in C#. public class MyActor : ReceiveActor
{
private readonly LoggingAdapter _log = Context.GetLogger();
...
} |
Lazy logger creation pattern has been applied. |
I've renamed Additionally I've extended share-nothing remote actor deployment example. Now it illustrated a way of dealing with passing more complex data structures - since F# expression cannot serialize definitions of any types and functions declared outside of the expression itself. Closest-to-erlang solution is to passing message in form of a tagged tuple, but since there is no erlang atom equivalent in F#, I've used integer constant literals, which could be used for tagging instead. PS: Waiting for positive contribution review ;) |
[<Interface>] | ||
type Actor<'msg> = | ||
inherit ActorRefFactory | ||
(** Explicitly retrieves next incoming message from the mailbox. *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please document using /// XML-doc comments - which are standard for F# coding. (Unless there's some reason not to)
… arguments for spawning parameters - list of options
Almost all of @dsyme comments has been taken into account. I want to discuss about two of them:
|
@Horusiath I'm not an experienced F# developer, but these conventions seem reasonable to me. |
I'm OK with this - if I get the chance to start using the API (I hope to) then I may have more input. Please also get on twitter and encourage people to trial the API and give feedback. Some F# Interactive actor scripting samples would also be useful in that regard, for tutorial purposes. |
Will this bring the API docs up-to-date too? http://akkadotnet.github.io/wiki/FSharp%20API |
@dsyme API documentation needs a separate commit. I'll be more than happy to give some better insights on official Akka.NET site. Current samples are available on this git repo under /src/examples directory. This commit also gives a new example of remote actor deployment feature for F# API and updates those, which have existed already. |
Can I ask, what is the state of this commit? Accordingly to F# Advent Calendar my tomorrow (Sunday) presentation should be about Akka.NET remote deployment with F#. I just like to know if I could use new API features for this purpose, or stay to the old one, or show both ;) (actually if we could deploy them on -Pre NuGet branch it would be awesome) |
__Brand New F# API__. The entire F# API has been updated to give it a more native F# feel while still holding true to the Erlang / Scala conventions used in actor systems. [Read more about the F# API changes](akkadotnet#526). __Multi-Node TestKit (Alpha)__. Not available yet as a NuGet package, but the first pass at the Akka.Remote.TestKit is now available from source, which allow you to test your actor systems running on multiple machines or processes. A multi-node test looks like this public class InitialHeartbeatMultiNode1 : InitialHeartbeatSpec { } public class InitialHeartbeatMultiNode2 : InitialHeartbeatSpec { } public class InitialHeartbeatMultiNode3 : InitialHeartbeatSpec { } public abstract class InitialHeartbeatSpec : MultiNodeClusterSpec The MultiNodeTestRunner looks at this, works out that it needs to create 3 processes to run 3 nodes for the test. It executes NodeTestRunner in each process to do this passing parameters on the command line. [Read more about the multi-node testkit here](akkadotnet#497). __Breaking Change to the internal api: The `Next` property on `IAtomicCounter<T>` has been changed into the function `Next()`__ This was done as it had side effects, i.e. the value was increased when the getter was called. This makes it very hard to debug as the debugger kept calling the property and causing the value to be increased. __Akka.Serilog__ `SerilogLogMessageFormatter` has been moved to the namespace `Akka.Logger.Serilog` (it used to be in `Akka.Serilog.Event.Serilog`). Update your `using` statements from `using Akka.Serilog.Event.Serilog;` to `using Akka.Logger.Serilog;`. __Breaking Change to the internal api: Changed signatures in the abstract class `SupervisorStrategy`__. The following methods has new signatures: `HandleFailure`, `ProcessFailure`. If you've inherited from `SupervisorStrategy`, `OneForOneStrategy` or `AllForOneStrategy` and overriden the aforementioned methods you need to update their signatures. __TestProbe can be implicitly casted to ActorRef__. New feature. Tests requring the `ActorRef` of a `TestProbe` can now be simplified: ``` C# var probe = CreateTestProbe(); var sut = ActorOf<GreeterActor>(); sut.Tell("Akka", probe); // previously probe.Ref was required probe.ExpectMsg("Hi Akka!"); ``` __Bugfix for ConsistentHashableEvenlope__. When using `ConsistentHashableEvenlope` in conjunction with `ConsistentHashRouter`s, `ConsistentHashableEvenlope` now correctly extracts its inner message instead of sending the entire `ConsistentHashableEvenlope` directly to the intended routee. __Akka.Cluster group routers now work as expected__. New update of Akka.Cluster - group routers now work as expected on cluster deployments. Still working on pool routers. [Read more about Akka.Cluster routers here](akkadotnet#489).
@Horusiath should be live on NuGet now :) |
@Aaronontheweb That's great! Thank you all for help. |
New features
log (level : LogLevel) (mailbox : Actor<'a>) (msg: string) : unit
logDebug (mailbox : Actor<'a>) (msg: string) : unit
logInfo (mailbox : Actor<'a>) (msg: string) : unit
logWarning (mailbox : Actor<'a>) (msg: string) : unit
logError (mailbox : Actor<'a>) (msg: string) : unit
logException (mailbox : Actor<'a>) (e: exn) : unit
pipeTo (computation : Async<'t>) (recipient : ICanTell) (sender : ActorRef) : unit
(|!>) (computation : Async<'t>) (recipient : ICanTell)
- pipe to equivalent used for forward async computation result to right-side recipient with NoSender(<!|) (recipient : ICanTell) (computation : Async<'t>)
- pipe to equivalent used for forward async computation result to left-side recipient with NoSenderinbox (system : ActorSystem) : Inbox
- equivalent ofInbox.Create
receive (timeout : TimeSpan) (i : Inbox) : 'm option
- equivalent ofInbox.Receive
but statically typed. Returns option withNone
result on timeout exceeded or result of incompatible type returned.filterReceive (timeout : TimeSpan) (predicate : 'm -> bool) (i : Inbox) : 'm option
- equivalent ofInbox.ReceiveWhere
, again statically typed. Returns option withNone
result on timeout exceeded or result of incompatible type returned.asyncReceive (i : Inbox) : Async<'m option>
- equivalent ofInbox.ReceiveAsync
. Async computation should returnNone
result on result of incompatible type returned. This may not be a correct signature and return type may changeBreaking changes
spawns
function. Insteadspawnp
function was createdspawnp (system : ActorRefFactory) (name : string) (mapParams : PropsParams -> PropsParams) (f : Actor<'m> -> Cont<'m, 'v>) : ActorRef
. Map params is a mapping function used for specifying all additional parameters to be applied onto innerProps
object used for actor creation. This is more comprehensive implementation thanspawns
, which could be used only for defining a SupervisorStrategy.spawne
also takes additional(mapParams : PropsParams -> PropsParams)
parameter.select
function has reversed input parameters. See F# API open propositions #513 for motivation.Examples updated + one new example
All of the changes above have been applied to F# API examples. Additionally there is a new sample showing use of F# spawning function for Remote Deployment feature - unlike the C# one, this is share nothing example, which means that there are no libraries with shared code. Actor logic is serialized as F# expression, send over the wire and then compiled and executed onto remote actor system!