next up previous contents
Next: Peeking at a message Up: Channel Previous: Sending a message   Contents

Receiving a message

Method receive() is used to receive messages, views, suspicions and blocks:

    public Object receive(long timeout) throws ChannelNotConnected, ChannelClosed, Timeout;

A channel receives messages asynchronously from the network and stores them in a queue. When receive() is called, the next available message from the top of that queue is removed and returned. When there are no messages on the queue, the method will block. If timeout is greater than 0, it will wait the specified number of milliseconds for a message to be received, and throw a TimeoutException exception if none was received during that time. If the timeout is 0 or negative, the method will wait indefinitely for the next available message.

Depending on the channel options (see 3.7.3), the following types of objects may be received:

Message
A regular message. To send a response to the sender, a new message can be created. Its destination address would be the received message's source address. Method Message.makeReply() is a helper method to create a response.

View
A view change, signalling that a member has joined, left or crashed. The application may or may not perform some action upon receiving a view change (e.g. updating a GUI object of the membership, or redistributing a load-balanced collaborative task to all members). Note that a longer action, or any action that blocks should be performed in a separate thread. A MergeView will be received when 2 or more subgroups merged into one (see 3.5.2 for details). Here, a possible state merge by the application needs to be done in a separate thread.

SuspectEvent
Notification of a member that is suspected. Method SuspectEvent.getMember() retrieves the address of the suspected member. Usually this message will be followed by a view change.

BlockEvent
The application has to stop sending messages until a new view has been received. It is used to synchronize messages between views, so that all messages are received in the view in which they are sent. When the application has stopped sending messages, it needs to acknowledge this message with a Channel.blockOk() method. Messages of this type are not usually enabled on a channel (see 3.7.3), therefore an application will not receive blocks at all. In case they are enabled, blockOk() has been invoked, and the application sends a message before having received the next view, the view in which the message will be delivered is not determined: it may be the next view, or any the message may even be discarded ! When blocks are not enabled, the view in which a message will be delivered, is not determined (but no message will be discarded !)

GetStateEvent
Received when the application's current state should be saved (for a later state transfer. A copy of the current state should be made (possibly wrapped in a synchronized statement and returned calling method Channel.returnState(). If state transfer events are not enabled on the channel (default), then this event will never be received. This message will only be received with the Virtual Synchrony suite of protocols (see the Programmer's Guide).

SetStateEvent
Received as response to a getState(s) method call. The argument contains the state of a single member (byte[]) or of all members (Vector). Since the state of a single member could also be a vector, the interpretation of the argument is left to the application.

The caller has to check the type of the object returned. This can be done using the instanceof operator, as follows:

    Object  obj;
    Message msg;
    View    v;
    obj=channel.receive(0); // wait forever
    if(obj instanceof Message)
        msg=(Message)obj;
    else if(obj instanceof View)
        v=(View)obj;
    else
       ; // don't handle suspicions or blocks

If for example views, suspicions and blocks are disabled, then the caller is guaranteed to only receive return values of type Message. In this case, the return value can be cast to a Message directly, without using the instanceof operator.

If the channel is not connected, or was closed, a corresponding exception will be thrown.

The example below shows how to retrieve the "Hello world" string from a message:

    Message msg; // received above
    String  s;
    try {
        s=(String)msg.getObject(); // error if object not Serializable
        // alternative: s=new String(msg.getBuffer());
    }
    catch(Exception ex) {
        // handle errors, e.g. casting error above)
    }

The Message.getObject() method retrieves the message's byte buffer, converts it into a (serializable) object and returns the object.


next up previous contents
Next: Peeking at a message Up: Channel Previous: Sending a message   Contents
Bela Ban 2002-11-16