Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • 08:35

    Aaronontheweb on dev

    Fix build script to be able to … (compare)

  • 08:35
    Aaronontheweb closed #3924
  • 08:28
    Aaronontheweb synchronize #3927
  • 08:28
    Aaronontheweb synchronize #3924
  • 08:28

    Aaronontheweb on dev

    added updated Windows Release p… Merge pull request #3869 from A… Fixed Akka.Remote.ResendUnfulfi… and 6 more (compare)

  • 08:28
    Aaronontheweb closed #3932
  • 08:22
    Aaronontheweb opened #3932
  • 08:16

    Aaronontheweb on 1.3.15

    (compare)

  • 08:14

    Aaronontheweb on master

    Fixed Akka.Remote.ResendUnfulfi… added v1.4.0-beta2 release note… added Akka.NET v1.3.15 release … and 2 more (compare)

  • 08:14
    Aaronontheweb closed #3931
  • 08:11
    Aaronontheweb synchronize #3931
  • 07:59
    Aaronontheweb commented #3905
  • 07:58
    Aaronontheweb edited #3931
  • 07:57
    Aaronontheweb commented #3889
  • 07:54
    Aaronontheweb synchronize #3931
  • 07:49
    Aaronontheweb opened #3931
  • 07:41
    Aaronontheweb closed #3930
  • 07:41
    Aaronontheweb commented #3930
  • 07:34
    Aaronontheweb opened #3930
  • 07:22
    Aaronontheweb synchronize #3924
Aaron Stannard
@Aaronontheweb
if you need to get some messages back as part of your cleanup process, use Ask and .Wait to block
either that or split the actor off into its own part of the hiearchy and have it deathwatch the parent
and have it begin its termination process once the parent dies
Claudio Bernasconi
@claudiobernasconi
Hi folks. Seems like I have a major problem understandig some fundamentals of Akka.net. I currently have the following Actor System:
BatchJobSystem.png

I use a Round-Robin-Pool-Router for my Worker Actors. The JobCoordinatorActor keeps track of how many "rows" have been processed by the workers. This works really well.

My problem is that I currently have to create the JobCoordiantorActors all on my own. This means that if I create 100 Jobs, 100 JobCoordinatorActors will be created and run simultaneously. What I really want is that I can start 100 jobs, but only 10 JobCoordinatorActors will run at the same time.

Therefore I tried to implement the JobCoordinatorActor as a Round-Robin-Pool-Router as well. The problem is, that I don't know how I can "block" the JobCoordinatorActor so that it keeps wainting until its workers finished, then finish the JobCoordinatorActor and take the next job from the queue.

Can you guide me to the right article / resource to solve my misunderstandig? Thank you very much.

Claudio Bernasconi
@claudiobernasconi
Ah maybe I got it. Do I have to use Actor behaviors so that I can tell a coordinator to be in "running" state which only accepts messages from its workers and after completing switch to "ready4work" state which allows to receive the next StartJobMessage?
Claudio Bernasconi
@claudiobernasconi
I now refactored my solution to make use of switchable behaviours within my Coordinator. My problem no is that I only get as many messages as instances of the Coordinator. My coordinator completes, changes its baviour to accept the next "StartJobMessage", but there won't be a new one. I am sure that I initally sent workload with 5 times the number of coordinators. How can it be that these messages disappear? Any help highly appreciated.
Bartosz Sypytkowski
@Horusiath
@claudiobernasconi When your actor is in running behavior, how do you handle StartJobMessage?
Claudio Bernasconi
@claudiobernasconi
@Horusiath when my actor is in running behavior I do not handle StartJobMessage. My code looks like this:

private void Running() {
Receive<WorkerCompletedMessage>( msg => HandleWorkerCompletedMessage(msg));
}

private void Ready(){
Receive<StartJobMessage>(msg => HandleStartJobMesage(msg));
}

so its either one message or the other. Is this the wrong approach?
I've somewhere read that it is possible to consume a message and put it back onto the stack or something like that. But i am not used to this concept. The way I think about it by now is that if I do not handle a specific message type in a specific behaviour that the message stays in the queue. Is this assumption wrong?
Bartosz Sypytkowski
@Horusiath
if message would stay in queue it would block all further messages. By default all unhandled messages are thrown to dead letters.
Claudio Bernasconi
@claudiobernasconi
Okay this explains the observed bahaviour. Can you guide me how I should implement it? Seems like I need to consume the message and put it back to (another) queue again?
Bartosz Sypytkowski
@Horusiath
there is a possiblity of using stashing, so that in case if you don't want to handle message yet, you can stash it aside, and at some point unstash all messages back to actor's mailbox
Claudio Bernasconi
@claudiobernasconi
Okay. I have a round robin router which has 10 JobCoordinatorActors. I assume that the round robin router tries to deliver the StartJobMessages to all of the 10 JobCoordinatorActors. So do I have to stash them for each JobCoordinatorActor?
Bartosz Sypytkowski
@Horusiath
it would be hard to do otherwise.
round robin router will evenly send message to all 10 actors. Each of them can stash a message when in receiving state, and then just unstash all of them when switching back to watingforjob state
Claudio Bernasconi
@claudiobernasconi
Okay seems reasonable. I will try this tomorrow (it's 7pm. here), but conceptually this seems to solve my issue. Thank you very much.
Bartosz Sypytkowski
@Horusiath
no problem ;)
Maxim
@dubrovkinmaxim
Hi guys. I have question about delivery strategy "at-least-once-delivery". As I understand after redeliver-interval all messages (which were not marked as delivered) will be delivered again. What's best practises to configure this behavior? Which redeliver-interval should I use in my cluster when I don't know how many messages will appear in input of this actor?
Maxim
@dubrovkinmaxim
For example: 10 000 messages are processed during 10-20 secs. I have redelivery-interval = 20 secs. What's will happen if in next iteration AtLeastOnceDeliveryReceiveActor receive 50 000 messages? As I undestend it will processed 10 000 messages(20 sec) after that 40 000 will redelivered again (40 000 + 40 000 =80 000 messages in mail box). Is it true? =)
Bartosz Sypytkowski
@Horusiath

@dubrovkinmaxim it won't happen at once, as you're requesting a deliveries one by one. But yes, in general redeliveries can stack up, up to a number specified at akka.persistence.at-least-once-delivery.max-unconfirmed-messages (it's 100 000 by default). When this threshold will be surpassed all calls for Deliver() method will automatically fail fast.

You can also get notified about something wrong happening here, as after several unconfirmed redelivery attempts (value specified at akka.persistence.at-least-once-delivery.warn-after-number-of-unconfirmed-attempts which is 5 by default) AtLeastOnceDeliveryActor will receive UnconfirmedWarning message with all messages that haven't been confirmed more than this number of times.

Claudio Bernasconi
@claudiobernasconi
@Horusiath Thank you very much for your help regarding stashing. I implemented it and it works great. My next question is, how can I make use of clustering? I mean technically I already implemented clustering, but now I want to scale adding a new node to the cluster. The problem is that if i send some work it gets round-robined to the existing 10 instances of the JobCoordinatorActor in Node1. If I add another Node to the system, it does not get any work, because it just starts its new set of JobCoordinatorActors which don't get any work assigned. What am I doing wrong here? How can I setup my system to make use of newly added nodes?
Bartosz Sypytkowski
@Horusiath
@claudiobernasconi you can get more info on cluster routers here. I'm not an expert on these, but AFAIK clustered router should know how to spawn routees on each node (ofc if it's configured as a pool router). You can read config to configure how many routees should be spawned on each node and how many of them could be spawned in total. From what I remember 2 things to remember here are:
  1. Router won't migrate existing routees when new node has been added. It can just spawn more of them. If you need automatic actor rebalancing Akka.Cluster.Sharding is what you need.
  2. Keep in mind that stashing will saturate router mailbox. What I mean here is if you have i.e. 20 messages in router mailbox, and it has 5 routees on a single node, where each one of these routees stashes all messages until some specific message will arrive, then those routees can empty router mailbox even thou they cannot process those messages right away. So if you put another node here, but no new messages arrived, routees spawned on that node won't get any remaining of those 20 messages, since they have been send by the router already to corresponding routees on the first node, where they got stashed.
Claudio Bernasconi
@claudiobernasconi
@Horusiath Thank you very much. You helped me again a lot. I will dive deep into this. One question regarding your 2nd point: Seems like my design is not ideal considering the bahaviour of the system you describe. Is there a possibility to design the system in a way that the messages are kept in the queue of the (Cluster)router so that they will be routed only if a JobCoordinatorActor is ready to process it? This way the system could scale if I add a new node to the cluster. In my understanding the system cannot scale if I'm using the stashing as I do it right now.
The reason why I (have to) stash is that I want to keep track of the progress of the child actors of the JobCoordinatorActor. So the JobCoordinatorActor basically receives two kind of messages. Those with the workload and those with the progress information of its child. As long as not all of the children have completed, it cannot work on a new workload. If you do not understand my case here I am willing to draw a diagram to express clearly what I am talking about. Just ask, please.
Bartosz Sypytkowski
@Horusiath
If you need to track a completion, maybe put it into a separate actor? I've created a simple sample on that back on SO - it's called aggregator pattern.
you basically create an actor and say it how much of the work is there to be done. then all of the workers will notify their completion not to JobCoordinatorActor but to Aggregator instead. Once everyone have completed their job, aggregator will notify someone about completion, partial completion or failure.
Horusiath @Horusiath afk
Claudio Bernasconi
@claudiobernasconi
Thanks I'll dig into this as well.
Claudio Bernasconi
@claudiobernasconi
Okay, instead of instantiating a pool-router in code, I make use of the creation in the config file. This way I should be able to use a clustered router, right? So I replace var jobCoordinatorRouter = actorSystem.ActorOf(actorSystem.DI().Props<JobCoordinatorActor>().WithRouter(new RoundRobinPool(5)), "JobCoordinator"); with the following snippet in the HOCON file:
deployment {
/JobCoordinator {
router = round-robin-pool
nr-of-instances = 20
cluster {
enabled = on
allow-local-routees = on
use-role = prototype
max-nr-of-instances-per-node = 5
}
}
}
How can I specify in the HOCON file which underlaying routee actor should be used? In the code line above I was selecting the JobCoordinatorActor as routee. In the HOCON file I am not specifing which routee to be used. Therefore my application does not process any work any more :-/.
Andrey Leskov
@andreyleskov
Hi all, is their any guide how to diagnose performance issues with akka.net ?
Classic performance monitors like DotTrace or Ants Profilers shows tons of threads and it is hard to understand anything
Bartosz Sypytkowski
@Horusiath
@claudiobernasconi Props.Create<JobCoordinatorActor>().WithRouter(FromConfig.Instance)
Maxim
@dubrovkinmaxim
@Horusiath Thank you!
Maxim
@dubrovkinmaxim
Sergey Prytkov
@Rattenkrieg
Hi guys, can I run only tests that are in specific project with provided FAKE script?
Bartosz Sypytkowski
@Horusiath
@Rattenkrieg you can alter FAKE script to contain specific path only - !! is used to create path filter and AFAIK it can be used with ++ or -- to include/exclude other filters
Sergey Prytkov
@Rattenkrieg
@Horusiath but there is no option to pass desired project(assembly) name as argument to that script?
Bartosz Sypytkowski
@Horusiath
I don't think so
Sergey Prytkov
@Rattenkrieg
ok, thanks
Bartosz Sypytkowski
@Horusiath
usually we make use of R# for running specific tests
Sergey Prytkov
@Rattenkrieg
there are some weird issues with my VS/R# - it can't locate any tests, so I felt lazy to investigate and tried to figure out another way to run tests
but seems there is no easier way than to fix VS/R#
Bartosz Sypytkowski
@Horusiath
R# sometimes has problems with detecting tests that are defined in abstract base classes but inherited higher in the inheritance hierarchy
Sergey Prytkov
@Rattenkrieg
Seems it's related with xunit