When we were designing how the managed objects will communicate while the objects are distributed among several nodes and thus can't access each other directly, there were several possibilities how to implement communication between the remote objects. We found both asynchronous and synchronous RPC useful and worth implementing but too complex for the lowest level of communication among objects.
We knew that we wanted something similar to asynchronous message sending. But the protocol based on asynchronous messages itself was not suitable for us as it would introduce two types of objects - managed objects and message objects. But it was just one step from the final solution which is implemented in the Massiv.
In the Massiv, managed objects and messages are the same. Managed objects can behave like messages and messages can behave like objects. What does that mean? Because each managed object is also a message, it can be sent to another objects. And because each message is also an object, it can have properties and methods which can be accessed and invoked.
The migration is the process when one or more messages (objects) are delivered (migrated) to another object. Here is the right point to make clear the difference between delivery and migration - there is no difference at all. When we are looking on some object as it is a message, the message is “delivered” to its recipient object. Actually, the object is migrated to the same node where the recipient resides and the object (message) is received by the recipient. You should have no problem understanding when “delivery” is interchanged with “migration” (and vice versa) without being explicitly stated.
The described model where objects and messages are the same, has some nice features.
Because messages are also managed objects, we don't need to take extra care of the messages. For example, the messages are automatically archived as any other object is.
Messages can contain any managed data.
Messages can expose some specific behavior because the the messages are totally under the control of the user of the Core. For example, some messages don't only need to be delivered to some object and then destroyed, but they can be delivered to the object and then they can return to the sender of the message (or they can be sent again to any other object). This feature is heavily used in implementation of synchronous RPC where the RPC messages are used to bring back results of the RPC invocation.
There doesn't need to be some global handler which will pass the message to its recipient once the message is delivered. The handler is part of the message object - when the message is delivered to its recipient, one of its methods is invoked with recipient as its argument. The method is virtual so each message can have its own handler which can do whatever is appropriate for the message. For example the recipient of the message doesn't need to notice at all that the message was delivered to him if the message's handler doesn't call any method of the recipient.