Actor Model vs Denial of Service

November 17, 2008 at 03:39 AM | categories: python, oldblog | View Comments

Kamaelia implements something similar to, but not the same as the Actor Model. Since I'd not heard of the actor model for the majority of time whilst working on Kamaelia (kamaelia is more like occam, unix pipes, hardware, etc), I've been reading up on it. One thing that I've come across about it that suprises me is this:
Communications among actors occur asynchronously: that is, the sending actor does not wait until the message is received before proceeding with computation.
(this summary courtesy of the Wikipedia page on the Actor Model, but the literature supports this view as well)
The difference between Kamaelia and the Actor Model is in a few places, but possibly the most fundamental is this:
  • With the actor model (as I understand it)
    • You have a mailbox where you receive messages. ("recv from inbox")
    • communications defaults to unidirectional, though you can build bi-directional
    • When you send a message, you know the recipient and send it direct to the recipient. ("send to bob")
    • Message sending is asynchronous
    • ie sender knows receiver, receiver does not (necessarily) know sender
      • This potentially introduces coupling in ways that makes co-ordination languages harder to build
  • With Kamaelia's model:
    • You receive messages from multiple named inboxes (ala receiving data on stdin, or receiving signals)
    • communications defaults to unidirectional, though you can build bi-directional
    • You send messages to named outboxes (ala sending to stdout, stderr)
    • A higher level co-ordination language (effectively) joins the dots between outboxes to inboxes (generally)
    • Message sending defaults to asynchronous, but you can define a "pipewidth" or "max number of messages in transit" to allow synchrony, where needed (such as a producer that produces data faster than the consumer can consume it)
    • ie sender does NOT know receiver, receiver does not (necessarily) know sender
      • Much like a CPU doesn't know whether it's plugged into a motherboard or a testing harness for example.
      • This defaults to needing a co-ordination language - but this encourages greater reusability of components, through a dataflow model
    • I say "kamaelia's" model here, but this is pretty similar to hardware, unix pipes, etc.
Now the thing I can't tell by looking at literature is what the general case is for most actor systems in practice:
  • Do they do the literal, and solely asynchronous thing? (ie always return immediately without error when you send a message)
  • Or do they introduce the ability to add in synchrony where necessary? (block or return an exception when a maximum inbox size is reached)
The reason I ask is because if you don't have the ability to define pipewidths, maximum inbox sizes, maximum outbox sizes or something then you can easily cause a denial of service attack in that scenario by having producers overload consumers. Consider a frame grabber feeding a slow, experimental video codec. In that scenario, it becomes rather important to be able to have a form of blocking (or EAGAIN) behaviour available. Indeed, this is such a common issue, that it's why unix pipes & filehandles will buffer a small amount of data, but block if you send too much data (or exhibit EAGAIN behaviour :). Similarly this is what's behind the socket.listen(argument) call in a server - to allow a certain number of connections to queue up, before refusing connections...

So, the question I really have is this: if you use or implement an actor model system, do you have any ability in your implementation to be able to say "maximum number of pending incoming messages" ? If you don't, then it is remarkably easy to write code that can break an actor based system by mistake, with problems in dealing with that - making code more complex, and less reusable.

I'd really be interested in hearing both positives and negatives here...

blog comments powered by Disqus