TIP 427: Introspection of Asynchronous Socket Connection

Login
Author:         Reinhard Max <[email protected]>
Author:         Harald Oehlmann <[email protected]>
Author:         Reinhard Max <[email protected]>
State:          Final
Type:           Project
Vote:           Done
Created:        16-Mar-2014
Post-History:   
Keywords:       async socket connect,introspection,IPV6
Tcl-Version:    8.6.4
Tcl-Branch:     tip-427

Abstract

This TIP describes a method to introspect the asynchronous connection process by an extension of the fconfigure interface in addition to fconfigure -error. This will enable better control over the asynchronous connection process, even in cases where the event loop is not in use.

Rationale

The socket core command supports two ways to establish a client socket, synchronous and asynchronous. In synchronous mode (which is the default) the command does not return until the connection attempt has completed (established or failed).

In asynchronous mode (-async option) the command returns after DNS lookup and the connection is established in the background. This is useful in situations where it is undesirable that a process or thread blocks for completing a synchronous connection attempt. Classically, an asyncronously connecting socket would indicate that it had connected (or failed to connect) by becoming writeable, which fileevent writable can be used to detect.

A DNS name may have multiple IP addresses associated, e.g. for IPv4/IPv6 dual stack hosts or for fail safety or load balancing reasons as it is the case for google.com as of this writing.

In Tcl 8.5 the socket command only tried to connect to a single IPv4 address that was randomly picked from the list returned by DNS. In Tcl 8.6, the socket command tries to connect to all the IP addresses of a DNS name in turn until one succeeds or all have failed.

This caused the following changes to the socket -async command from Tcl 8.5 to 8.6:

The usage of socket -async is seen as helpful even without the event loop. An example is an application, which checks a list of hosts for a connection. The application may start many background socket connects, do something else, and then collect the results. Without the event loop (i.e., a fileevent writable), there is no non-blocking way to discover if the asynchronous connect has completed.

In addition, the following future points may be considered:

Proposed Change

Current Introspection Change

The introspection functions should act as follows during an asynchronous connection process:

Introspection Command to Inspect a Running Asynchronous Connect

An additional introspection function should inform if the asynchronous connect is running or if it has terminated:

fconfigure channel -connecting

This option returns 1 as long as a socket is still in the process of connecting asynchronously and 0 when the asynchronous connection has completed (succeeded or failed) or the socket was opened synchronously.

Non-Event Loop Operation

If the event loop runs, the state machine of a (possibly multiple-address try) async connection proceeds within an internal callback.

In addition to that (for the case the event loop does currently not run), it proceeds whenever a channel operation is attempted on the socket_

Use Case of the Connecting Option

My own use case for the proposed option -connecting is as follows. A TCL script is started within Rivet to do two tasks:

I don't use the event loop to get a linear program with controlled order.

So the program flow is as follows:

I have cut the data base processing into two parts; I assume there are normally two IP's to try, one IPV6 and one IPV4.

Alternatives

Two alternatives for the behavior of fconfigure -sockname and fconfigure -peername are:

These are open to discussion.

Implementation

The fossil branch tip-427 contains an implementation of these extensions.

Copyright

This document has been placed in the public domain.