How to detect connection changes

The signal

TnyAccount *a = ...
g_signal_connect (a, "connection-status-changed",
	G_CALLBACK (on_constatus_changed), self);

Dealing with the signal

It's not uncommon to in case of TNY_CONNECTION_STATUS_CONNECTED_BROKEN TnyConnectionStatus to set the TnyAccount instance offline. This means that your application accepts the fact that either connecting failed or the connection is broken, and that it will set the account in offline state. Making it ready for offline operation. Although you probably want to explain that you did that, to your user.

The signal handler can't be thread safe, so there are no guarantees about the actual connection status (it might change while you are handling the situation). In fact, the Tinymail infrastructure can't guarantee that during your handler, nothing "wrong" with the connection will happen. It should, however, issue a new emission of the signal soon after the new situation. Even if this happens while you are handling the current situation.

static void
on_constatus_changed (TnyAccount *a, TnyConnectionStatus status, gpointer user_data)
{
	gchar *str = NULL;

	if (status == TNY_CONNECTION_STATUS_DISCONNECTED)
		str = "disconnected";
	if (status == TNY_CONNECTION_STATUS_CONNECTED)
		str = "connected";
	if (status == TNY_CONNECTION_STATUS_CONNECTED_BROKEN)
	{
		/* tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (a), FALSE, NULL); */
		str = "con broken";
	}
	if (status == TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)
		str = "discon broken";
	g_print ("CON EVENT FOR %s: %s\n",
		tny_account_get_name (a), str);
}

Getting the status at any other time

This method is not thread safe, so there are no guarantees about the actual connection status (it might change while you are working with the status variable).

TnyAccount *account = ...
TnyConnectionStatus status = tny_account_get_connection_status (account);

Meaning of the different statuses

  • TNY_CONNECTION_STATUS_DISCONNECTED : The account is disconnected and set in offline state. All operations will be offline
  • TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN : The account is set in offline state but something about it is wrong (rare situation)
  • TNY_CONNECTION_STATUS_CONNECTED_BROKEN : The account is in online state but somethign is wrong (common situation when dealing with connection problems)
  • TNY_CONNECTION_STATUS_CONNECTED : The account is in online state and connected. Although it's possible that a new state will happen, especially in case of a network problem. Tinymail, though, will assume a good connection opon its next operation and will try. If that fails, a new connection-status-changed signal will be emitted later.
  • TNY_CONNECTION_STATUS_RECONNECTING : The account is reconnecting (usually this is not a state that you should handle)
  • TNY_CONNECTION_STATUS_INIT : Nothing has happened yet (rare state, at application initialization for example)

Clarification for TNY_CONNECTION_STATUS_CONNECTED_BROKEN

There are two situations that cause your status to be set in broken but connected: A broken connection attempt and a broken connection that happened after a successful connection.

A broken connection attempt can mean different things depending on the service. Usually it means either:

  • Host lookup failed. Usually a timeout. The timeout for host lookups in Tinymail is set to 30 seconds.
  • Timed out (usually filtered by a firewall)
  • Port was not open

A broken connection means that either a read or a write call timed out. The timeout in Tinymail is set to 15 seconds although there are situations that require a shorter timeout. Usually on IMAP, but not always, it's reading the IDLE situation or writing the NOOP that causes the timeout to occur.

It's possible using the tny_camel_account_add_option API of TnyCamelAccount to influence the "delay" time for IDLE on IMAP (the idle_delay option). This is the delay that Tinymail uses between turning the IDLE off and requesting a new IDLE state. Tinymail allows you to specify this time because a lot IMAP servers wont do a lot during IDLE, other than hoping that you'll soon stop the IDLE state, so that they can at that point suddenly give everything.

Making that timeout shorter will also make detecting connectivity problems happen faster. Making it shorter, though, increases bandwidth consumption while IDLE too. The default for this is 20 seconds. Together with the actual read and write timeout, it can therefore take up to 45 seconds to detect a connection problem with the default Tinymail settings on IMAP.