Jython Journeys

Notes about my work with jython and python

Asynchronous networking for jython: Overview

without comments

Over the Christmas holidays in 2003, I wrote a design for how Asynchronous Socket I/O might be implemented in jython, using java.nio. I wrote up some notes in HTML, and placed them on a group of pages on xhaus.com. These notes were the basis of the design which I later used to implement asynchronous I/O for jython sockets, which is now a part of the jython distribution.

Although these notes are now out-of-date, having been surpassed by the actual implementation itself, I am publishing them here for historical purposes. The notes are broken down into four main areas.

  1. Overview
  2. Socket module
  3. Select module
  4. Asyncore module

For documentation on how to use the jython’s asynchronous socket I/O, see the documentation for the socket, select, asyncore, and asynchat modules.




Introduction

The purpose of this document is to discuss the implementation of socket timeouts and asynchronous socket I/O processing in jython.

In versions of the java language prior to 1.4, java had no built in support for non-blocking I/O. This applied to all forms of I/O, including files, sockets, pipes, etc. This has meant that all I/O involved the use of blocking calls, which consequently required the use of threads. While threads are a useful abstraction for programmers that permits the processing of multiple requests simultaneously, this abstraction comes at a high cost, in terms of resource consumption. High consumption of resources leads to fundamental limits on the number of requests that can be processed at a time, which means that thread-based architectures can scale badly, and perhaps fail to take advantage of the capabilities of modern PC hardware. For a more detailed discussion of this topic, read about the C10K problem. For more information about processing sockets in an asynchronous fashion, read this tutorial on Asynchronous Socket Programming.

In contrast, cpython has had inbuilt support for non-blocking I/O for a long time, based on the C/unix select call, which allows the programmer to examine the readiness state of multiple file descriptors (the unix abstraction which represents all I/O channels). This non-blocking I/O support has enabled cpython to support development of server and client architectures that do not suffer from the limitations of threads, and to process large numbers of requests in a highly stable fashion. Among the cpython frameworks based on non-blocking I/O are

Prior to version 1.4, java did not provide support for non-blocking socket I/O, therefore it was not possible to provide such support in jython. In version 1.4, java evolved the capability of using I/O channels in a non-blocking manner. This means that it is now possible to implement non-blocking I/O in jython, in a manner that is compatible with cpython. The purpose of these documents is to discuss the implementation of such facilities.

Also, since version 2.3, cpython has had support for socket timeouts. However, support does not currently exist in jython for socket timeouts, since at the time that the existing jython module was written (version 2.1), timeouts were not a part of the standard interface of sockets. The java platform has always had support for socket timeouts, even in version prior to java 1.4. If modifications are to made to the existing jython socket module to support non-blocking I/O, now is the ideal opportunity to update the socket module to support timeouts as well. As will be discussed, there is a fundamental relationship between non-blocking socket I/O and socket timeouts, in the cpython model at least.



Goals for this implementation project

The following are goals for this implementation of non-blocking I/O in jython.

  1. Cpython compatibility. The primary requirement is that the developed software be interface-compatible with the cpython library modules which provide socket support. This so that the existing large volume of cpython code which uses sockets can be executed in jython with no modification.
  2. Thread-safe. The developed software must be thread-safe, i.e. as far as is possible, accessing objects (created through the software) from multiple threads simultaneously must result in predictable behaviour and no corruption of data.
  3. Non-blocking TCP socket support. The developed software should support nonblocking access to both client and server TCP sockets. This applies to all operations, including opening and closing connections to socket endpoints, reading and writing data, and detection of out-of-band data.
  4. Non-blocking UDP socket support. Ideally, non-blocking operations should be supported on UDP/datagram sockets.
  5. Socket timeout support. In cpython 2.3, socket objects gained two new methods: the settimeout and setblocking methods. Although the language features to implement these capabilities for jython sockets have always been available on the Java platform, the current jython socket implementation does not support thse methods (since they were not a standard part of the cpython socket API when the jython module was first written). Although the primary goals of this project are to support nonblocking I/O, it would also be desirable to implement these methods for all versions of java prior to 1.4, so that jythonistas can at least have an API which is as compatible as possible with cpython 2.3, even if they are using a pre1.4 JVM.

The following are not goals of this project.

  1. Non-blocking file operation support. Ideally, in order to support the development of high-throughput and robust server architectures, the developed software should provide support for non-blocking operations on files and directories.
  2. Non-blocking pipe operation support. Ideally, the developed software should provide support for non-blocking operations on pipe, i.e. communications channels between OS processes.
  3. Non-blocking generic I/O support. Ideally, the developed software should provide support for non-blocking operations on any form of I/O channel, i.e. any communications channel that supports transmission and receipt of a stream of bytes.

However, it is currently not possible to provide support for these desirable features, in a platform independent fashion, since java 1.4 does not support non-blocking operations on I/O channels other than sockets. While it is possible to provide support in a platform-dependent fashion, using JNI, such an implementation is outside the scope of this project.



Java vs. jython

There are two choices for the language in which this software can be implemented.

Language Pros Cons
Java
  1. Speed. If the software is written in Java, it will be faster, since a layer of jython interpretation will be avoided.
  2. More robust exception handling: java’s insistence on explicit declaration and handling of exceptions means that exceptions are less likely to go unforeseen or unprocessed.
  1. Changing object model in jython. As noted by Samuele Pedroni, the interface to the java implementation of jython classes may change in the near future, which would require a rewrite for future versions of jython. (Presumably this is because of the requirement to support python 2.2 new-style classes and metaclasses).
  2. Lengthier implementation.
Jython
  1. More flexibility in prototyping multiple approaches.
  2. More flexibility when building, thus more likely end up with running software.
  3. Less lines of code means less bugs.
  4. Can be readily translated to java in the future.
  1. Slight loss of execution speed.

It is proposed to implement this software in jython.

Written by alan.kennedy

December 26th, 2003 at 9:30 pm

Posted in jython

Tagged with , ,