Jython Journeys

Notes about my work with jython and python

Timeout sockets for jython

without comments

Back in 2005, I modified the jython socket module to support timeouts. Brian Zimmer checked in that patch, since I did not have jython SVN commit rights at that time.

I wrote a documentation page about the new timeout support, and placed it on xhaus.com. Due to a rearrangement of the xhaus.com website, I am moving that page to this blog.

It should be noted that the timeout functionality has been superceded by the further work that I did to make the socket module support asychronous I/O. So you should refer to the jython socket module documentation to see how to use timeouts. This page appears here solely for historical purposes.


Introduction

Socket timeouts are now included in the jython 2.2 distribution! So the information on this page is now out of date; you should download the latest release of jython instead.

Sockets are the core technology that enable inter-machine communications on the Internet. They generally do a pretty excellent job of communicating information across the globe, and are generally straightforward to use in software. But sometimes networks are saturated or servers are overloaded, which means that code using sockets has to be aware that socket connections can break, or can timeout, meaning that replies were not received from a remote party before a specified time had elapsed.

Writing robust network software can be made much easier when a language supports detection of timeouts on sockets. The purpose of this page is to describe some modifications I’ve made to the standard jython socket module to support socket timeouts.

You can read below about the history of socket timeouts in cpython, java and jython.

How to get the code

To use timeouts, simply

  1. Download CVS version 1.16 of the socket.py module.
  2. Replace the $jython_home/Lib/socket.py module with the new one just downloaded.

The source was originally made available as a patch against version 1.15 of the socket module.

Documentation

The API implemented should be identical to the cpython 2.3 API, so you should use the cpython 2.3 socket module documentation. In most cases, you should get identical behaviour from the same code run on both platforms. This includes the socket.timeout exception, which is defined as a subclass of the socket.error exception.

However, see below for one important difference between cpython and jython: the treatment of a zero timeout value.

Testing

I have also provided a module of unit-tests for the new timeout functionality. This module is derived mostly from the socket test module from cpython 2.3: I copied a lot of that code, and added a couple of new tests.

The test module is designed to run on both cpython (2.3+ only) and jython, and should ideally give identical results on both platforms. However, there is one of the tests (testTimeoutZero), that will fail on cpython, because of the problem with zero timeouts.

Differences in the treatment of zero timeout values

On cpython, when you specify a zero (i.e. 0 or 0.0) timeout value, the socket should behave the same as if the socket had been placed in non-blocking mode. See the cpython 2.3 socket object documentation for details.

Unfortunately, it is not possible to support non-blocking mode on sockets in java versions prior to 1.4. Moreover, java interprets a zero timeout value as an infinite timeout, i.e. the socket is placed in blocking mode.

To solve this conflict, I decided that the best thing to do with zero timeouts is to adjust them to the smallest possible timeout in java, which is 1 millisecond. So if you do socket.settimeout(0) with this module, what you will really get is equivalent to the cpython call socket.settimeout(0.001).

This means that you may get differing exception signatures when using zero timeouts under cpython and jython.

  1. Cpython: socket operations with zero timeouts that fail will raise socket.error exceptions. This is equivalent to a -1 return from the C socket.recv call, with errno set to EAGAIN, meaning "The socket is marked non-blocking and the receive operation would block, or a receive timeout had been set and the timeout expired before data was received."
  2. Jython: socket operations with zero timeouts that fail will generate socket.timeout exceptions.

History of socket timeouts in python & java

Timeouts in cpython

A socket timeout API was only introduced in Cpython version 2.3. Prior to that, the only way to implement socket timeouts was to use the select system call, a technique which was used by Tim O Malley’s timeoutsocket.py

Timeouts in java

Java has supported socket timeouts since JDK version 1.1, when the getSoTimeout() and setSoTimeout() methods were added to java.net.Socket objects.

However, Java could not support non-blocking I/O until JVM 1.4, which introduced the java.nio package.

Timeouts in jython

Although Java has been capable of supporting socket timeouts since JDK 1.1, this feature was never added to released versions of jython, since the most recent version of jython released is jython 2.1. Because socket timeouts were only introduced into cpython in version 2.3, there was no cpython 2.1 API for jython 2.1 to copy or implement. The code that I have provided implements the cpython 2.3 socket timeout API.

Written by alan.kennedy

June 3rd, 2005 at 10:00 am

Posted in jython

Tagged with ,