Scala, Actors, what happens to unread inbox messag

2019-06-19 08:26发布

问题:

What happens to unread inbox messages in Scala Actors? For example two cases:

1.If forget to implement react case for special message:

actor!NoReactCaseMessage

2. If messages comes too fast:

(timeOfProcessingMessage > timeOfMessageComes)

If first or second case happens, would it be stacked in memory?

EDIT 1 Is there any mechanism to see this type of memory leak is happening? Maybe, control number of unread messages then make some garbage collect or increase actor pool. How to get number of unread messages? How this sort of memory leaks solved in other languages? For example in Erlang?

回答1:

The mailbox is a queue - if nothing is pulling the messages from the queue (i.e. if the partial function in your react or receive loop returns false for isDefinedAt), then the messages just stay there.

Strictly speaking this is a memory leak (of your application), although the seriousness of it is dependent on how these unread messages grow in number (obviously). For example, I often use actors to merge in a replay query and a "live stream" of messages both identified by a sequence number. My reaction looks like this:

var lastSeq = 0L
loop {
  react {
    case Msg(seq, data) if seq > lastSeq => lastSeq = seq; process(data)
  }
}

This contains a memory leak, but not a "serious" one, as there will be an upper bound in the number of duplicate messages (i.e. there can be no more once the replay query is finished).

However, this may still be an annoyance, as for each reaction, the actor sub-system will scan those messages again to see whether they can be processed.

In fact, thinking about a real mailbox might be a good analogy here. Imagine you left all your junk mail in there: pretty soon, you'd be suffering starvation because of all the junk mail you would have to sift through in order to get to the credit card statement.



回答2:

How this sort of memory leaks solved in other languages? For example in Erlang?

Same as in Scala. First issue:

  1. If forget to implement react case for special message

You very rarely need to leave a message in the mailbox intentionally and receive it later. I haven't ever encountered such a situation. So you can always include a catch-all clause (case _ => ... in Scala), which will do nothing, log a warning, or throw an exception -- whatever makes most sense in your situation.

  1. If messages comes too fast

Instead of sending messages directly to a process which can't handle them fast enough, add a buffering process. It can throw away extra messages, send them to more than one worker process, etc.