简体   繁体   中英

Should I keep a registry of child actors?

I recently started working on a system, and I am using Akka.NET. I am still learning how to think in the terms of the actor model, so I would be open to suggestions from the more experienced.

I try to ask a more general question first:

How to keep track of child actor state by a manager entity in order to make decisions on which child to interact with , if the decision must be based on a number of parameters and complex business rules distributed in multiple actor classes.

I'll try to simplify the problem I am facing: Let's say I have an Actor System, and there is an actor, called Backlog .

The Backlog is responsible for creating and supervising Jobs (also actors).

Jobs have a lifecycle, for the sake of simplicity they can be either Active or Completed . They are created Active, and turn Completed when receiving a specific message. Completion does not mean termination. That comes later, at some point (so no deathwatch). Jobs can be and eventually are associated with Resources . One Job might be associated with zero, one or many Resources .

Resources are actors not supervised by the Backlog . There is a limited number of Resources .

Only one active Job can be associated with a Resource at any time.

It is possible that a Resource is not associated with a Job . It is possible that a Resource is not aware of being associated with a Job .

Resources are sometimes detected by sensors. The Detector will need to know the Intention of the Resource . The Intention is part of the mutatable state of the Job .

A Resource does not have an Intention on it's own, only when being associated with the Job , but it needs to state an Intention when being asked, so it needs to ensure there is a Job associated. (As the detector detects Resources, and not Jobs.)

In my design the Resource needs to ask the Backlog for a Job , if it does not have one when being detected.

Now the Backlog may or may not have a Job for this resource. If it does not, it should create one (let's say it knows how to). In order to do that it needs to know which of its Jobs are active and if any of those is already associated with the Resource that was asking.

Still with me?

So how should I make Backlog find out, whether it has a Job for Resource R ? Should I broadcast a message to all the Job actors and ask them if they are active? And also if they are accidentally handling R ? How do I make sure all Jobs did actually process it and how much should I wait for them to do it (especially since 0 ms seems to be the only acceptable performance for such simple tasks).

Or should I keep dictionaries holding Job actor references by Resource identifiers? And also by (last known) states involved in this decision? And then how should I maintain these dictionaries? Looking for Domain events? Or introduce yet more messages for Jobs to tell Backlog about their state changes with at-least-once guarantees?

To be honest, I love the mindset and the benefits of using the actor model, but the sheer amount of code here required to implement functionality that would be like a single line of LINQ query in the traditional OO makes me worried about how willing the rest of the team will be to handle this code.

SUMMARIZING

I have an actor Backlog responsible for creating and supervising Jobs , other actors that represent a concept in the domain. On some occassions, it needs to select exactly one of these Jobs based on some criteria involving the mutable state of the child actors, or determine if there is no job currently available. (Having multiple suitable jobs indicates a problem and should be detected.)

Question: Do I have optioins other than broadcasting some message to all jobs, containing criteria and waiting for each of the jobs to apply this criteria to themselves respond with a positive or negative answer?

Even though you described a lot, some important details are missing, for example are the backlogs processed in FIFO? it is important for the solution.

  1. For example if they do, I would use some queue such as RabbitMQ which actors can pull tasks when they are ready, this way the backlog actor should not even care, it is just dispatching a job into the appropriate queue.
  2. If you don't care exactly about the order, you can use routers and send the request (command/message) to one of the |R| job actors, and use for example the smallest queue size routing strategy.

If I will answer to the primarily question, one way of doing this configure the manager to receive commands which updates the child status and update this internally, it is easy and will not require more than a Dictionary in the Manager actor since it is guarantee to be executing single command at a time.

The relation to LINQ does not seems to be clear to me at all for you have described unless something fundamentally missing in your question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM