6. Advanced functions

6.1. Sending to self

By default, an application doesn't send the messages to itself. Usually, there are more efficient and convenient ways to communicate withing a program. However, if you want to take benefit of the ease of ivy or to be as transparent as possible, you can set the Ivy object so that the pattern matching and message sending will be done for the sender too. This method exists since 1.2.4.

public void sendToSelf(boolean b);
public boolean isSendToSelf();

6.2. Newline within messages

As we have seen in Ivy.sendMsg(), you can not have newline characters within the string you send on the bus. If you still want to send messages with newline, you can encode and decode them at the emitter and receiver's side. With Ivy.protectNewLine(boolean b), you can set your Ivy object to ensure encoding and decoding of newlines characters. This is tested and working between java ivy applications, but not yet implemented in other ivy libraries. The newlines are replaced by ESC characters ( hex 0x1A ). As the encoding and decoding cost a little more CPU and is not yet standardized in the Ivy protocol, use it at your own risk. We should of course protect the other protocol special caracters.

6.3. Sending direct messages

Direct messages is an ivy feature allowing the exchange of information between two ivy clients. It overrides the subscription mechanism, making the exchange faster ( there is no regexp matching, etc ). However, this features breaks the software bus metaphor, and should be replaced with the relevant bounded regexps, at the cost of a small CPU overhead. The full direct message mechanism in java has been made available since the ivy-java-1.2.3, but i won't document it to make it harder to use.

6.4. Asynchronous Subscription to messages

For each and every remote agent on the bus, a thread is in charge of handling the encoding and decoding of the messages and of the execution of the callbacks. Thus, if a callback consumes much time, the rest of the communication is put on hold and the processing is serialized, eventually leading to a stacking in the socket buffer and to the blocking of the message sender. To alleviate this, we have set up since ivy-java 1.2.4 an asynchronous subscription, where each and every time a callback is performed, it is done in a newly created separate thread. As creating a thread is quite expensive, one should use this method for lengthy callbacks only. Furthermore, to avoid concurrent access to the callback data, the String[] argument passed on to the callbacks are cloned. This causes an extra overhead.

public int bindMsg(String regexp, IvyMessageListener callback,boolean async);
public int bindAsyncMsg(String regexp, IvyMessageListener callback);
If the async boolean parameter is set to true, a new thread will be created for each callback. The same unBindMsg() can be called to cancel a subscription.

6.5. Waiting for someone: waitForClient and waitForMsg

Very often, while developping an Ivy agent, you will be facing the need of the arrival of another agent on the bus to perform your task correctly. For instance, for your spiffy application to run, a gesture recognition engine will have to be on the bus, or another data sending application. The Ivy way to do this is to subscribe to the known agent's ready message (be sure to subscribe before starting the bus), or to implement an IvyApplicationListener and change of state in the connect() method. However, it is often useful to stop and wait, and it is awkward to wait for a variable change.

IvyClient waitForClient(String name, int timeout)
IvyClient waitForMsg(String regexp, int timeout) 
These two methods allow you to stop the flow of your main (or other) thread by waiting for the arrival of an agent, or for the arrival of a message. If the agent is already here, waitForClient will return immediately. If timeout is set to null, your thread can wait "forever", otherwise it will wait timeout milliseconds. With waitForMsg, be aware that your subscription can be propagated to the remote agents after that their message was sent, so that you'd wait for nothing. You had better be sure that the waitForMsg method is called early enough.

6.6. Subscribing to subscriptions

TODO