frnsys / djinn

Urban simulation and market dynamics toolkit with connectors to popular machine learning tools

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Actor architecture

frnsys opened this issue · comments

This is a bit more info on what I was thinking for the low-level architecture and what I've started implementing, which is a basic actor system.

Actors are the core unit. They:

  • are constructed to respond to particular Messages (enums in Rust)
  • have Inboxes (FIFO) in which Messages are queued
  • may be distributed across processes/nodes (eventually Routers need to be implemented, which handle communication locally, via a Unix socket, or over a TCP socket)
  • Routers handle, at the higher-level, the delivery of messages to an Actor's Inbox
  • managed in pools by a Dispatcher, which check which Actors have Messages and assign them a thread to process those Messages

A few notes:

  • this isn't concerned with how Actors are distributed across a cluster (that'll be worked out at a higher-level by a Distributor)
  • at a higher-level there'd also be a special Manager actor (one per process) which manages a local population of Actors, i.e. so that a central node can tell them when to step the stimulation.
  • there is not (necessarily) a 1-to-1 mapping of Actors<->Agents. An Actor could represent a single agent, or it could represent a component of an Agent that is independent from its other components
  • this also isn't concerned with the nasty parts of distributed computing (node failures, network lag/timeouts, etc), I'm not very familiar with how to approach those

Questions:

  • should there be two classes of Messages? I.e. a "fire-and-forget" class which does not expect or care about a response from the recipient, and an "call-and-response" class which does expect a response from the recipient. If so, should the latter open up a direct socket between Actors or something else?

What you're describing sounds like the difference between UDP and TCP. If you were going the "fire and forget" route, then in the corresponding Router it should automatically default to UDP if not local (i.e. if set up for network).

This is also similar to how you configure queues, e.g. acks in RabbitMQ. No acks is essentially fire-and-forget.

My vote goes for yes, two classes of Messages.

ok great - we still want the Message to make it there for sure, so I think we still want to use TCP as the underlying method. I suppose I meant "fire-and-forget" at a higher level than the actual socket communication.

ended up going with a different architecture, so closing this