These are chat archives for akkadotnet/akka.net

18th
Mar 2015
jcwrequests
@jcwrequests
Mar 18 2015 01:06
@Horusiath +1 on the Ricardo Presentation. For those of us how are trying to learn F# I think using Akka may be a good way to get comfortable with the language.
@Aaronontheweb @rogeralsing @nvivo I made the new extension method and adapter to make creating child actors using DI simple and explicit.
    public class DIActorAdapter
    {
        readonly DIExt producer;
        readonly IActorContext context;
        public DIActorAdapter(IActorContext context)
        {
            if (context == null) throw new ArgumentNullException("context");
            this.context = context;
           this.producer = context.System.GetExtension<DIExt>();
        }
       public ActorRef ActorOf<TActor>(string name = null) where TActor : ActorBase, new()
       {
            return context.ActorOf(producer.Props(typeof(TActor).Name), name);
       }
    }

    public static DIActorAdapter DI(this IActorContext context)
    {
        return new DIActorAdapter(context);
    }
Aaron Stannard
@Aaronontheweb
Mar 18 2015 02:08
@jcwrequests there's something up with your .SLN on that branch - check out the comments from the build bot
Emilian Ionascu
@emilianionascu
Mar 18 2015 09:07
hey all, sorry for the on and off posting
I didn't mean to criticise so please take all my feedback as a potential constructive one
so the static classes issue - it's ok to have one layer of statics for methods that take input parameters and produce some output that is then used elsewhere, but when the static layers are used one inside the other it might become harder to maintain and adapt the code
also it's unclear that the class that you're using has a dependency on another class - which is static as well which in turn might have another dependecy on another one
I'm more in favor of programming to interfaces and using dependency inversion and building things instead of statics
Emilian Ionascu
@emilianionascu
Mar 18 2015 09:12
there's 29 pages of results with Static and I believe that is caused by the potential adaptation of Objects from scala
the extension methods - it is my opinion that they have been added so that you can extend existing functionality to which you don't have access to directly in situations such as you're using a library and you want to add extra functionality to a type maybe
Emilian Ionascu
@emilianionascu
Mar 18 2015 09:18
however when one is building the library, one should not revert to extension methods and instead should use OOP practices together with SOLID principles to make the code extendable and maintanable
Roger Johansson
@rogeralsing
Mar 18 2015 09:20
Can you show one of the static uses that you find strange? most are for factory methods on things like Address.Parse , ActorRef.NoSender etc. and a few internal util methods for string parsing etc.
Emilian Ionascu
@emilianionascu
Mar 18 2015 09:20
nested classes definitions - did you notice how painful it is to write new Foo.BarMessageType() because intellisense and ReSharper will always autocomplete to new Foo() first?
Emilian Ionascu
@emilianionascu
Mar 18 2015 09:28
@rogeralsing - I'll navigate through the code and report them if I'll find any. My answer was mostly focused on :point_up: March 17 2015 4:54 PM
Natan Vivo
@nvivo
Mar 18 2015 09:41
@emilianionascu I'm usually a pretty picky guy and I wouldn't pick on those items. =) I don't think we can measure code quality by the number of pages in a search result. If you take a look at the .NET source code itself, there will be much more static and nested classes there. .NET has also a lot of "goto" statements in some places, even though people consider that "a bad practice". I think the kind of usage Akka does of these is consistent with this kind of project, which is too complex to do otherwise.
David Smith
@smalldave
Mar 18 2015 13:04
@rogeralsing did you ever get an answer to your SO question? do you really want Thread.VolatileRead / Thread.VolatileWrite?
See http://joeduffyblog.com/2010/12/04/sayonara-volatile/. I struggle with the volatile keyword. I find it very hard to read the authors intention.
I see volatile in the codebase quite a bit and it is difficult to see what issue it is addressing.
Roger Johansson
@rogeralsing
Mar 18 2015 13:07
Here is the thing we tried to solve, currently the custom thread pool me and @Aaronontheweb are making, has a concurrentqueue per worker, where the workers own tasks are stored.. the worker thread dequeue and producers add work to the queue.. but, this comes with a cost of contention since concurrentqueue can only dequeue one item at a time.. I would like to try a front/backbuffer approach.. worker operates on backbuffer, producers add to frontbuffer. .. once backbuffer is empty.. swap the two
but I could never get the producers to see the latest frontbuffer. those threads sometimes still saw the old buffer
not even sure if that is a good approach, but it felt like it :)
David Smith
@smalldave
Mar 18 2015 13:18
like the idea (likewise no idea if it's a good approach). this stuff is hard :) I'd suggest not using volatile and trying to address issues explicitly
but I probably just don't understand volatile ;)
Emilian Ionascu
@emilianionascu
Mar 18 2015 13:23
@nvivo given that my intention is not to criticise I shall pause the dialog and hopefully between my work and my baby I will get the time to contribute to the project and perhaps then my 2 cents will be more valuable
Natan Vivo
@nvivo
Mar 18 2015 13:29
@rogeralsing at risk of being silly, have you ever tried replacing concurrentqueue with a simple queue/linked list with a lock? Depending on the patterns for enqueue/dequeue a custom class with locks can be much faster than concurrentqueue is.
Natan Vivo
@nvivo
Mar 18 2015 13:37
Specifically, if you are already thinking about a back/front buffers, locking once and dequeueing multiple items to a temp buffer could speed things up for reading.
@emilianionascu relax, I'm new here as well. feel free to contribute =)
Emilian Ionascu
@emilianionascu
Mar 18 2015 13:41
would you be open to adding third party dependencies such as zero mq?
I've been using it in a desktop app and it works flawlessly
then I discovered ReactiveExtensions but that's another story
:)
Natan Vivo
@nvivo
Mar 18 2015 13:47
I have zero decision power here. =) And I think Akka already has a transport mechanism, called Helios. Not sure what you want to do..
@emilianionascu just FYI, the development is currently focused on porting the Scala Akka features to .NET, so unless there is something very important there depending on zeromq that wasn't ported already I don't think it would be considered for now
Roger Johansson
@rogeralsing
Mar 18 2015 13:57
JVM Akka does support (or at least did) for different MQ implementations, we have discussed adding support for e.g. NServiceBus, but there are a lot of other things with higher prio atm
Roger Johansson
@rogeralsing
Mar 18 2015 14:03
@emilianionascu is the purpose with 0mq plugin to enable durable messaging for remoting?
Natan Vivo
@nvivo
Mar 18 2015 14:11
Yeah, but ZeroMQ is not exacly equivalent to NServiceBus. It's more of a low level layer where you could implement Helios on top.
ZeroMQ is very low level
Roger Johansson
@rogeralsing
Mar 18 2015 14:36
But under what conditions would ZeroMQ "inproc" be useful within Akka.NET?
David Smith
@smalldave
Mar 18 2015 14:41
@rogeralsing apologies. you don't actually use volatile. Interlocked.Exchange is atomic read / write and fenced. no idea why that isn't working
Natan Vivo
@nvivo
Mar 18 2015 15:36
I don't think ZeroMQ in proc would have any use for Akka
Natan Vivo
@nvivo
Mar 18 2015 15:41
@rogeralsing, please be patient with me on my comment on #700. I feel like you want to punch me already =)
Roger Johansson
@rogeralsing
Mar 18 2015 17:24
Haha no worries
David Smith
@smalldave
Mar 18 2015 18:43
@rogeralsing I think you should try at least a memory barrier before the read of your exchanged variable in thread two and possibly after. if it works not sure why. volatile is using acquire and release fences rather than full fences so behaviour is different. if it works then you could at least start reasoning why :)
Roger Johansson
@rogeralsing
Mar 18 2015 18:44
Ive tried mem barriers too.... Interlocked.MemoryBarrier and Thread.MemoryBarrier... no luck :) I must be missing something else I guess
Aaron Stannard
@Aaronontheweb
Mar 18 2015 20:08
@smalldave @rogeralsing I tried using Interlocked.Exchange and didn't get good results either :\
Aaron Stannard
@Aaronontheweb
Mar 18 2015 20:28
Aaron Stannard
@Aaronontheweb
Mar 18 2015 20:44
@HCanber I'm going to modify your TaskBasedScheduler so it can be overriden with a different task factory for scheduling
and then subclass it with an implementation that does that
goal is to make it so actors who use a ForkJoinDispatcher have the option to schedule onto that dispatcher's threads
rather than the ThreadPool
going to be a configuration option
for that dispatcher type specifically
you can implicitly pass in a specific execution context for scheduling
if I created an overload (or equivalent) for doing this on the built-in scheduler
I.e. Context.System.Scheduler.TellRepeatedly(...., MyCustomTaskScheduler)
is that the best way of doing this?
it's not an issue that needs to be addressed immediately, but since I'm implementing this dispatcher stuff it's something I'm thinking about
David Smith
@smalldave
Mar 18 2015 21:13
@aaronontheweb finally looking at restartnodespec. Got issue where node tries to send message to test actor on other node. Endpoint immediately disassociates. Any clues on where to look next? Is there some logging I can enable?
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:18
@smalldave might have some ideas - does the endpoint throw any error before it disassociates?
or give any reason as to why?
David Smith
@smalldave
Mar 18 2015 21:23
@aaronontheweb nothing in the logs. Not tried debugging. Child process plugin just hangs visual studio for me so debugging a node is a pain
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:24
IMHO, we need some better documentation around configuration settings
it's hard even for me to remember how to do "LOG EVERYTHING"
David Smith
@smalldave
Mar 18 2015 21:29
@rogeralsing @aaronontheweb afaik exchange is fully fenced and barriers around read means no scope for cpu caching / instruction reordering issues. I'm no expert though. Maybe empty buffer check causing too many exchanges?
@aarontheweb do you remember? :) agree about documentation. I've looked before
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:31
no, not offhand
:\
the other pisser is that there are separate logging configs for remoting
I think I just go through and set STD-OUT and everything else to DEBUG
and hope that it works
you know what...
@smalldave akkadotnet/akka.net#744
not acceptable that this is so hard to figure out
lol
Natan Vivo
@nvivo
Mar 18 2015 21:36
Isn't compareexchange a single assembly instruction?
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:38
the bottom line was that the front / back buffer swapping ended up hurting performance more than helping it
the way we tried to implement it
we'd probably have to write our own data structure to do it correctly
Natan Vivo
@nvivo
Mar 18 2015 21:39
what about locking regular linked lists?
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:40
i.e. a ConcurrentQueue implementation that can atomically DequeueAll
Natan Vivo
@nvivo
Mar 18 2015 21:40
yep, that's what i use to do, usually is faster than concurrentqueue
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:40
@nvivo yeah, that could work I think
Natan Vivo
@nvivo
Mar 18 2015 21:40
it depends on how many inserts/dequeues you do
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:40
I was thinking a double-ended queue could do the trick too
Natan Vivo
@nvivo
Mar 18 2015 21:40
but lock + dequeueall is really fast in simple data structures
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:41
basically the idea was to have the executor process its work without locking
but still let the synchronized queue accept work
and when the executor drained its queue, do a swap
Natan Vivo
@nvivo
Mar 18 2015 21:41
right
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:41
let me link you to the project
Natan Vivo
@nvivo
Mar 18 2015 21:41
doesn't concurrent queue already do something like that keeping a local list per thread?
Bartosz Sypytkowski
@Horusiath
Mar 18 2015 21:42
@nvivo locking depends heavily on usage pattern, for me dequeue all seems to be not commonly used
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:42
if you can change the queuing structure and improve the benchmark, we'd happily accept it
@nvivo yeah but in this case the concurrentqueue is exclusive to one thread
except in cases where a thread dies
and another thread is created to resume work on it
Natan Vivo
@nvivo
Mar 18 2015 21:44
@Horusiath agree. I'm just saying because if swap was an option, you could just dequeue all to a temp buffer and process all messages before trying to dequeue again
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:45
@nvivo yeah, and that makes sense for this case
the key to the speed of the DedicatedThreadPool is reducing lock contention
so the fact that all tasks are queued directly to a worker's local queue is a big help
no global lock contention among shared threads
there are other optimizations that can be made too
in particular, for recursive scheduling calls - being able to write directly to the unsafe queue
I haven't thought through how to do that safely yet
Natan Vivo
@nvivo
Mar 18 2015 21:47
I'll take a look at the project
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:47
nice
we'd appreciate your input
Natan Vivo
@nvivo
Mar 18 2015 21:47
too many things happening at once here =)
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:48
I took care of all of the horrible NuGet and DevOps shit yesterday
with that project
so if you get the benchmark up, should be easy to distribute
only magic trick is to make sure you stick to keeping everything in that source file
since that's what gets distributed in the nuget package, not a binary
Natan Vivo
@nvivo
Mar 18 2015 21:48
question
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:49
shoot
Natan Vivo
@nvivo
Mar 18 2015 21:49
what type of usage are you trying to optimize for? equal # of reads and writes?
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:49
in the thread pool?
from the work queue you mean?
Natan Vivo
@nvivo
Mar 18 2015 21:49
yes
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:49
ah
... here's what I think we're trying to optimize for
queuing work is probably going to happen at a faster rate than actually performing the work
for all non-trivial work
we want to optimize for read speeds on the thread executing the work
to decrease the time interval between executing tasks
Natan Vivo
@nvivo
Mar 18 2015 21:51
hmm.. ok
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:51
I don't think we care if there's additional overhead involved in queuing the work (writes) as long as it's not significant
but making it so the executor can blast through a big segment of its work queue without contention is ideal
the analogy @rogeralsing used, which I like is the idea of a front queue and back queue in graphics programming
front queue's optimized for reads
back for writing
when the worker exhausts its front queue, there might be some penalty involved in swapping the content from the back queue into the front
but as long as that penalty is lower than the cost of locking on a single queue for both reads and writes, we come out ahead
does that make sense?
Natan Vivo
@nvivo
Mar 18 2015 21:54
yes
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:54
cool
we use FAKE on that project too
so if you run ./build.cmd all
it will automatically launch the benchmark
after running the normal MSBuild / NUnit stuff
Natan Vivo
@nvivo
Mar 18 2015 21:55
just downloaded.. let me try
Aaron Stannard
@Aaronontheweb
Mar 18 2015 21:55
:+1:
Natan Vivo
@nvivo
Mar 18 2015 21:58
ok. run the test
I'll take a look at the code, not sure if I can help, but I'll give it a shot
just to understand, what you are doing is replacing the LinkedList for something else that does the swap internally?
Aaron Stannard
@Aaronontheweb
Mar 18 2015 22:01
I use a LinkedList on top of the custom TaskScheduler I wrote
(based off of an MSFT example)
Aaron Stannard
@Aaronontheweb
Mar 18 2015 22:01
but the actual threadpool uses this:
 internal sealed class WorkerQueue
        {
            internal ConcurrentQueue<Action> WorkQueue = new ConcurrentQueue<Action>();
            internal readonly ManualResetEventSlim Event = new ManualResetEventSlim(false);

            public void AddWork(Action work)
            {
                WorkQueue.Enqueue(work);
                Event.Set();
            }
        }
(it's further down the page)
Natan Vivo
@nvivo
Mar 18 2015 22:02
hm, ok
Aaron Stannard
@Aaronontheweb
Mar 18 2015 22:03
the task scheduler is just so we can schedule on top of this thread pool
doesn't really do much
Max Gortman
@nayato
Mar 18 2015 22:03
btw, CLR moved to concurrent queue to improve GC
it's easier for GC to walk queue segments compared to linked list nodes
Natan Vivo
@nvivo
Mar 18 2015 22:17
so, the DedicatedThreadPool will accept work from multiple threads, but the worker is tied to a specific thread, correct?
Natan Vivo
@nvivo
Mar 18 2015 22:47
got the idea here...
Roman Golenok
@shersh
Mar 18 2015 23:20
Hey guys
How to use Database in Akka.NET ? Any samples? Do I need to create Actor for Db reading operations or I should perform action inside actor where it need?