Version 18 of socket -async

Updated 2014-04-04 11:59:57 by oehhar

Purpose

This page is dedicated to the asyncroneous socket connect, started by 'socket -async'. See the socket page for a general description.

It also serves as communication page for development and compares current TCL 8.5.15, TCL 8.6.1 and future versions.

Async connect got more complicated in TCL 8.6, as multiple destination IPs are internally supported (due to IPV6 or DNS lookup resulting in multiple IPs).

Command behaviour

socket -async

'socket -async' host first does a syncroneous DNS lookup.

Then the connect is started as background process.

  • In TCL8.5, this terminates without any interaction by background processes.
  • In TCL8.6, the event loop or command invocation is required to check multiple IPs.
VersionStatus
8.5.15ok
8.5.16+ok
8.6.1 unixok, requires event loop
8.6.1 winonly first IP (broken)
8.6.2+ok, requires event loop
ideasmay be moved in own thread to not require event loop and not to pause between connect tries

update,vwait

Starting the event loop allows in TCL8.6 to continue with the next try or to fail finally

fileevent writable

Fires when async connect terminates with success or error.

VersionStatus
8.5.15ok, see bugs
8.5.16+ok
8.6.1 winonly first IP (broken)
8.6.1 unixok
8.6.2+ok

fileevent readable

Fires when async connect terminates with error.

VersionStatus
8.5.15 unixok
8.5.15 winonly works when also writable event installed, see bugs
8.5.16+ok
8.6.1 winonly first IP and only with writable event (broken)
8.6.1 unixok
8.6.2+ok

blocking gets,read,puts

The async connect is terminated syncroneously.

On success, the operation is performed.

On connect failure, the connect error is returned by the command. (still to discuss)

VersionStatus
8.5.15ok
8.5.16+ok
8.6.1 winonly first IP (broken)
8.6.1 unixok
8.6.2+ok

non blocking gets,read,puts

The async connect state is checked or continued (next IP) in a non-blocking way.

Possible results:

NumberConditionAction
NB1async connect still in progresswrite operation is buffered and sheduled for background flush.
Read operation returns empty string
NB2async connect succeededoperation is directly executed
NB3async connect failedconnect error or other error is returned

Implementation status:

VersionStatus
8.5.15 unix?
8.5.15 winNB3 buggy: operation is buffered, no error
8.5.16+ unix?
8.5.16+ winBug not attacked jet
8.6.1 winNB3 buggy: operation is buffered, no error
8.6.1 unix?
8.6.2+ winOk (see TIP)
8.6.2+ unix?

close

A close while connection is in progress or after a succesful connection should succeed.

A close after a failed connection should return the connect error if not jet reported.

VersionStatus
8.5.15ok. Small bug: returned error message might be the one of a pending flush.
8.5.16+ok Small bug still present, which is acceptable
8.6.1ok
8.6.2+ok

fconfigure

Any fconfigure command on the socket continues the connect process.

VersionStatus
8.6.1 winno
8.6.1 unixno
8.6.2+ok

fconfigure -error

A final connect error should be returned by 'fconfigure -error'. No error should be flagged while connection is running.

Implementation status:

VersionStatus
8.5.15ok
8.5.16+ok
8.6.1 winresult of first tested IP (broken)
8.6.1 unixThe errors of all tested IPs show temporarely up
8.6.2+ok

fconfigure -sockname

My own IP of the socket connection. Returns list of IP, Name, Port.

Since IPV6, this value may change within connect tries from "127.0.0.1" to "::1". Also the port may change.

Implementation status:

VersionStatus
8.5.15 winreturns "0.0.0.0 0.0.0.0 51063"
8.5.16+?
8.6.1 winreturns ":: :: 51070" if first try is IPV6, otherwise an IP V4 address
8.6.1 unix?
8.6.2+?

Idea: The connection process should not be reflected. A compatibility value or an error should returned while connecting.

If we reflect the connection process, we would have issues later, if we would push the connect process to an own thread.

fconfigure -peername

The destination IP. Returns list of IP, Name, Port.

Since IPV6, this value may change within connect tries. Also the port may change (if auto).

Implementation status:

VersionStatus
8.5.15 winreturns information of tried IP while connecting. Error if connection failed
8.5.16+?
8.6.1 winreturns information of first tried IP. Error if first connect try failed
8.6.1 unixreflects connection process
8.6.2+?

Idea: The connection process should not be reflected. A compatibility value or an error should returned while connecting.

TIPs

Behaviour of fconfigure -peername, -sockname, -error, -connecting

A discussion tip on the behaviour of those commands while connecting was drafted.

A new option '-connecting' should return 1 if connection is still in process.

Reason for that: there are use cases for socket -async without event loop.

Example: Within Web-Server verify multiple servers for connectivity. Open many sockets in the background, do some other calculations, check if connect terminated by "-connecting".

fconfigure -errorno

A possibility to return the full POSIX information of a background error was drafted.

Two possible solutions:

  • fconfigure -errordict: returns a dict as 'catch {} e d'
  • fconfigure -invokeerror: throws the stored background error or does nothing if no error present

Bugs

Win TCL8.6.1 only tries first IP

Bug 13d3af3ad5

TCL8.6.1 only tries the first of eventual multiple IP addresses to connect. This may cause serious connect issues with IPV6.

This is fixed in branch bug-13d3af3ad5 which also serves as main branch to fix all bugs in TCL8.6.1 and to test enhancements too.

Win connect ignored

Bug 336441ed59

When a connect terminates to quick so the notifier is not ready yet, the connect is ignored and thus it waits forever for it.

VersionStatus
8.5.15bug present
8.5.16+fixed
8.6.1bug present
8.6.2+fixed in branch bug-13d3af3ad5

Test is timing dependent and may ignore issue on some machines.

Empty error message on close on failed background flush

Bug 97069ea11a

VersionStatus
8.5.15bug present
8.5.16+fixed
8.6.1bug present
8.6.2+fixed

  Test proposal

The test is difficult, as an async connect must fail after a puts is issued on the channel.

Idea: write a dummy channel driver, which may be set to an error state by fconfigure -seterror and where the readbale/writable state may be set. So one could:

set h [open dummy]
fconfigure $h -seterror EWOULDBLOCK
fileevent $h writable {set x writable}
fconfigure $h -blocking 0
puts $h abc
fconfigure $h -setwritable 1
vwait x
catch {close $h} e d

No readable event on async socket connect failure

Bug 581937ab1e

VersionStatus
8.5.15 winbug present
8.5.16+ winFixed
8.6.1 winbug present
8.6.2+ winFixed in bug-13d3af3ad5 , test in core-8-5-branch

non-blocking operations do not fail after failed connect

This is present on windows 8.5 and is not jet attacked.

ToDo's

Clarify demanded functionality

  • When to throw which error?
  • When does a non-blocking function fail ?
  • What returns fconfigure -peername,-sockname ?

Port tests from 8-5-branch to trunk

The following new tests are only present in 8.5 and should also go to 8.6:

  • socket-8.2
  • socket-8.3

Process test failures

The branch of bug-13d3af3ad5 requires fine tuning.

  Current windows test failures
==== socket-14.7.2 pending [socket -async] and blocking [gets], no listener FAILED
==== Contents of test case:

        set sock [socket -async localhost [randport]]
        catch {gets $sock} x
        list $x [fconfigure $sock -error]

---- Result was:
{error reading "sock01B57690": connection refused} {}
---- Result should have been (glob matching):
{error reading "sock*": socket is not connected} {connection refused}
==== socket-14.7.2 FAILED



==== socket-14.11.0 pending [socket -async] and blocking [puts], no listener, no flush FAILED
==== Contents of test case:

        set sock [socket -async localhost [randport]]
        fconfigure $sock -blocking 0
        puts $sock ok
        fileevent $sock writable {set x 1}
        vwait x
        close $sock

---- Result was:
socket is not connected
---- Result should have been (exact matching):
broken pipe
==== socket-14.11.0 FAILED



==== socket-14.11.1 pending [socket -async] and blocking [puts], no listener, flush FAILED
==== Contents of test case:

        set sock [socket -async localhost [randport]]
        fconfigure $sock -blocking 0
        puts $sock ok
        flush $sock
        fileevent $sock writable {set x 1}
        vwait x
        close $sock

---- Result was:
socket is not connected
---- Result should have been (exact matching):
broken pipe
==== socket-14.11.1 FAILED

return connection failure of non-blocking gets/puts on (win) 8.5*

In tcl 8.5 (win), read or puts after a connection failure do not fail. This might be corrected or not by another bug fix. No priority at the moment.

prioritize connect errors and return most appropriate

If a socket connect fails, the error in the latest connect stage should be returned. This would prioritize "access denied" (e.g. socket in use) before "network unreachable" (no route).

Project stage for Win and Unix.

This is already implemented for Unix server sockets.