These are chat archives for akkadotnet/akka.net

25th
Apr 2015
Stefan Sedich
@stefansedich
Apr 25 2015 07:25
ah right @rogeralsing after digging around more I realize our EventBus is the LookupEventBus, SubchannelEventBus etc all in one.
Roger Johansson
@rogeralsing
Apr 25 2015 07:26
yes, in Scala they have traits for all the different variations, so it cannot be ported straight off if I recall correctly
Stefan Sedich
@stefansedich
Apr 25 2015 07:27
yeah the traits are neat
need to dig into scala
we have some _foo privates and some with no underscore, what is the convention?
Roger Johansson
@rogeralsing
Apr 25 2015 07:29
we use underscore on privates now.. we didnt early on, so that code is probably from the early days
we pretty much use default R# settings now
Stefan Sedich
@stefansedich
Apr 25 2015 07:29
yeah cool, I had done some cleanup around the event bus area
Stefan Sedich
@stefansedich
Apr 25 2015 07:38
will get a PR over for it somtime soon
Roger Johansson
@rogeralsing
Apr 25 2015 08:00
cool :+1:
Nikita Tsukanov
@kekekeks
Apr 25 2015 09:12
Guys
I've figured out a way
How to await from UntypedActor safely
Roger Johansson
@rogeralsing
Apr 25 2015 09:13
you can do that by wrapping your code inside RunTask(async () =>
Nikita Tsukanov
@kekekeks
Apr 25 2015 09:13
Nope
No tasks
Roger Johansson
@rogeralsing
Apr 25 2015 09:13
404
Nikita Tsukanov
@kekekeks
Apr 25 2015 09:14
protected override async void OnReceive(object message)
{
    if (message is string)
    {
        await Task.Delay(100).ActorAwait();
        Console.WriteLine("Returned from Task.Delay, Message: {0}, Self: {1}, Sender: {2}", message, Self, Sender);
    }
    else
        Console.WriteLine("Unknown message: {0} - {1}", message.GetType(), message);

}
Roger Johansson
@rogeralsing
Apr 25 2015 09:16
that will break actor concurrency? code path will return at "await" and then continue with the next message.. so even if you pass the context around, your actor is now multithreaded.. unless I read it completely wrong
Nikita Tsukanov
@kekekeks
Apr 25 2015 09:16
You've read it completely wrong
)
See the code in ActorAwait
It wraps the task inside a custom Awaiter
Roger Johansson
@rogeralsing
Apr 25 2015 09:17
so what happens on "await" is that line blocking?
Nikita Tsukanov
@kekekeks
Apr 25 2015 09:17
That wraps continuation in
_task.ContinueWith(t =>
                {
                    _state.Self.Tell(new CompleteTask(_state, continuation), _state.Sender);
                }, TaskContinuationOptions.ExecuteSynchronously);
See?
Continuation is sent back to the actor's mailbox after task finishes
Roger Johansson
@rogeralsing
Apr 25 2015 09:18
ah ok, that is exactly what happens when running an async inside this.RunTask(async => async stuff inside the actor (there is a helper method for eactly this
Nikita Tsukanov
@kekekeks
Apr 25 2015 09:18
Nope, not exactly
Roger Johansson
@rogeralsing
Apr 25 2015 09:19
when doing that, all continuations are piped back using CompleteTask also
there are examples of that in the AsyncAwaitSpec
Nikita Tsukanov
@kekekeks
Apr 25 2015 09:20
It looks like that I've read ActorTaskScheduler completely wrong)
So that call to Task.Factory.StartNew doesn't create any new threads?
I thought it has some overhead
Roger Johansson
@rogeralsing
Apr 25 2015 09:23
some overhead as it schedules to the thread pool. but there are a lot of stuff to take into account, tasks that complete on IO completion ports, exceptions that are thrown inside other tasks etc.
and reentrancy vs non reentrancy
e.g. the code you pasted here is reentrant, as soon as the Receive hits the first await it will return and start processing new messages, as that is what happens in the async await state machine.
Nikita Tsukanov
@kekekeks
Apr 25 2015 09:25
Well, reentrancy can also be implemented via a custom awaiter
Exceptions will be rethrown by boilerplate code generated by compiler
Roger Johansson
@rogeralsing
Apr 25 2015 09:26
you have to replicate the same code that is in the actor task scheduler. to suspend/resume the mailbox
Nikita Tsukanov
@kekekeks
Apr 25 2015 09:26
yup
it was just a proof-of-concept
But that approach should have better performance
And it is also more prone to bugs, since people might forget to call ActorAwait
Roger Johansson
@rogeralsing
Apr 25 2015 09:28
the receive method is now async void. I dont think you can marshall the exception back to the caller if anything blows up this way
Nikita Tsukanov
@kekekeks
Apr 25 2015 09:28
Compiler will call GetResult
which will throw when I'll complete the implementation
This is how built-in task awaiter works
Roger Johansson
@rogeralsing
Apr 25 2015 09:29
async void runs on the current SynchronizationContext and never on current taskscheduler
throws exceptions that is
Nikita Tsukanov
@kekekeks
Apr 25 2015 09:29
Exceptions will be thrown inside message handler
actor's message handler, I mean
Roger Johansson
@rogeralsing
Apr 25 2015 09:31
hmm that might work when beeing reentrant as continuations are passed back, but when doing mailbox suspension and not beeing able to pipe back, I think it will break
Exceptions in IO completion port stuff will probably not work either
e.g. if any ReadFileAsync or similar blows up while reading on an IO thread
I'm not claiming to be right here, the async await stuff is a complete mine field. and things that looks like they will hold in every case might not :)
Exception's stack trace:
System.Exception: error
   at Sandbox.Program.MyActor.<SomeTaskThatThrowsException>d__3.MoveNext() in c:
\Users\keks\Projects\Sandbox\Sandbox\Program.cs:line 65
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Sandbox.Program.ActorAwaiter.GetResult() in c:\Users\keks\Projects\Sandbox
\Sandbox\Program.cs:line 103
   at Sandbox.Program.MyActor.<OnReceive>d__0.MoveNext() in c:\Users\keks\Projec
ts\Sandbox\Sandbox\Program.cs:line 49
                                         

Exceptions in IO completion port stuff will probably not work either

Why won't they work?
When exception is thrown, continuation passed to ConfigureAwait will be called on IO thread, then continuation passed to ActorAwaiter will be pushed to actor's mailbox via a system message (CompleteTask), then compiler-generated continuation will call GetResult and here the exception is rethrown.

Roger Johansson
@rogeralsing
Apr 25 2015 09:43
not if you are non-reentrant, then you can't pipe back to actor mailbox as that is suspended. unless I'm too confused atm
when beeing non-reentrant the entire flow needs to complete as a normal tpl flow and when the last part completes, or an exception occurs, the mailbox needs to be resumed and the exception needs to be thrown in the correct context. but maybe it will work, it was just a pain to get all the bits working together when we built the initial support
Nikita Tsukanov
@kekekeks
Apr 25 2015 09:47

then you can't pipe back to actor mailbox as that is suspended

I think that system messages can be piped back

I mean ActorTaskScheduler does exactly that
Pushing CompleteTask messages to suspended mailbox
Before first delay, message: 1
After suspended delay, message: 1
Before first delay, message: 2
After suspended delay, message: 2
After reentrant delay, message: 1
After reentrant delay, message: 2
 
Seems to work as expected
Roger Johansson
@rogeralsing
Apr 25 2015 10:05
ah nice, super cool :) there might actually be some nice benefits to doing things this way.. e.g. `await Task.WhenAll(StartTask1(),StartTask2()).ActorAwait(...) task 1 and task 2 can still execute in parallel while the await on the WhenAll is actor safe
Nikita Tsukanov
@kekekeks
Apr 25 2015 10:17
I'll make a PR today or tomorrow
Nikita Tsukanov
@kekekeks
Apr 25 2015 11:13
akkadotnet/akka.net#903
Natan Vivo
@nvivo
Apr 25 2015 11:18
I don't know... async void is really not recommented
the only reason you should ever write "async void" is to interop with event handlers in windows forms
async methods should always return a task, that's the rule
Nikita Tsukanov
@kekekeks
Apr 25 2015 11:25
That's the rule with default awaiters
Because continuation is executed on thread pool
And there is nobody to catch any exceptions
With a custom awaiter, however, it's perfectly fine
Natan Vivo
@nvivo
Apr 25 2015 11:26
I disagree
It's not that it doesn't work
Nikita Tsukanov
@kekekeks
Apr 25 2015 11:26
Akka is here to handle your exceptions
So it's fine
Natan Vivo
@nvivo
Apr 25 2015 11:27
It's the fact that the only reason "async void" is allowed is to allow you to write legacy code
Nikita Tsukanov
@kekekeks
Apr 25 2015 11:27
Nope
Natan Vivo
@nvivo
Apr 25 2015 11:27
it's not something supported or recommended. having this support in a new library is asking for trouble
Nikita Tsukanov
@kekekeks
Apr 25 2015 11:27
It's also very useful when you know that your code will never throw exceptions
async void is dangerous only because of continuation executed from "somewhere" and no exception handling guarantees
Natan Vivo
@nvivo
Apr 25 2015 11:40
again, this is not about wether it works or not. I think it's about if akka as a library written today would choose this path or just change itself to support the TPL correctly, something I have advocated before
If you were to have an async handler inside an untyped actor, I'd rather you could write async Task OnReceive(msg) than async void OnReceive. But that would require more changes that Akka is not prepared to make
Nikita Tsukanov
@kekekeks
Apr 25 2015 11:42
Yup, having dispatchers to do the work will be nice
Natan Vivo
@nvivo
Apr 25 2015 11:42
I've written a small wrapper around stashing that emulates this behavior: https://github.com/nvivo/akka-async-actors
Nikita Tsukanov
@kekekeks
Apr 25 2015 11:43
ActorTaskDispatcher is also a hack anyway
Natan Vivo
@nvivo
Apr 25 2015 11:45
I've said before: any attempt to emulate the async/await support will end up in many many hours trying to fix edge cases and ultimately fall back to just add correct support for it
Unfortunately, this goes against some other minor edge cases that Akka.net is not willing to let go
Nikita Tsukanov
@kekekeks
Apr 25 2015 11:47
https://github.com/nvivo/akka-async-actors/blob/master/Src/Akka.Contrib.AsyncActors/AsyncUntypedActor.cs
So you are messing up with the stash. It's really an emulation, I see
So the only correct solution is a total overhaul of dispatching logic
Natan Vivo
@nvivo
Apr 25 2015 12:10
Well, it depends on what you call "correct"
If correct means keeping most of the code as equal as possible to the JVM implementation, then no
If correct means allowing people to use .net as intended, then yes =)
Nikita Tsukanov
@kekekeks
Apr 25 2015 12:16
I think, I found a bug in AsyncTaskScheduler )))
Roger Johansson
@rogeralsing
Apr 25 2015 12:16
@nvivo your solution can be fixed to use the new mailbox suspension, to get rid of the stash
Nikita Tsukanov
@kekekeks
Apr 25 2015 12:16
See #904
Natan Vivo
@nvivo
Apr 25 2015 12:16
yes, I'm aware of that.
it's that we're discussing different things
Nikita Tsukanov
@kekekeks
Apr 25 2015 12:17
That's what you get when you use suspended mailbox instead of implementing required logic in dispatcher
Natan Vivo
@nvivo
Apr 25 2015 12:30
My guess is that @kekekeks wants the same thing I proposed when I started in Akka. What is missing is that I started to understand why that specific feature was not implemented yet.
That doesn't mean I think it's not needed. It's just that I'm more aware of the constraints and the size of the change.
Natan Vivo
@nvivo
Apr 25 2015 15:00
@rogeralsing what is bothering you about the TPL?
Roger Johansson
@rogeralsing
Apr 25 2015 15:01
that I just dont get when it does what. why does asp.net use a synchronization context at all to start with?
Natan Vivo
@nvivo
Apr 25 2015 15:01
in asp.net, sync context is used to bring back the HttpContext.Current after await
Roger Johansson
@rogeralsing
Apr 25 2015 15:01
ah doh, i knew that :) just getting senile :)
Natan Vivo
@nvivo
Apr 25 2015 15:02
haha np I completely get you
I tried to run that solution, it seems to work when the actorOf starts the actor in the asp.net context, but doesn't when I start the actor outside and run with actorselection
does akka use the SyncrhonizedDispatcher automatically from asp.net?
Roger Johansson
@rogeralsing
Apr 25 2015 15:03
nope
Natan Vivo
@nvivo
Apr 25 2015 15:03
strange
Roger Johansson
@rogeralsing
Apr 25 2015 15:04
that is what I mean, TPL seems like a guess work at best, no matter how much time one spend on analyzing, there will be special cases anyway :-/
Natan Vivo
@nvivo
Apr 25 2015 15:05
I don't see it like that
can you give an example of that?
Roger Johansson
@rogeralsing
Apr 25 2015 15:06
4 lines up ^ :)
Natan Vivo
@nvivo
Apr 25 2015 15:06
ahaha ops
But I think some of that is due to how akka uses tasks, not the tpl itself
There are some things I cannot explain exactly, but there are some smells in akka code
this mixing TPL with dispatchers probably
the thing is that i completely get now why this was done this way
and I agree this shouldn't change like this
brb
Roger Johansson
@rogeralsing
Apr 25 2015 15:10
we should probably set up some sort of discussion somewhere (not on github issues) and dissect the async await stuff, try to find exactly what we need to support and what should be considered OT or out of scope
Natan Vivo
@nvivo
Apr 25 2015 15:11
I'd like to help on that. But I don't want to fight about it =)
There are things that are hard to explain in an issue. People assume too much about my temperament :-p
What I do believe however is that these places that require ".Result" are edge cases that should disappear in no time. Akka should prepare more for the future where this is not needed than where it is
Roger Johansson
@rogeralsing
Apr 25 2015 15:16
the thing is that if we have a long discussion on the github issuetracker, it steals focus from other things, i think it might be easier to just do a skype meeting or something about it
in what cases do people have to use sync code? I mean MVC and Web API supports async actions
webforms and legacy code comes to mind, but in a greenfield project, are there any places one still need to go async?
go sync*
Nikita Tsukanov
@kekekeks
Apr 25 2015 15:19

that I just dont get when it does what

https://www.microsoft.com/en-us/download/details.aspx?id=19957 explains a lot

Roger Johansson
@rogeralsing
Apr 25 2015 15:22
thanks! never seen that one before, awesome
Nikita Tsukanov
@kekekeks
Apr 25 2015 15:22

in what cases do people have to use sync code? I mean MVC and Web API supports async actions

Constructors are still synchronious, for example

thanks! never seen that one before, awesome

Actually, I've posted it in comments to #886 3 days ago

Nobody reads the comments >_<
Natan Vivo
@nvivo
Apr 25 2015 15:27
@Horusiath case specifically was about calling Akka from an MVC authentication method that was syncrhonous.
But my guess is that this is being fixed in the new MVC 6 that is about to come out
Arjen Smits
@Danthar
Apr 25 2015 16:36
What I do believe however is that these places that require ".Result" are edge cases that should disappear in no time.
@nvivo I disagree
People using .Result. Granted, thats wrong. But only because .Result is dangerous. In the sense that it can cause deadlocks.
However what they are trying to do is using an async thing in an synchronous way.
And those cases will always be there. There will always be people who get a Task back and want to wait on that task to complete, without doing that in an async way. And that has nothing to do with legacy libraries or stuff.
Arjen Smits
@Danthar
Apr 25 2015 16:44
I always hated how the TPL acts like a virus in your code. Its almost like java's unchecked exceptions. Once you start with it, you have to use it everywhere :P But thats beside the point.
the point is, that .Result is not the only way to turn async code into a synchronous flow. you could use await (which does stuff with the current context and continuations) or just wrap it in Task.Run().
But its a thorny problem all around
Arjen Smits
@Danthar
Apr 25 2015 16:55
Its annoying too. Every time I think I reasoned it out. I create an example app. And see , that which i though was the answer, blown up in my face :P
I learned more about the TPL then I ever hoped i would need.
all the while thinking: I must be doing something wrong, it cant be this hard right?
Natan Vivo
@nvivo
Apr 25 2015 17:09
@Danthar what I said is that the requirement to use Result should disappear, not that people would stop using it. =)
The discussion was that people had to use that with Akka because there was no other way to do it
I used to think of async/await as a virus too... I hated changing my code to obey some constraint I didn't have before
But at some point I started seeing some benefits, understood what it did and now I just don't care about that anymore. It's hard for me nowadays to create any api that doesn't return a task
With async coming to javascript, I guess this will become so mainstream that people won't notice it's there
Natan Vivo
@nvivo
Apr 25 2015 17:14
Now, there is a huge difference between understanding async/await and implementing all the requirements to use tasks transparently with all these contexts and etc
Arjen Smits
@Danthar
Apr 25 2015 18:19
The discussion was that people had to use that with Akka because there was no other way to do it
oh I totally missed that. Sorry :P
That makes sense, I just misunderstood then.
Aaron Stannard
@Aaronontheweb
Apr 25 2015 18:58
oh hey, another epic async / await thread
been a solid week since we had one of those
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:24
You'll get an increasing bunch of people whining about it
Aaron Stannard
@Aaronontheweb
Apr 25 2015 19:25
I'm actually ok with that
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:25
Until Akka.Net finally will be TPL-friendly
Aaron Stannard
@Aaronontheweb
Apr 25 2015 19:25
I think people should learn how to use the TPL itself and use PipeTo
and be comfortable making explicit choices about how they use the results of their tasks
async / await makes it way harder to reason about your code, and the actors are already asynchronous
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:26
just not friendly to C# built-in async primitives )
Aaron Stannard
@Aaronontheweb
Apr 25 2015 19:27
it's about as primitive as using is
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:28
At some point every library in .NET ecosystem will expose Tasks
Aaron Stannard
@Aaronontheweb
Apr 25 2015 19:28
yep, and you can use them
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:28
With overhead of scheduling task-friendly code on a separate thread
Aaron Stannard
@Aaronontheweb
Apr 25 2015 19:29
that's overhead that you're going to get anyway - await isn't "turbo mode engage"
async and await simplifies a few things, like error handling in a continuation chain
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:30
if Task was returned from Task.FromResult, you are doing a lot of completely unnecessary stuff
Roger Johansson
@rogeralsing
Apr 25 2015 19:30
:fast_forward: wrooooom
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:31
And ReceiveActors async overload is buggy
akkadotnet/akka.net#904
Aaron Stannard
@Aaronontheweb
Apr 25 2015 19:32
I'm going to refer you to this: http://www.aaronstannard.com/how-to-start-contributing-to-oss/ - read the "assume there's good reason for previous designs" part
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:32
Compatibility with JVM implementation is a good reason, yes
Aaron Stannard
@Aaronontheweb
Apr 25 2015 19:32
yes it is
and so's being able to benefit from the four years of heavy production use bugs they've found in real-life
having to adapt that code to the CLR is challenging and an imperfect science
and one of the facts of life is that the async and await model we're used to in procedural OO programming in .NET stands in direct contrast to what the actor model tries to provide
so rather than pigeonhole on why this square peg doesn't fit in this round hole
drop the "this shouldn't be this way" and "this is wrong" instant reactions and just give the actor model a try using what's already built into Akka.NET
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:37
BTW, where can I find some instructions about how to "run the test suite with the debugger attached"?
Aaron Stannard
@Aaronontheweb
Apr 25 2015 19:38
we don't have some irrational hatred towards the async / await keywords - but man, they really make it a lot harder to write clean actor code that complies with the basic concurrency restriction imposed by Akka actors
and I'd rather be telling people to learn how to use TPL composition than using synchronization mechanisms for their actor's state
@kekekeks do you have ReSharper by any chance?
if you download the XUnit test runner plugin forit
and run just the Akka.Tests assembly
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:39
Oh, get it
Aaron Stannard
@Aaronontheweb
Apr 25 2015 19:39
you should see where the it hangs
and then you can attach the debugger
I found a couple of issues in the Akka.Cluster.Tests library the other day
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:40
blob
Aaron Stannard
@Aaronontheweb
Apr 25 2015 19:40
yessir
that's correct
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:41
It seems that VS is catching exceptions that are handled in tests
Aaron Stannard
@Aaronontheweb
Apr 25 2015 19:42
I'd recommend running the suite first without debugging
and see where it hangs
just so you can narrow it down to a specific fixture
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:43
roger that!
Aaron Stannard
@Aaronontheweb
Apr 25 2015 19:43
90% chance it's a test with IDisposable
XUnit and the TestKit both try to dispose it and end up racing eachother
but there's a way of making that not happen that I can show you
err, it's a test CLASS with IDisposable
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:48
Tail_chopping_router_must_throw_exception_if_no_result_will_arrive_within_the_given_time
Xunit.Sdk.TrueExceptionFailed: Timeout 00:00:00.7000000 while waiting for a message of type Akka.Actor.Status+Failure
It's the only failing test in Akka.Tests
And it's reproducable
i. e. if I lauch this test it still fails
Nikita Tsukanov
@kekekeks
Apr 25 2015 19:57
Hm, it's not a false positive
Ok, now it throws "somewhere" in external code
Roger Johansson
@rogeralsing
Apr 25 2015 20:02
love the "system.core threw an exception" well yeah, thanks for that xUnit:)
Nikita Tsukanov
@kekekeks
Apr 25 2015 20:04
Fixed
I forgot about IsCancelled status
And someone expected that OperationCancelledException not to be wrapped inside AggregateException
Aaron Stannard
@Aaronontheweb
Apr 25 2015 20:54
8A65czr - Imgur.gif
that was for you @kekekeks
Nikita Tsukanov
@kekekeks
Apr 25 2015 20:59
You forgot the glowing hair part )
Natan Vivo
@nvivo
Apr 25 2015 22:05
W
Wow! Who let the dogs out?
Chanan Braunstein
@chanan
Apr 25 2015 22:06
Hi, I was looking at the potential SqlServer Persistence plugin that Bartosz mentioned to me in a thread in the google group. I was wondering if anyone knows why it is implemented using the SyncWriteJournal instead of the AsyncWriteJournal (or proxy)?
Natan Vivo
@nvivo
Apr 25 2015 22:06
Epic async vs akka: FIGHT!
Roger Johansson
@rogeralsing
Apr 25 2015 22:58
cc @Horusiath