Sets the device’s disconnection handling policy and its reconnection timeout period
The disconnection handling policy SUSPEND_ON_ERROR, RETURN_ON_ERROR or RETURN_ON_ERROR_NO_DISCONNECT
The successful transmission criterion WAIT_TIL_SENT or WAIT_FOR_ACK
Maximum time (in seconds) allowed for the server to acknowledge receipt of data
The server.setsendtimeoutpolicy() method sets the timeout and reconnection policy for the imp’s connection to the server. The default setting — and the only mode of operation available in early impOS™ releases — corresponds to:
server.setsendtimeoutpolicy(SUSPEND_ON_ERROR, WAIT_TIL_SENT, 30);
It is important to understand the effects of setting the server.setsendtimeoutpolicy() parameters, which have a major impact on how the imp operates as a networked device.
This parameter allows you specify how the imp reacts when it unexpectedly disconnects from the server, or when it encounters an error during a call to the server:
SUSPEND_ON_ERROR The imp will stop executing code, attempt to reconnect to the server for one minute. If it fails to do so, it will go into a deep sleep. Every nine minutes the imp will wake up and try to connect for one minute, and then go back to sleep if it can’t establish a connection. This is the default behavior.
RETURN_ON_ERROR The imp will continue executing code. It will return a Send Error Code to Squirrel. The callback function registered using server.onunexpecteddisconnect(), if any, will be called. If RETURN_ON_ERROR is in effect, the only way for your imp to reconnect is to explicitly call server.connect(), so a common pattern is to make that call in the server.onunexpecteddisconnect() callback.
RETURN_ON_ERROR_NO_DISCONNECT Available from impOS 38 The imp will continue executing code. If all of the data waiting to be sent will not fit entirely into the send buffer (which may already contain data to send), the error SEND_ERROR_WOULDBLOCK is returned. The device does not disconnect. This policy ensures you are informed and can take appropriate action when the amount of data you are adding would cause Squirrel to block: an occurrence which takes place when impOS has to wait for the buffer to drain before it can add any remaining data from the send command. It also allows you to trap circumstances where the volume of data to be sent might such that the time taken to send it exceeds the timeout setting, causing the imp to return a send error code of SEND_ERROR_TIMEOUT and disconnect (under RETURN_ON_ERROR).
By checking the return value (from whichever imp API data send methods you are using) for the RETURN_ON_ERROR_NO_DISCONNECT send error code SEND_ERROR_WOULDBLOCK, you can choose how to proceed: perhaps try again later when the buffer is clear. You should note that RETURN_ON_ERROR_NO_DISCONNECT sets an upper limit on the size of data that can be sent from the device: the send buffer size less SSL overhead.
By requesting either RETURN_ON_ERROR or RETURN_ON_ERROR_NO_DISCONNECT, you are requesting explicit control over the processes of connecting and disconnecting the imp to or from the server. You should familiarize yourself with the network state diagram before selecting this policy. In SUSPEND_ON_ERROR mode, the imp implicitly takes care of maintaining the connection.
If you plan to use either RETURN_ON_ERROR or RETURN_ON_ERROR_NO_DISCONNECT, we recommend placing it in the first line in your code to be executed. This is to ensure that a class instantiation or other side-effect does not cause server traffic to be executed with the default SUSPEND_ON_ERROR policy. Remember, SUSPEND_ON_ERROR is in force as soon as your code begins running and until Squirrel processes a server.setsendtimeoutpolicy() statement setting the policy to RETURN_ON_ERROR or RETURN_ON_ERROR_NO_DISCONNECT.
This parameter allows you to configure what is considered a ‘successful transmission’.
WAIT_TIL_SENT The imp will consider that it has achieved a successful transmission as soon as the data has entered its send buffer. In most cases, this results in calls to the server appearing to be asynchronous, because the imp will continue executing code as soon as the message is buffered. This is the default behavior.
WAIT_FOR_ACK The imp will wait until the message has been sent to the server and the server has acknowledged the receipt of the data. This will result in calls to the server appearing synchronous, because the imp will stop executing code until the message has been sent and an acknowledgement received. WAIT_FOR_ACK guarantees that the data has reached the server, but can result in more sluggish device code. Consequently, we recommend only using WAIT_FOR_ACK in applications where confirmation of data receipt is absolutely essential.
The timeout parameter governs how long impOS allows for the action specified by the waitPolicy parameter to complete, ie. for the server to respond synchronously or asynchronously. In either case, if the timeout period was exceeded, the method responsible for sending the data, eg. agent.send(), will return the Send Error Code SEND_ERROR_TIMEOUT and the device will stop waiting for a successful transmission indicator. The device will also consider itself to be disconnected.
One consequence of this is that if you set a timeout of zero and then send lots of short messages — for example, 20 server log entries in a row — then the imp’s buffers will fill and it will disconnect. To avoid this, always provide a finite (but small) timeout to give the system time to process the TCP ACKs — or, from impOS 38, make use of the RETURN_ON_ERROR_NO_DISCONNECT policy (see above) and check the imp API’s data-send methods’ return values.
The following example demonstrates performance differences between WAIT_TIL_SENT and WAIT_FOR_ACK. Both code snippets are identical except for the argument passed into the waitPolicy parameter in server.setsendtimeoutpolicy(). Since we are sending large amounts of data, WAIT_FOR_ACK appears more sluggish, as the server.log() call blocks until the message has been sent and an acknowledgement has been received. The code assumes a standard LED has been connected to an imp001 or imp002’s pin 1. The rate at which the LED flashes is governed by the server.setsendtimeoutpolicy() waitPolicy argument chosen.
The following example demonstrates how you can use RETURN_ON_ERROR with a server.onexpecteddisconnect() callback to cycle through a list of known connections and attempt to connect to each one of them until you find one that works. The code assumes a standard LED has been connected to an imp001 or imp002’s pin 1.