<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jython Journeys &#187; asynchronous</title>
	<atom:link href="http://jython.xhaus.com/tag/asynchronous/feed/" rel="self" type="application/rss+xml" />
	<link>http://jython.xhaus.com</link>
	<description>Notes about my work with jython and python</description>
	<lastBuildDate>Tue, 01 Dec 2009 19:37:22 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Socket shutdown versus socket close on cpython, jython and java.</title>
		<link>http://jython.xhaus.com/socket-shutdown-versus-socket-close-on-cpython-jython-and-java/</link>
		<comments>http://jython.xhaus.com/socket-shutdown-versus-socket-close-on-cpython-jython-and-java/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 18:16:48 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=65</guid>
		<description><![CDATA[So, here we are again with translating cpython socket semantics to java socket semantics, in order to correctly implement the cpython socket API on jython.
The latest issue is socket shutdown.

Cpython sockets have two separate methods related to terminating a socket connection; the close method and the shutdown method.
Before we get into the difference between the [...]]]></description>
			<content:encoded><![CDATA[<p>So, here we are again with translating cpython socket semantics to java socket semantics, in order to correctly implement the cpython socket API on jython.</p>
<p>The latest issue is <strong>socket shutdown</strong>.<br />
<span id="more-65"></span><br />
<a href="http://docs.python.org/library/socket.html#id1">Cpython sockets</a> have two separate methods related to terminating a socket connection; the <strong>close</strong> method and the <strong>shutdown</strong> method.</p>
<p>Before we get into the difference between the two, we should note that when a TCP socket connection is to be terminated, a network packet containing a FIN is sent to the peer, informing them to tear down the connection (although <a href="http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_termination">sometimes an RST packet can be sent instead</a>). It is a sometimes used practice to <a href="http://www.developerweb.net/forum/showthread.php?t=2940">shutdown only one side of a connection</a>. For example, when a client knows that its request has been fully transmitted, it shuts down its transmit stream to the server, but leaves the receive stream open for the response. This makes the clients intention for future communications more explicit, and may lighten the load on the server. However, this is controversial topic, because that can also lead <a href="/?p=5">asynchronous servers</a> to mistakenly think that a socket is readable when it is not. You can find a detailed and thorough discussion of this topic in ActiveState <a href="http://code.activestate.com/recipes/408997/">Recipe 408997: When to not just use socket.close()</a>; make sure to read all of the comments.</p>
<p>The <strong>close</strong> method of sockets closes the file descriptor to which the socket is connected. When the last file descriptor connected to the socket is closed, then the operating system also closes the underlying socket, which results in the transmission of the FIN packet. That wording is important: <em>&#8220;when the last file descriptor .. is closed&#8221;</em> has specific meaning in many unix network servers architectures. The archetypal design for a network server on unix is to accept incoming socket connections in one process, and then spawn a subprocess to service the connection. Since the child process inherits the file descriptor table of its parent, it also inherits a file descriptor for the socket. Which means that there can be multiple file descriptors open on a socket. Which means that closing a socket is not guaranteed to close the connection; that will not happen until <strong>all</strong> file descriptors for the socket are closed.</p>
<p>The <strong>shutdown</strong> method, on the other hand <strong>only</strong> sends the FIN packet, regardless of how many file descriptors are open to the socket; moreover, it doesn&#8217;t affect any of those file descriptors.</p>
<p>There are some problems for implementing <strong>shutdown</strong> on java and thus on jython. Java servers are almost always multi-threaded, and process incoming requests in spawned threads, <strong>not</strong> processes. For this reason, and because of the fact that java does not expose C file descriptors, there are no socket methods that differentiate between the socket and file descriptor; the two are one and the same in java. This applies to all types of socket.</p>
<p>Implementing shutdown will be discussed below under the different socket types</p>
<ol>
<li><strong>TCP client sockets</strong> are fine: <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html">java.net.Socket</a> objects have the <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html#shutdownInput()">shutdownInput</a> and <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html#shutdownOutput()">shutdownOutput</a> methods, which shut down the receive stream and the transmit stream respectively.</li>
<li><strong>TCP server sockets</strong> are different: they don&#8217;t have transmit and receive streams: they exist only to <strong>accept</strong> incoming socket connections. So when a TCP server socket is shutdown, the result of the call should be to close the listen queue for the socket, and discard all queued incoming connections. In java, server sockets do not have a shutdown method (as you can see from their javadocs: <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/ServerSocket.html">java.net.ServerSocket</a> and <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/nio/chennels/ServerSocketChannel.html">java.nio.channels.ServerSocketChannels</a>: remember, both classes are required to fully implement all cpython socket semantics in jython). So, how to implement the <strong>shutdown</strong> for TCP server sockets? In java, the same effect is achieved is issuing the <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/ServerSocket.html#close()">close</a> method. So the choice is whether or not to make <strong>shutdown</strong> call <strong>close</strong>? Since production code that uses the <strong>shutdown</strong> method will also call the <strong>close</strong> method immediately, or soon afterwards, that would make that series of calls fail. Therefore, the right choice (IMHO) is to have the <strong>shutdown</strong> method as a no-op, i.e. <strong>do nothing</strong>, and document the fact that the user must call <strong>close</strong> on the socket in the <a href="http://wiki.python.org/jython/NewSocketModule">jython socket module documentation. </a></li>
<li><strong>UDP sockets</strong>, similarly don&#8217;t have input and output streams; calling shutdown on the socket should stop the acceptance of incoming packets. But in java, neither <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/DatagramSocket.html">java.net.DatagramSocket</a>s nor <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/nio/channels/DatagramSocket.html">java.nio.channels.DatagramSocketChannel</a>s have <strong>shutdown</strong> methods; instead the same effect is achieved in by calling the <strong>close</strong> method. So, the right choice for the <strong>shutdown</strong> of UDP sockets is to make it a no-op, and document that fact.</li>
</ol>
<p>I have checked in an implementation of the above into the jython SVN; in the release 2.2 maintenance branch at <a href="http://fisheye3.atlassian.com/changelog/jython?cs=6000">revision 6000</a> and into trunk at <a href="http://fisheye3.atlassian.com/changelog/jython?cs=6001">revision 6001</a>. I have put together this page to record my reasoning for implementing things this way, and the research that I&#8217;ve done in trying to arrive at the right implementation. Or at least, an implementation that is <strong>as right as possible</strong> for the jython programmer.</p>
<p>On a related note, I see that the good people over in <a href="http://twistedmatrix.com/">Twisted Matrix</a> are making <a href="http://twistedmatrix.com/trac/ticket/3413">great progress with getting twisted running on jython</a>. It will be fantastic to see one of the premier python <a href="/?p=5">asynchronous frameworks</a> working on jython!</p>
<p>Lastly, thanks to <a href="http://twistedmatrix.com/glyph/">Glyph Lefkowitz</a> of <a href="http://twistedmatrix.com">twisted</a> for reporting this situation in the jython bug tracker: <a href="http://bugs.jython.org/issue1121">listening socket shutdown expects the wrong kind of socket</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/socket-shutdown-versus-socket-close-on-cpython-jython-and-java/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Twisted and Zope: high performance asynchronous network servers in jython.</title>
		<link>http://jython.xhaus.com/twisted-and-zope-high-performance-asynchronous-network-servers-in-jython/</link>
		<comments>http://jython.xhaus.com/twisted-and-zope-high-performance-asynchronous-network-servers-in-jython/#comments</comments>
		<pubDate>Mon, 15 Sep 2008 19:10:13 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=5</guid>
		<description><![CDATA[I&#8217;m tremendously excited this week; it looks like the work I did on supporting asynchronous sockets and select in jython has paid off.

Cpython excels in a very specific area; asynchronous (aka non-blocking) network servers. Back in the days before multi-threading was invented, asynchronous designs were the only available mechanism for managing more than one connection [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m tremendously excited this week; it looks like <a href="http://fisheye3.atlassian.com/changelog/jython?cs=3227">the work I did on supporting asynchronous sockets and select in jython</a> has paid off.</p>
<p><span id="more-5"></span></p>
<p>Cpython excels in a very specific area; <a href="http://en.wikipedia.org/wiki/Asynchronous_I/O">asynchronous (aka non-blocking) network servers</a>. Back in the days before <a href="http://en.wikipedia.org/wiki/Thread_(computer_science)">multi-threading</a> was invented, asynchronous designs were the only available mechanism for managing more than one connection in a single <a href="http://en.wikipedia.org/wiki/Process_(computing)">process</a>. Although it was possible to spawn off <a href="http://en.wikipedia.org/wiki/Child_process">new processes</a> to service incoming requests, that made <a href="http://en.wikipedia.org/wiki/Inter-process_communication">communicating and sharing</a> information and resources (e.g. database connections) between server components more complex and intractable.</p>
<p>With an asynchronous design, all of the incoming socket connections are managed by a single process. Current socket connections are kept in a simple data structure, such as a list, along with state information relating to the connection, and perhaps a handler, i.e. a piece of code that services the incoming requests. The single process used the unix <a href="http://docs.python.org/lib/module-select.html">select</a> call (or its descendants such as <a href="http://docs.python.org/lib/poll-objects.html">poll</a>) to monitor the state of every connection simultaneously, and then invoking the associated handlers when a network event of interest to them occurred (i.e. following a <a href="http://en.wikipedia.org/wiki/Reactor_pattern">reactor pattern</a>). And therein lies the problem.</p>
<p>When the asynch server calls the handler to service a request, that handler cannot delay before it returns; it must return very quickly, or it holds up the entire server. Returning quickly is easy if you&#8217;re doing trivial processing, e.g. an echo or chat server.  But if you need to connect to a database, or even do something as simple as a DNS lookup, that requires forming another network connection, sending a request packet and waiting for a response. Which means that if your database or DNS library waits until the response arrives, hundreds of milliseconds or even seconds later, then the entire network server is held up, and clients must wait possibly seconds for service; clearly unacceptable. So with asynchronous servers, you must always use libraries that are aware they are operating in an asynchronous environment, are able to surrender control while they are awaiting a network response, and can add themselves to the server <a href="http://en.wikipedia.org/wiki/Reactor_pattern">reactor</a>, so that they can be notified when their response arrives.</p>
<p>While asynchronous architectures thrived in many areas, they proved to be overly complex for the mainstream programming market. Making all libraries asynch-aware, and tracking all of the interactions between them, was complex, difficult to understand, and thus error-prone. <a href="http://en.wikipedia.org/wiki/Thread_(computer_science)">Multi-threading</a> was invented to circumvent these problems. Instead of a single thread of execution controlling network service, separate threads of execution could be created, giving the illusion that there were multiple copies of the server code executing simultaneously, inside the same process, sharing memory, etc. Actually all the threads were running on the same linear processor, and the available <a href="http://en.wikipedia.org/wiki/Preemptive_multitasking#Time_slice">timeslices</a> were divided between them, in much the same way that most modern operating systems timeslice a single processor between multiple processes. The threads would generally run the same instructions, but would have their own program counter and call stack. Threads made programmers lives much easier, since threads could be designed to execute in a linear fashion. If the thread needed to pause at any stage, e.g. to await the response to a network request, it simply suspended itself, and a different thread <a href="http://en.wikipedia.org/wiki/Context_switch">would be selected to be given CPU time</a>. At low cost.</p>
<p>Well, not quite.</p>
<p>There are problem with threads. Threads can have <a href="http://forums.sun.com/thread.jspa?messageID=3803197">very large memory overheads</a>, perhaps measuring in megabytes. Threads must <a href="http://en.wikipedia.org/wiki/Synchronization_(computer_science)">synchronised</a>, so that they don&#8217;t corrupt shared data structures, e.g. <a href="http://en.wikipedia.org/wiki/Race_condition">race conditions</a>, which can be very hard to recognise when they happen, and complex to avoid in design. And threads can <a href="http://en.wikipedia.org/wiki/Deadlock">deadlock</a>, which can be enormously difficult to debug.</p>
<p>The overhead of threads is such that it is rare to see a threading-based server outperform a well designed asynchronous server, on identical hardware. Threaded servers rarely service more than a couple of thousand network connections simultaneously; many can only service in the hundreds per second. There have been incredible increases in all forms of hardware capacity in recent decades; commodity boxes come  with gigahertz processors, gigabytes of memory, terabytes of hard disk, and gigabits of network bandwidth. But although threaded-based servers have vastly improved in design, they still cannot match the performance of asynchronous servers, and address the <a href="http://www.kegel.com/c10k.html">C10K problem</a>.</p>
<p>The C10K problem is a simple one; how to service 10,000 simultaneous network requests. I refer to you the <a href="http://www.kegel.com/c10k.html">C10K website</a> for enormously detailed technical information on this complex problem. Suffice it to say that asynchronous architectures, with their much smaller memory usage, and lack of need for locking, synchronisation and context-switching, are generally considered to be far more performant than threaded architectures.</p>
<p>So where does python come in? It so happens that python is an excellent language for writing asynchronous servers. Python&#8217;s expressiveness and conciseness make it an excellent choice for developing simple and elegant solutions to the problems posed by asynchronous designs. Python was first published in 1991, years before java, and did not develop multi-threading until much later; <a href="http://docs.python.org/lib/module-threading.html">python&#8217;s threading design</a> borrows much from java&#8217;s design. Before threading came to python, asynchronous was the design of choice; none more so than Sam Rushing&#8217;s <a href="http://www.nightmare.com/medusa/">medusa</a>, which is still considered the archetypal asychronous design, and was adapted into python as the <a href="http://www.python.org/doc/current/lib/module-asyncore.html">asyncore module</a>.</p>
<p>But asyncore is basic, and doesn&#8217;t provide non-blocking support for the protocols necessary in a real-world application; database protocols, DNS lookups, etc. But there are two heavyweights in the python asynchronous world that have the required support, in a robust form. <a href="http://www.zope.com">Zope Corporation</a> was there first with their venerable <a href="http://en.wikipedia.org/wiki/Zope">Zope</a> product, arguably the grand-daddy of all python web frameworks. But dissatisfaction with Zope&#8217;s complexity lead to a new initiative; the <a href="http://en.wikipedia.org/wiki/Twisted_(software)">Twisted Matrix</a>. I won&#8217;t try to introduce Twisted here; take a look at the names of the sponsors on the <a href="http://twistedmatrix.com/">Twisted website</a> to see how important a framework it is.</p>
<p>And that&#8217;s why I&#8217;m excited; Twisted could soon be running on jython!</p>
<p>Back in the old days, jython 2.1 could not do aysnchronous socket operations. Jython 2.1 was written in the days when the only socket support in java was <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/package-summary.html">java.net</a>, which was threading oriented. It was only in <a href="http://java.sun.com/j2se/1.4.2/docs/guide/nio/">version 1.4 of the JVM that asynchronous support arrived</a>, in the shape of the <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/package-summary.html">java.nio</a> package. Now java has robust asynchronous support, after several years in the field.</p>
<p>I saw the possibility of using java.nio to enable jython to do asynchronous sockets a couple of years ago. I developed the support, and <a href="&lt;a href=">checked it into jython 2.2 last year</a>, in the hope that it would draw the attention of developers of the big cpython asynchronous frameworks. Java has some distinct advantages over cpython in high performance network serving world, with the most obvious being the ability to run on all cores of <a href="http://en.wikipedia.org/wiki/Multi-core_(computing)">multi-core processors</a> simultaneously. Cpython is restricted in this regard by it&#8217;s <a href="http://en.wikipedia.org/wiki/Global_Interpreter_Lock">Global Interpreter Lock</a>, which prevents multiple threads running pure python code from running on multiple cores or processors simultanously. In java, and thus in jython, every single core in the multi-core system can be running its own reactor, actually simultaneously.</p>
<p>It&#8217;s looking more like those cpython asynchronous frameworks could be coming to jython soon.</p>
<p>The founder and chief architect of Twisted, <a href="http://glyph.twistedmatrix.com/">Glyph Lefkowitz</a>, logged three bugs (<a href="http://bugs.jython.org/issue1119">1119</a>, <a href="http://bugs.jython.org/issue1120">1120</a>, <a href="http://bugs.jython.org/issue1121">1121</a>) against the jython socket module last week; I fixed them yesterday. I&#8217;m glad to say that they were all relating to corner cases and unusual usage; so far there have been no reports of serious bugs in the main functionality of the socket module. So hopefully the road to running twisted on jython is clear and obstacle free, at least at the level of socket communications.</p>
<p>And the Zope people have an ongoing project to get Zope running on jython; see the <a href="http://www.nabble.com/forum/Search.jtp?query=jython&amp;sort=date&amp;local=y&amp;forum=6720">Zope-dev archives</a> for ongoing updates.</p>
<p>Yes, exciting times indeed!</p>
<p>If you are interested in reading further about asynchronous I/O in the java.nio package, I thoroughly recommend Ron Hitchens book <a href="http://javanio.info">Java NIO</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/twisted-and-zope-high-performance-asynchronous-network-servers-in-jython/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous networking for jython: Overview</title>
		<link>http://jython.xhaus.com/asynchronous-networking-for-jython-overview/</link>
		<comments>http://jython.xhaus.com/asynchronous-networking-for-jython-overview/#comments</comments>
		<pubDate>Fri, 26 Dec 2003 21:30:57 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=107</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p xmlns:date="http://exslt.org/dates-and-times">Over the Christmas holidays in 2003, I wrote a design for how <a href="http://en.wikipedia.org/wiki/Asynchronous_I/O">Asynchronous Socket I/O</a> might be implemented in jython, using <a href="http://java.sun.com/j2se/1.4.2/docs/guide/nio/">java.nio</a>. 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.</p>
<p>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.</p>
<ol>
<li>
<a href="/asynchronous-networking-for-jython-overview/">Overview</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-socket-module/">Socket module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-select-module/">Select module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-asyncore-module/">Asyncore module</a>
</li>
</ol>
<p>For documentation on how to use the jython&#8217;s asynchronous socket I/O, see the documentation for the <a href="http://wiki.python.org/jython/NewSocketModule">socket</a>, <a href="http://wiki.python.org/jython/SelectModule">select</a>, <a href="http://www.python.org/doc/2.5/lib/module-asyncore.html">asyncore</a>, and <a href="http://www.python.org/doc/2.5/lib/module-asynchat.html">asynchat</a> modules.</p>
<p><span id="more-107"></span><br />
<hr /><a name="intro"></a><br />
<h2>Introduction</h2>
<p>
				The purpose of this document is to discuss the implementation of socket timeouts and asynchronous socket I/O processing in jython.
			</p>
<p>
				In versions of the java language prior to 1.4, java had no built in support for <b>non-blocking</b> 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 <b>thread</b>s. 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 <a href="http://www.kegel.com/c10k.html">C10K problem</a>. For more information about processing sockets in an asynchronous fashion, read this <a href="http://squirl.nightmare.com/medusa/async_sockets.html">tutorial on Asynchronous Socket Programming</a>.
			</p>
<p>
				In contrast, cpython has had inbuilt support for non-blocking I/O for a long time, based on the C/unix <b>select</b> 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
			</p>
<ul>
<li>
<a href="http://www.twistedmatrix.com">Twisted</a>
</li>
<li>
<a href="http://www.nightmare.com/medusa/index.html">Medusa</a>
</li>
<li>
<a href="http://www.python.org/doc/current/lib/module-asyncore.html">Asyncore</a> (library module)</li>
</ul>
<p>
				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.
			</p>
<p>
				Also, since version 2.3, cpython has had support for <b>socket timeouts</b>. 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.
			</p>
<hr /><a name="goals"></a><br />
<h2>Goals for this implementation project</h2>
<p>
				The following are goals for this implementation of non-blocking I/O in jython.
			</p>
<ol>
<li>
<b>Cpython compatibility</b>. 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.</li>
<li>
<b>Thread-safe</b>. The developed software must be <b>thread-safe</b>, 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.</li>
<li>
<b>Non-blocking TCP socket support</b>. 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 <b>out-of-band</b> data.</li>
<li>
<b>Non-blocking UDP socket support</b>. Ideally, non-blocking operations should be supported on UDP/datagram sockets.</li>
<li>
<b>Socket timeout support</b>. In cpython 2.3, socket objects gained two new methods: the <b>settimeout</b> and <b>setblocking</b> 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.</li>
</ol>
<p>
				The following are <b>not</b> goals of this project.
			</p>
<ol>
<li>
<b>Non-blocking file operation support</b>. 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.</li>
<li>
<b>Non-blocking pipe operation support</b>. Ideally, the developed software should provide support for non-blocking operations on pipe, i.e. communications channels between OS processes.</li>
<li>
<b>Non-blocking generic I/O support</b>. 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.</li>
</ol>
<p>
				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.
			</p>
<hr /><a name="language"></a><br />
<h2>Java vs. jython</h2>
<p>
                There are two choices for the language in which this software can be implemented.
            </p>
<table border="1">
<tr>
<th>Language</th>
<th>Pros</th>
<th>Cons</th>
</tr>
<tr>
<td><b>Java</b></td>
<td>
<ol>
<li>Speed. If the software is written in Java, it will be faster, since a layer of jython interpretation will be avoided.</li>
<li>More robust exception handling: java&#8217;s insistence on explicit declaration and handling of exceptions means that exceptions are less likely to go unforeseen or unprocessed.</li>
</ol>
</td>
<td>
<ol>
<li>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).</li>
<li>Lengthier implementation.</li>
</ol>
</td>
</tr>
<tr>
<td><b>Jython</b></td>
<td>
<ol>
<li>More flexibility in prototyping multiple approaches.</li>
<li>More flexibility when building, thus more likely end up with running software.</li>
<li>Less lines of code means less bugs.</li>
<li>Can be readily translated to java in the future.</li>
</ol>
</td>
<td>
<ol>
<li>Slight loss of execution speed.</li>
</ol>
</td>
</tr>
</table>
<p>
                It is proposed to implement this software in jython.
            </p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/asynchronous-networking-for-jython-overview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous networking for jython: the socket module</title>
		<link>http://jython.xhaus.com/asynchronous-networking-for-jython-the-socket-module/</link>
		<comments>http://jython.xhaus.com/asynchronous-networking-for-jython-the-socket-module/#comments</comments>
		<pubDate>Fri, 26 Dec 2003 21:10:59 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=112</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>Over the Christmas holidays in 2003, I wrote a design for how <a href="http://en.wikipedia.org/wiki/Asynchronous_I/O">Asynchronous Socket I/O</a> might be implemented in jython, using <a href="http://java.sun.com/j2se/1.4.2/docs/guide/nio/">java.nio</a>. 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.</p>
<p>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.</p>
<ol>
<li>
<a href="/asynchronous-networking-for-jython-overview/">Overview</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-socket-module/">Socket module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-select-module/">Select module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-asyncore-module/">Asyncore module</a>
</li>
</ol>
<p>For documentation on how to use the jython&#8217;s asynchronous socket I/O, see the documentation for the <a href="http://wiki.python.org/jython/NewSocketModule">socket</a>, <a href="http://wiki.python.org/jython/SelectModule">select</a>, <a href="http://www.python.org/doc/2.5/lib/module-asyncore.html">asyncore</a>, and <a href="http://www.python.org/doc/2.5/lib/module-asynchat.html">asynchat</a> modules.</p>
<p><span id="more-112"></span><br />
<hr /><a name="intro"></a><br />
<h2>Modifications to the existing jython socket module</h2>
<p>
				There are a number of modifications that would need to be made to the existing jython socket implementation in order to facilitate support for timeouts and for non-blocking operations. These modifications are discussed in this document.
			</p>
<hr /><a name="socketvschannel"></a><br />
<h2>Socket objects vs. SocketChannel objects</h2>
<p>
                It is required to provide a facility in jython which permits the programmer to &#8220;watch&#8221; the readiness status of multiple I/O channels. In cpython, file descriptors are the handles which are used to represent watchable channels. A typical code sequence might look like this
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">s = <span style="color: #dc143c;">socket</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span>AF_INET, SOCK_STREAM<span style="color: black;">&#41;</span>
fd = s.<span style="color: black;">fileno</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
po = <span style="color: #dc143c;">select</span>.<span style="color: black;">poll</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
po.<span style="color: black;">register</span><span style="color: black;">&#40;</span>fd<span style="color: black;">&#41;</span></pre></div></div>

<p>
                However, the concept of a file descriptor has no meaning on the java platform, since the JVM does not use file descriptors (they are too platform specific). Instead, in a jython implementation, it will be necessary to obtain a <b>java.nio.channels.SelectableChannel</b> representing the channel to be watched.
            </p>
<p>
                Fortunately, all socket objects in the <b>java.net</b> package have a <b>getChannel()</b> method (as of java 1.4 anyway).</p>
<p>
             	Unfortunately, this method returns a <b>null</b> value when used with a socket created by the constructors <b>java.net.Socket</b>, <b>java.net.ServerSocket</b>, <b>java.net.DatagramSocket</b>. The only time when <b>java.net.*Socket.getChannel()</b> returns a SelectableChannel is when the socket itself was created through  the <b>java.nio.channels</b> package. In all cases, this is done by calling a static method of the relevant class. The creation methods for the different channel types are
            </p>
<table border="1">
<tr>
<th>Channel type</th>
<th>Java.net constructor</th>
<th>Java.nio construction method</th>
</tr>
<tr class="tabodd">
<td>TCP Client Socket</td>
<td>java.net.Socket()</td>
<td>java.nio.channels.SocketChannel.open()</td>
</tr>
<tr class="tabeven">
<td>TCP Server Socket</td>
<td>java.net.ServerSocket()</td>
<td>java.nio.channels.ServerSocketChannel.open()</td>
</tr>
<tr class="tabodd">
<td>UDP Socket</td>
<td>java.net.DatagramSocket()</td>
<td>java.nio.channels.DatagramChannel.open()</td>
</tr>
</table>
<p>
                This restriction means that all sockets that are to be processed using this proposed non-blocking socket I/O API must be created through the java.nio construction method outlined above.
            </p>
<p>
            	However, it is not simply of case of switching over to the new methods for all socket creation, since it is hoped to also support as many operations as possible on JVMs prior to version 1.4, e.g. timeouts. Therefore, it is necessary to separate out socket creation operations to a single set of factory methods or functions, which can be altered depending on the runtime environment in which they are run. The following is one proposed code sequence for creating socket factory functions, which should work on all JVMs. Another possible approach might be to create a factory class which dynamically modifies its behaviour.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">import</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;using java.nio&quot;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _createclientsock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">SocketChannel</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _createserversock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">ServerSocketChannel</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _createdatagramsock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">DatagramChannel</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ImportError</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;using java.net&quot;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _createclientsock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> java.<span style="color: black;">net</span>.<span style="color: black;">Socket</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _createserversock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> java.<span style="color: black;">net</span>.<span style="color: black;">ServerSocket</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _createdatagramsock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> java.<span style="color: black;">net</span>.<span style="color: black;">DatagramSocket</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
				Note that it should be sufficient to return simple <b>java.net</b> socket objects from these functions, because
			</p>
<ol>
<li>It requires less code modification to the existing jython socket module: the existing code is designed to work with <b>java.net.*Socket</b> objects.</li>
<li>In the case of 1.4 JVMs, where support for non-blocking operations is provided, the SelectableChannel corresponding to a socket can always be retrieved from the socket&#8217;s <b>getChannel()</b> method.</li>
<li>In the case of pre-1.4 JVMs, which do not support nonblocking I/O, calls to the <b>getChannel()</b> method will fail. However, non-blocking support is not provided for pre-1.4 JVMs.</li>
</ol>
<p>
				In summary
            </p>
<ol>
<li>Sockets should be created using the java.nio APIs where possible</li>
<li>Sockets should be created using the java.et APIs if java.nio is not available</li>
<li>Both these factory methods should return objects which implement the same interface, i.e. the interface presented by socket objects in the java.net package.</li>
<li>When a java.nio.channels.SelectableChannel is required, it can be retrieved from the socket using the the <b>getChannel()</b> method.</li>
</ol>
<hr /><a name="socketcreation"></a><br />
<h2>Socket creation in existing jython socket module</h2>
<p>
                The existing jython socket module constructs all sockets by using constructors from the <b>java.net</b> package. However, as discussed above, if a socket channel is to be watchable, a java.nio.channels.SelectableChannel object is required. Thus, the existing jython socket module will have to be modified to use the the factory approach outlined above, which uses java.nio where possible, and java.net where not. The only parts of the socket module that should require modification are the parts that actually create sockets.
            </p>
<p>
            For example, the following is the current code for the connect method of socket objects
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> connect<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, addr, port=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;This signifies a client socket&quot;</span>
     <span style="color: #ff7700;font-weight:bold;">if</span> port <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
         addr = <span style="color: black;">&#40;</span>addr, port<span style="color: black;">&#41;</span>
     <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>
     host, port = addr
     <span style="color: #ff7700;font-weight:bold;">if</span> host == <span style="color: #483d8b;">&quot;&quot;</span>:
         host = java.<span style="color: black;">net</span>.<span style="color: black;">InetAddress</span>.<span style="color: black;">getLocalHost</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
     <span style="color: #008000;">self</span>._setup<span style="color: black;">&#40;</span>java.<span style="color: black;">net</span>.<span style="color: black;">Socket</span><span style="color: black;">&#40;</span>host, port<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
                Which could be replaced with code similar to the following
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> connect<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, addr, port=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;This signifies a client socket&quot;</span>
     <span style="color: #ff7700;font-weight:bold;">if</span> port <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
         addr = <span style="color: black;">&#40;</span>addr, port<span style="color: black;">&#41;</span>
     <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>
     host, port = addr
     <span style="color: #ff7700;font-weight:bold;">if</span> host == <span style="color: #483d8b;">&quot;&quot;</span>:
         host = java.<span style="color: black;">net</span>.<span style="color: black;">InetAddress</span>.<span style="color: black;">getLocalHost</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
     sock = _createclientsocket<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
     <span style="color: #008000;">self</span>._setup<span style="color: black;">&#40;</span>sock<span style="color: black;">&#41;</span>
     <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>java.<span style="color: black;">net</span>.<span style="color: black;">InetSocketAddress</span><span style="color: black;">&#40;</span>host, port<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
				Note that this code is not yet sufficient: there is still timeout and blocking configuration to be taken into account. See below under <a href="#newmethods">Implementing the cpython 2.3 blocking/timeout model</a>.
			</p>
<hr /><a name="watchabletypes"></a><br />
<h2>Types of channels that can be examined</h2>
<p>
                In cpython, when a channel is to be watched, the <b>file descriptor</b> representing the channel is registered with a <a href="http://www.python.org/doc/current/lib/poll-objects.html">poll object</a>. However, whether or not the channel is <b>watchable</b> is determined by the operating system, and is thus platform independent. This model fits very well with cpython&#8217;s late-binding ethos.
            </p>
<p>
                In contrast, java has a very precise object model which differentiates watchable channels from other channel types by having watchable channel types extend the abstract class <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectableChannel.html">java.nio.channels.SelectableChannel</a>. If a java object is not a subclass of this abstract class, it cannot be &#8220;watched&#8221;.
            </p>
<p>
				This means that a mechanism is required for obtaining the underlying SelectableChannel from any given socket, through a public method, preferably re-using a known and comparable method from the cpython 2.3 API.
            </p>
<p>
                It is proposed to use the (currently unimplemented in jython) <b>fileno()</b> method to enable the programmer to obtain a <b>SelectableChannel</b> object which can be passed to poll objects. The fileno() method is the closest analogy to a SelectableChannel in the cpython model, and its return value is most frequently used as a SelectableChannel would be. However, since the two concepts are different, it is proposed to create two separate methods with the same interface. Thus, the fileno method for sockets could be defined as follows in the jython socket module.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> _tcpsocket:
 <span style="color: black;">&#91;</span>....<span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> getchannel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>.<span style="color: black;">getChannel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    fileno = getchannel</pre></div></div>

<p>
				The <b>getchannel()</b> method could be used internally to the new jython socket module, since it has inherent knowledge that the returned value is not a file descriptor but a SelectableChannel.
			</p>
<p>
				A similar method would be required for the <b>_udpsocket</b> class.
			</p>
<hr /><a name="newmethods"></a><br />
<h2>Implementing the cpython 2.3 blocking/timeout model</h2>
<p>
            The following list of cpython socket methods (as of cpython 2.3) are currently not available on jython socket objects, mostly because they are to do with non-blocking I/O or timeouts.
            </p>
<table border="1">
<tr>
<th>Method</th>
<th>Description</th>
<th>Notes</th>
</tr>
<tr class="tabodd">
<td>setblocking</td>
<td>This method permits the programmer to configure a socket to be in blocking or non-blocking mode.</td>
<td>This is the direct equivalent of the java <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectableChannel.html#configureBlocking(boolean)">java.nio.channels.SelectableChannel.configureBlocking()</a> method.</td>
</tr>
<tr class="tabeven">
<td>settimeout</td>
<td>This method permits the programmer to set the timeout value for a timeout mode socket.</td>
<td>This is the direct equivalent of the java <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectableChannel.html#configureBlocking(boolean)">java.nio.channels.SelectableChannel.configureBlocking()</a> method.</td>
</tr>
<tr class="tabodd">
<td>gettimeout</td>
<td>This method permits the programmer to retrieve the timeout value for a timeout mode socket.</td>
<td>This should return the currently configured timeout value.</td>
</tr>
</table>
<p>
                In the cpython socket model, the above top two methods are closely related. The <a href="http://www.python.org/doc/current/lib/socket-objects.html">cpython module reference for the socket module</a> says the following
            </p>
<p width="80%">
<cite><br />
Some notes on socket blocking and timeouts: A socket object can be in one of three modes: blocking, non-blocking, or timeout. Sockets are always created in blocking mode. In blocking mode, operations block until complete. In non-blocking mode, operations fail (with an error that is unfortunately system-dependent) if they cannot be completed immediately. In timeout mode, operations fail if they cannot be completed within the timeout specified for the socket. The setblocking() method is simply a shorthand for certain settimeout() calls.<br />
            </cite>
</p>
<p width="80%">
<cite><br />
Timeout mode internally sets the socket in non-blocking mode. The blocking and timeout modes are shared between file descriptors and socket objects that refer to the same network endpoint. A consequence of this is that file objects returned by the makefile() method should only be used when the socket is in blocking mode; in timeout or non-blocking mode file operations that cannot be completed immediately will fail.<br />
            </cite>
</p>
<p>
                The following algorithms for a jython implementation of the above methods could be proposed, in order to reflect the same semantics as the cpython API.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">    <span style="color: #ff7700;font-weight:bold;">def</span> settimeout<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, timeout<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> timeout <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">setblocking</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            millis = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>timeout <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">1000</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> millis == <span style="color: #ff4500;">0</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">setblocking</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>.<span style="color: black;">setSoTimeout</span><span style="color: black;">&#40;</span>millis<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> setblocking<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, flag<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">getchannel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">configureBlocking</span><span style="color: black;">&#40;</span>flag<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> JynioException<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Channel cannot be configured for blocking'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
                However these naive implementations cannot be used in practice, because of the <a href="#deferred">deferred creation of socket implementation objects</a>. This deferred creation of socket implementation objects means that the actual underlying implementation socket may not exist when the settimeout() and setblocking() methods are called. Therefore the socket configuration information must be stored locally on the jython socket object, for use in configuring the socket after it&#8217;s deferred creation.
            </p>
<p>
                Since the goal of this project is cpython 2.3 compatibility, it is proposed that the three explicit modes mentioned in the cpython documenation be adopted as allowable states of jython socket objects. These modes are <b>blocking</b>, <b>non-blocking</b>, <b>timeout</b>, and could be represented as constants as follows.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">MODE_BLOCKING    = <span style="color: #483d8b;">'block'</span>
MODE_NONBLOCKING = <span style="color: #483d8b;">'nonblock'</span>
MODE_TIMEOUT     = <span style="color: #483d8b;">'timeout'</span></pre></div></div>

<p>
                Also, there should be a permitted set of states for any given socket. Whether or not a socket is in one of the permitted states can be checked by assertions.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">_permittedstates = <span style="color: black;">&#40;</span>MODE_BLOCKING, MODE_NONBLOCKING, MODE_TIMEOUT<span style="color: black;">&#41;</span></pre></div></div>

<p>
                Note, however, that compatibility with cpython 2.3 <b>on JVM platforms prior to 1.4</b> is also a goal. On such JVMs there are only two permissible modes of operation: <b>blocking</b> and <b>timeout</b>: non-blocking operation is not supported. Therefore, the code above would have to be written as
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">import</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>
    _permittedmodes = <span style="color: black;">&#40;</span>MODE_BLOCKING, MODE_NONBLOCKING, MODE_TIMEOUT<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ImportError</span>:
    _permittedmodes = <span style="color: black;">&#40;</span>MODE_BLOCKING, MODE_TIMEOUT<span style="color: black;">&#41;</span></pre></div></div>

<p>
                The definition of the above methods then becomes (including required modifications to other functions/methods).
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span>family, <span style="color: #008000;">type</span>, flags=<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
    <span style="color: black;">&#91;</span>.....<span style="color: black;">&#93;</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> = MODE_BLOCKING
    <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> = <span style="color: #ff4500;">0</span>
    <span style="color: black;">&#91;</span>.....<span style="color: black;">&#93;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> _tcpsocket:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _config<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> <span style="color: #ff7700;font-weight:bold;">in</span> _permittedmodes
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>: <span style="color: #ff7700;font-weight:bold;">return</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> == MODE_BLOCKING:
            <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>.<span style="color: black;">setSoTimeout</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> == MODE_NONBLOCKING:
            <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>.<span style="color: black;">getchannel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">configureBlocking</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> == MODE_TIMEOUT:
            <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>.<span style="color: black;">setSoTimeout</span><span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">timeout</span><span style="color: #66cc66;">*</span><span style="color: #ff4500;">1000</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> settimeout<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, timeout<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> timeout <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> = MODE_BLOCKING
            <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> = <span style="color: #008000;">None</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>timeout<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> = MODE_NONBLOCKING
            <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> = <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> = MODE_TIMEOUT
            <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> = timeout
        <span style="color: #008000;">self</span>._config<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> setblocking<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, flag<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> flag:
            <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> = MODE_BLOCKING
            <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> = <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> = MODE_NONBLOCKING
            <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> = <span style="color: #ff4500;">0</span>
        <span style="color: #008000;">self</span>._config<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
				Note the introduction of the <b>_config()</b> method, which will be required on the <b>_tcpsocket</b> and <b>_udpsocket</b> classes. When and where this method should be used is discussed below.
			</p>
<hr /><a name="deferred"></a><br />
<h2>Deferred creation of socket implementation objects</h2>
<p>
                In cpython, after a socket object has been created, it can be used as either a server or a client socket. However, on the java platform, this &#8220;late-binding&#8221; on the socket implementation object itself cannot be used, because server and client socket objects are implemented through separate classes on the JVM.
            </p>
<p>
                The current jython socket module <b>defers</b> the creation of socket objects until it is known for what purpose the socket will be used. For example, when the <b>connect()</b> method is called on a socket object, it is then known that this is to be a client socket.
            </p>
<p>
            	All such methods that determine the final server/client/datagram nature of a socket (i.e. that both create and configure sockets), must be modified to take the new timout and blocking configuration options into account. This can be done through the <b>_config()</b> method discussed in the previous section. The sequence of operations should then be
            </p>
<ol>
<li>Create the socket</li>
<li>Configure the socket for timeouts, blocking, etc</li>
<li>Carry out the desired operation on the socket (e.g. accept, connect, etc)</li>
</ol>
<p>
                Taking the above definition of the <b>socket.connect()</b> method, and modifying it to support blocking configuration gives the following code.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">    <span style="color: #ff7700;font-weight:bold;">def</span> connect<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, addr, port=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;This signifies a client socket&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> port <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
            addr = <span style="color: black;">&#40;</span>addr, port<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>
        host, port = addr
        <span style="color: #ff7700;font-weight:bold;">if</span> host == <span style="color: #483d8b;">&quot;&quot;</span>:
            host = java.<span style="color: black;">net</span>.<span style="color: black;">InetAddress</span>.<span style="color: black;">getLocalHost</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        sock = _createclientsock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>._setup<span style="color: black;">&#40;</span>sock<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>._config<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># Configure timeouts, etc, now that the socket exists</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>java.<span style="color: black;">net</span>.<span style="color: black;">InetSocketAddress</span><span style="color: black;">&#40;</span>host, port<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
                The following is a typical expected call sequence for using sockets with timeouts.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">socket</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
s = <span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span>AF_INT, SOCK_STREAM<span style="color: black;">&#41;</span>
s.<span style="color: black;">settimeout</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1.0</span><span style="color: black;">&#41;</span>
s.<span style="color: black;">connect</span><span style="color: black;">&#40;</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'www.python.org'</span>, <span style="color: #ff4500;">80</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span></pre></div></div>

<p>
                Socket methods that would require similar modification to the <b>connect()</b> method above are
            </p>
<ol>
<li>_tcpsocket.accept()</li>
<li>_tcpsocket.listen()</li>
<li>_udpsocket.bind()</li>
<li>_udpsocket.connect()</li>
<li>_udpsocket.sendto()</li>
</ol>
<hr /><a name="exception"></a><br />
<h2>Exception compatibility with cpython.</h2>
<p>
				It is desirable that the proposed new jython socket module present the same &#8220;exceptions interface&#8221; as the cpython 2.3 socket module. This is currently not the case with the existing jython socket module. Consider the following two logs of interactive sessions with socket, one on cpython 2.3 and the other on jython 2.1.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">Python <span style="color: #ff4500;">2.3</span> <span style="color: black;">&#40;</span><span style="color: #808080; font-style: italic;">#46, Jul 29 2003, 18:54:32) [MSC v.1200 32 bit (Intel)] on win32</span>
Type <span style="color: #483d8b;">&quot;help&quot;</span>, <span style="color: #483d8b;">&quot;copyright&quot;</span>, <span style="color: #483d8b;">&quot;credits&quot;</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #483d8b;">&quot;license&quot;</span> <span style="color: #ff7700;font-weight:bold;">for</span> more information.
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">socket</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> s = <span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span>AF_INET, SOCK_STREAM<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> s.<span style="color: black;">connect</span><span style="color: black;">&#40;</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'anamethatdoesnotexist'</span>, <span style="color: #ff4500;">80</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;stdin&gt;&quot;</span>, line <span style="color: #ff4500;">1</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">?</span>
  File <span style="color: #483d8b;">&quot;&lt;string&gt;&quot;</span>, line <span style="color: #ff4500;">1</span>, <span style="color: #ff7700;font-weight:bold;">in</span> connect
<span style="color: #dc143c;">socket</span>.<span style="color: black;">gaierror</span>: <span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span>, <span style="color: #483d8b;">'getaddrinfo failed'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
				And
			</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">Jython <span style="color: #ff4500;">2.1</span> on java1.4.2 <span style="color: black;">&#40;</span>JIT: null<span style="color: black;">&#41;</span>
Type <span style="color: #483d8b;">&quot;copyright&quot;</span>, <span style="color: #483d8b;">&quot;credits&quot;</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #483d8b;">&quot;license&quot;</span> <span style="color: #ff7700;font-weight:bold;">for</span> more information.
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">socket</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> s = <span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span>AF_INET, SOCK_STREAM<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> s.<span style="color: black;">connect</span><span style="color: black;">&#40;</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'anamethatdoesnotexist'</span>, <span style="color: #ff4500;">80</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
Traceback <span style="color: black;">&#40;</span>innermost last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;console&gt;&quot;</span>, line <span style="color: #ff4500;">1</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">?</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\j</span>ython21<span style="color: #000099; font-weight: bold;">\L</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ocket.py&quot;</span>, line <span style="color: #ff4500;">135</span>, <span style="color: #ff7700;font-weight:bold;">in</span> connect
java.<span style="color: black;">net</span>.<span style="color: black;">UnknownHostException</span>: anamethatdoesnotexist
        at java.<span style="color: black;">net</span>.<span style="color: black;">PlainSocketImpl</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>PlainSocketImpl.<span style="color: black;">java</span>:<span style="color: #ff4500;">153</span><span style="color: black;">&#41;</span>
        <span style="color: black;">&#91;</span>.......<span style="color: black;">&#93;</span>
        at org.<span style="color: black;">python</span>.<span style="color: black;">util</span>.<span style="color: black;">jython</span>.<span style="color: black;">main</span><span style="color: black;">&#40;</span>jython.<span style="color: black;">java</span><span style="color: black;">&#41;</span>
&nbsp;
java.<span style="color: black;">net</span>.<span style="color: black;">UnknownHostException</span>: java.<span style="color: black;">net</span>.<span style="color: black;">UnknownHostException</span>: anamethatdoesnotexist</pre></div></div>

<p>
                This difference between exceptions reported on the different platforms makes it more difficult to write robust portable code, and can lead to unnecessary increased code density. It is desirable that the jython socket module generate the same exceptions as the cpython 2.3 module, to make the programmers job more straightforward.
            </p>
<p>
				However, this is non-trivial task. There is a very wide variety of socket exceptions that can be reported, reflecting the wide varieties of errors or problems that can be encountered with sockets, especially in relation to resource usage and other physical considerations. Also, sometimes the same exception differs in meaning subtly between platforms.
            </p>
<p>
				Another point is that although it may not be trivial to report the same exceptions as cpython, the following question should be asked: Is it correct to raise Java platform exceptions from socket methods?
            </p>
<p>
				To be discussed. I know this is not a trivial problem.
            </p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/asynchronous-networking-for-jython-the-socket-module/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous networking for jython: the select module</title>
		<link>http://jython.xhaus.com/asynchronous-networking-for-jython-the-select-module/</link>
		<comments>http://jython.xhaus.com/asynchronous-networking-for-jython-the-select-module/#comments</comments>
		<pubDate>Fri, 26 Dec 2003 21:05:27 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=115</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>Over the Christmas holidays in 2003, I wrote a design for how <a href="http://en.wikipedia.org/wiki/Asynchronous_I/O">Asynchronous Socket I/O</a> might be implemented in jython, using <a href="http://java.sun.com/j2se/1.4.2/docs/guide/nio/">java.nio</a>. 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.</p>
<p>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.</p>
<ol>
<li>
<a href="/asynchronous-networking-for-jython-overview/">Overview</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-socket-module/">Socket module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-select-module/">Select module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-asyncore-module/">Asyncore module</a>
</li>
</ol>
<p>For documentation on how to use the jython&#8217;s asynchronous socket I/O, see the documentation for the <a href="http://wiki.python.org/jython/NewSocketModule">socket</a>, <a href="http://wiki.python.org/jython/SelectModule">select</a>, <a href="http://www.python.org/doc/2.5/lib/module-asyncore.html">asyncore</a>, and <a href="http://www.python.org/doc/2.5/lib/module-asynchat.html">asynchat</a> modules.</p>
<p><span id="more-115"></span><br />
<hr /><a name="intro"></a><br />
<h2>Implementing the select function and poll objects</h2>
<p>
                The purpose of this document is to discuss implementation strategies for a jython implementation of the <a href="http://www.python.org/doc/current/lib/module-select.html">cpython select module</a>. In cpython, the select module provides two different methods for simultaneously examining the readiness status of a <b>set</b> of I/O channels.
            </p>
<ol>
<li>The <a href="http://www.python.org/doc/current/lib/module-select.html">select</a> function, which is derived from the <a href="http://unixhelp.ed.ac.uk/CGI/man-cgi?select+2">original Unix select call</a>, and takes as parameters three lists of file descriptors:
<ol>
<li>a list containing file descriptors which may be <b>readable</b>
</li>
<li>a list containing file descriptors which may be <b>writable</b>
</li>
<li>a list containing file descriptors which may have <b>out-of-band</b>(OOB) data</li>
</ol>
<p>                When the select function is called, it reads through each of these lists, and prepares its own internal lists of file descriptors which are to be &#8220;selected&#8221;. It then examines the readiness of the file descriptors in this internal list, and returns three lists which are subsets of the three lists passed in as parameters.</li>
<li>
<a href="http://www.python.org/doc/current/lib/poll-objects.html">Poll objects</a>, which are object-oriented descendants of the select function. In order to examine the readiness status of multiple file descriptors, the programmer creates a poll object. File descriptors are explicitly registered with the poll object. These descriptors are checked every time the poll objects <b>poll()</b> method is called, until the file descriptor is explicitly <b>unregistered</b>.</li>
</ol>
<p>
                As mentioned on the cpython <a href="http://www.python.org/doc/current/lib/poll-objects.html">Poll objects documentation page</a>, poll objects are superior to the select function call, since they <i>only require listing the file descriptors of interest, while select() builds a bitmap, turns on bits for the fds of interest, and then afterward the whole bitmap has to be linearly scanned again</i>. This means that performance of poll objects should be better than the select function.
            </p>
<p>
                Although poll objects may be superior, the select function call is still supported in cpython, for the following reasons.
            </p>
<ol>
<li>
<b>Historic</b>. There is a substantial body of code written in cpython which uses the select function.</li>
<li>
<b>Windows</b>. Windows does not support poll objects (Windows has it&#8217;s own equivalent API call).</li>
<li>
<b>Unix</b>. Although most modern unices support poll objects, there are still some variants that do not.</li>
</ol>
<p>
                As discussed below, cpython poll objects exhibit a very similar model to <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/Selector.html">java.nio.channels.Selector</a> objects, and thus it is natural to implement one using the other. Once poll objects have been implemented, a jython implementation of the select function can be layered on top of them.
            </p>
<hr /><a name="selector"></a><br />
<h2>Implementing poll objects with java Selector objects</h2>
<p>
                A likely approach to implementing cpython poll objects in jython is to implement them using java Selector objects.
            </p>
<p>
                The following are similarities between cpython <a href="http://www.python.org/doc/current/lib/poll-objects.html">select.poll</a> objects and <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/Selector.html">java.nio.channels.Selector</a> objects.
            </p>
<ol>
<li>Both are single objects which can &#8220;watch&#8221; multiple I/O channels at once.</li>
<li>Both monitor a set of I/O channels which have been explicitly <b>registered</b> with the object.</li>
<li>Both return a set of &#8220;keys&#8221; which indicate which channels are ready for I/O. In case of cpython, this is in the form of a list of tuples giving <b>(file descriptor, event mask)</b>. In java&#8217;s case, this is in the form of a set of <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectionKey.html">java.nio.channels.SelectionKey</a>s, which contain an event mask (or in java terminology, a set of <b>interestOps()</b>).</li>
<li>Both objects support the concept of a timeout, i.e. that the method call which watches the set of registered channels can timeout after a user specified time.</li>
<li>Both objects support the concept of taking a &#8220;snapshot view&#8221;, i.e. a zero-length timeout.</li>
<li>Both objects support the concept of waiting indefinitely for some readiness notification to appear.</li>
</ol>
<p>
                The important differences are as follows
            </p>
<ol>
<li>Java Selector objects have clearly defined semantics when a single selector object is operated from <b>multiple threads</b>. In contrast, the documentation for cpython poll objects makes no guarantees (or even statements) at all about access to poll objects from multiple threads (presumably this is related to the fact that cpython has a Global Interpreter Lock (GIL) which prevents more than one thread from executing python at any given time. See below under <a href="#threading">Threading</a> for more information).</li>
<li>Java SelectionKey objects permit the <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectionKey.html#attach(java.lang.Object)">attachment of application objects</a>, meaning that the programmer can attach a handler object to each channel, and which might be rsponsible for handling all I/O on the channel. Note however that although this facility is useful when writing application frameworks, it is unlikely to be useful in the case of implementing a cpython compatible select module, since cpython poll objects do not support the &#8220;attachment&#8221; of application objects to I/O channels to be watched. However, the <a href="/asynchronous-networking-for-jython-the-asyncore-module/">asyncore module</a> may be an ideal place to exploit this feature.</li>
</ol>
<hr /><a name="threading"></a><br />
<h2>Threading and the cpython Global Interpreter Lock</h2>
<p>
            	TBD: Need to understand possible use-cases for calling poll objects from multiple threads.
            </p>
<p>
            	If you have come across a need to call poll objects from multiple threads, I&#8217;d like to hear about it.
            </p>
<hr /><a name="register"></a><br />
<h2>Registering and unregistering channels</h2>
<p>
                The cpython documentation states that when a channel is to be registered, the parameter passed can be either of two object types:-
            </p>
<ol>
<li>The channels file descriptor</li>
<li>An object which has a <b>fileno()</b> method which returns a file descriptor.</li>
</ol>
<p>
                In the jython implementation of poll objects, a SelectableChannel object is required. Therefore, it is proposed that in jython the same model as cpython be adopted, with the term <b>file descriptor</b> replaced by the term <b>SelectableChannel</b>.
            </p>
<p>
                If an object is registered which is an instance of <b>java.nio.channels.SelectableChannel</b> or any of subclasses, then that object represents the channel which is to be watched.
            </p>
<p>
                If the object is <b>not</b> such an instance, then the objects <b>fileno()</b> method should be called, to attempt retrieve a SelectableChannel. If the method does not exist, then the object is not watchable, and an exception should be raised. If the method returns an object, but that object is not a SelectableChannel, the channel is unwatchable and an exception should be raised. If the method returns an object and that object is a SelectableChannel, then that object is the channel to be watched.
            </p>
<p>
                Suggested code for this purpose is
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> poll:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _getselectable<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, channel<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>channel, java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">SelectableChannel</span><span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> channel
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">hasattr</span><span style="color: black;">&#40;</span>channel, <span style="color: #483d8b;">'fileno'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #008000;">callable</span><span style="color: black;">&#40;</span><span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>channel, <span style="color: #483d8b;">'fileno'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
                result = <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>channel, <span style="color: #483d8b;">'fileno'</span><span style="color: black;">&#41;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>result, java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">SelectableChannel</span><span style="color: black;">&#41;</span>:
                    <span style="color: #ff7700;font-weight:bold;">return</span> result
                <span style="color: #ff7700;font-weight:bold;">else</span>:
                    <span style="color: #ff7700;font-weight:bold;">raise</span> JynioException<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Channel '</span><span style="color: #66cc66;">%</span>s<span style="color: #483d8b;">' is not a watchable channel'</span> <span style="color: #66cc66;">%</span> channel<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #ff7700;font-weight:bold;">raise</span> JynioException<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Channel '</span><span style="color: #66cc66;">%</span>s<span style="color: #483d8b;">' is not a watchable channel'</span> <span style="color: #66cc66;">%</span> channel<span style="color: black;">&#41;</span></pre></div></div>

<p>
                A typical call sequence using the register function is given here. Note that this code should work in both cpython and jython.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">select</span>
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">socket</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
pobj = <span style="color: #dc143c;">select</span>.<span style="color: black;">poll</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
s = <span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span>AF_INET, SOCK_STREAM<span style="color: black;">&#41;</span>
s.<span style="color: black;">setblocking</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
s.<span style="color: black;">connect</span><span style="color: black;">&#40;</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'www.python.org'</span>, <span style="color: #ff4500;">80</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
pobj.<span style="color: black;">register</span><span style="color: black;">&#40;</span>s, <span style="color: #dc143c;">select</span>.<span style="color: black;">POLLIN</span> | <span style="color: #dc143c;">select</span>.<span style="color: black;">POLLOUT</span><span style="color: black;">&#41;</span>
readychans = pobj.<span style="color: black;">poll</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<hr /><a name="datastructs"></a><br />
<h2>Internal data of the poll object</h2>
<p>
                The poll object needs to keep track of the channels which it is watching. In java, java.nio.channels.Selector objects are used to watch multiple channels. Therefore, it is proposed to have a Selector as an instance variable of every poll object, against which all channels can be registered. The Selector should be created at __init__ time of the poll object, like so.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> poll:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: black;">&#91;</span>....<span style="color: black;">&#93;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">selector</span> = java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">Selector</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: black;">&#91;</span>....<span style="color: black;">&#93;</span></pre></div></div>

<p>
                In the cpython model, a channel <b>is registered</b> with a watcher, whereas in java the channel <b>registers itself</b> with the watcher, returning a SelectionKey representing the registration. This means that when a Selector returns a set of channels that are ready for I/O operations, it will return a set of SelectionKeys. But we need to return the original object back to the programmer that they passed in. So we need a mechanism for mapping SelectionKeys back to original parameters.
            </p>
<p>
                When a SelectionKey is returned from a Selector, the channel corresponding to that key can be obtained through the <b>channel()</b> method. Further, since we know that that channel represents a socket, we can retrieve the users original socket through the <b>socket()</b> method. However, if we do not keep track of the users original object, then we cannot know from the SelectionKey which object the user passed in. Therefore, we need to keep track of the original object the user passed into the function. This could be done with a simple dictionary which is internal to the jython poll object. The key for the dictionary would be the SelectableChannel corresponding to the channel.
            </p>
<p>
                When a channel is <b>unregistered</b> with a poll object, the channel should no longer be watched. The java model, however, is slightly different than what might be expected (surprise!): instead of a watcher unregistering a watchable channel, the key representing the registration of a watchable channel with a watcher must be cancelled! Therefore, it will be necessary to keep track of all SelectionKeys generated by the Selectable/Selector/registration process, so that they can be cancelled later.
            </p>
<p>
                It is proposed to store this information in a simple python dictionary which is internal to the jython poll object. The key for the dictionary would be the SelectableChannel corresponding to the channel. The values in the dictionary should contain the following.
            </p>
<ol>
<li>
<b>userobject</b>, i.e. the object which the user passed into the registration function, and which should be returned to them when the channel is ready for I/O.</li>
<li>
<b>SelectionKey</b>, i.e. the SelectionKey representing the registration with the internal Selector object. This is so that the registration can be cancelled at a later stage.</li>
</ol>
<p>
                This dictionary should created at __init__ time of the poll object, and modified at every channel registration and unregistration. The following are suggested algorithms for the poll object. Note that, according to the cpython 2.3 documentation, it is <b>not</b> an error for a channel to be registered twice with a poll object, but any attempt to unregister a channel that was never registered should result in a KeyError. Note that this code ignores the need for event flags, the implementation of which will be discussed below.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> poll:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">selector</span> = java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">Selector</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
&nbsp;
     <span style="color: #ff7700;font-weight:bold;">def</span> _getselectable<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, userobject<span style="color: black;">&#41;</span>:
         <span style="color: #808080; font-style: italic;"># Implementation which seeks a SelectableChannel object given above</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> register<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, userobject, flags<span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># Flags ignored for now</span>
        channel = <span style="color: #008000;">self</span>._getselectable<span style="color: black;">&#40;</span>userobject<span style="color: black;">&#41;</span>
        selectionkey = channel.<span style="color: black;">register</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">selector</span>, flags<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span><span style="color: black;">&#91;</span>channel<span style="color: black;">&#93;</span> = <span style="color: black;">&#40;</span>userobject, selectionkey<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> unregister<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, userobject<span style="color: black;">&#41;</span>:
        channel = <span style="color: #008000;">self</span>._getselectable<span style="color: black;">&#40;</span>userobject<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span><span style="color: black;">&#91;</span>channel<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">cancel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">del</span> <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span><span style="color: black;">&#91;</span>channel<span style="color: black;">&#93;</span></pre></div></div>

<hr /><a name="flags"></a><br />
<h2>Mapping cpython event flags to java interest ops</h2>
<p>
                When a channel is registered with a watcher, the programmer defines a set of events in which they are interested. In cpython, this is done through OR&#8217;ing bitmasks containing the following possible values
            </p>
<table border="1">
<tr>
<th>Flag</th>
<th>Meaning</th>
</tr>
<tr class="tabodd">
<td>POLLIN</td>
<td>Check whether the channel has data ready for reading</td>
</tr>
<tr class="tabeven">
<td>POLLOUT</td>
<td>Check whether the channel is ready for writing data</td>
</tr>
<tr class="tabodd">
<td>POLLPRI</td>
<td>Check whether there is <b>Out-Of-Band</b> data present on this channel.</td>
</tr>
</table>
<p>
                The following are important to note
            </p>
<ol>
<li>Cpython does not have an event flag to represent a <b>CONNECT</b> event. Instead, a client socket is known to be connected when it is ready for writing, i.e. a <b>POLLOUT</b> event is generated.</li>
<li>Cpython does not have an event flag to represent a <b>ACCEPT</b> event, i.e. that a server socket accept() would not block if called, and would return a new socket. Instead, a server socket is known to be ready to accept when it is ready for reading, i.e. a <b>POLLIN</b> event is generated.</li>
<li>Note the above seems only to be documented in the <a href="http://www.python.org/doc/current/lib/module-asyncore.html">cpython documentation for the asyncore module</a>. It is also interesting to note that the asyncore module has reverse-engineered its own <b>pseudo-events</b> to represent the <b>CONNECT</b> and <b>ACCEPT</b> events.</li>
</ol>
<p>
                Java also uses a OR&#8217;ed bitmasks of flags to represent the sert of events that is of interest on the channel. Java defines the following constants in the java.nio.channels.SelectionKey object.
            </p>
<table border="1">
<tr>
<th>Flag</th>
<th>Meaning</th>
</tr>
<tr class="tabodd">
<td>OP_ACCEPT</td>
<td>Check whether the server socket channel is ready for accepting. Server socket channels support this event only! They do not support OP_READ!</td>
</tr>
<tr class="tabeven">
<td>OP_CONNECT</td>
<td>Check whether the client socket channel is connected</td>
</tr>
<tr class="tabodd">
<td>OP_READ</td>
<td>Check whether the channel has data ready for reading</td>
</tr>
<tr class="tabeven">
<td>OP_WRITE</td>
<td>Check whether the channel is ready for writing data</td>
</tr>
</table>
<p>
                Obviously, this presents some difficulties, since there are discrepancies between the event flags that are used by cpython and java. Cpython uses the POLLIN flag to represent two events that are represented by separate flags in java: OP_ACCEPT and OP_READ. Similarly, cpython uses the POLLOUT flag to represent both the java events OP_CONNECT and OP_WRITE. There is no way in cpython to specify the <b>CONNECT</b> or <b>ACCEPT</b> events, but these are required by Java. Conundrum!
            </p>
<p>
                A naive solution to this problem might be to attempt to set both java flags as being of interest when the relevant cpython flag is specified. For example, use both event mask <b>OP_READ | OP_ACCEPT</b> when the python mask <b>POLLIN</b> is specified. However, this may result in error, since OP_ACCEPT is only a valid flag on server socket channels: it would probably generate an IllegalArgumentException if used on a client socket (see the <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectionKey.html#interestOps(int)">documentation for the SelectionKey.interestOps()</a> method for more information. As mentioned on that page, if an event flag is not present in the mask of <b>valid operations</b> on that channel (as determined by the <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectableChannel.html#validOps()">SelectableChannel.validOps()</a> method, then an exception is raised.
            </p>
<p>
                Therefore, a proposed solution is to only add these <b>implied</b> java events when they are present in the validOps mask for the channel being registered. Code to carry out this proposed mapping is as follows
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">SelectionKey</span> <span style="color: #ff7700;font-weight:bold;">import</span> OP_ACCEPT, OP_CONNECT, OP_WRITE, OP_READ
&nbsp;
POLLIN   = <span style="color: #ff4500;">1</span>
POLLOUT  = <span style="color: #ff4500;">2</span>
POLLPRI  = <span style="color: #ff4500;">4</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> poll:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> register<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, channel, mask<span style="color: black;">&#41;</span>:
        jmask = <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> mask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> POLLIN:
            <span style="color: #808080; font-style: italic;"># Note that OP_READ is NOT a valid event on server socket channels.</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> channel.<span style="color: black;">validOps</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_ACCEPT:
                jmask = OP_ACCEPT
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                jmask = OP_READ
        <span style="color: #ff7700;font-weight:bold;">if</span> mask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> POLLOUT:
            jmask |= OP_WRITE
            <span style="color: #ff7700;font-weight:bold;">if</span> channel.<span style="color: black;">validOps</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_CONNECT:
                jmask |= OP_CONNECT
        <span style="color: black;">&#91;</span>....<span style="color: black;">&#93;</span></pre></div></div>

<p>
            Note that the absence of the python POLLPRI constant is discussed below.
        </p>
<p>
            Combining this code with the code given above, this gives a final definition of the poll object (minus the definition of the poll() method) as follows.
        </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>
<span style="color: #ff7700;font-weight:bold;">from</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">SelectionKey</span> <span style="color: #ff7700;font-weight:bold;">import</span> OP_ACCEPT, OP_CONNECT, OP_WRITE, OP_READ
&nbsp;
<span style="color: #808080; font-style: italic;"># These values should be checked in the cpython implementation.</span>
&nbsp;
POLLIN   = <span style="color: #ff4500;">1</span>
POLLOUT  = <span style="color: #ff4500;">2</span>
POLLPRI  = <span style="color: #ff4500;">4</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> poll:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">selector</span> = java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">Selector</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
&nbsp;
     <span style="color: #ff7700;font-weight:bold;">def</span> _getselectable<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, userobject<span style="color: black;">&#41;</span>:
         <span style="color: #808080; font-style: italic;"># Implementation which seeks a SelectableChannel object given above</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> register<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, userobject, mask<span style="color: black;">&#41;</span>:
        jmask = <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> mask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> POLLIN:
            <span style="color: #808080; font-style: italic;"># Note that OP_READ is NOT a valid event on server socket channels.</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> channel.<span style="color: black;">validOps</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_ACCEPT:
                jmask = OP_ACCEPT
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                jmask = OP_READ
        <span style="color: #ff7700;font-weight:bold;">if</span> mask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> POLLOUT:
            jmask |= OP_WRITE
            <span style="color: #ff7700;font-weight:bold;">if</span> channel.<span style="color: black;">validOps</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_CONNECT:
                jmask |= OP_CONNECT
        channel = <span style="color: #008000;">self</span>._getselectable<span style="color: black;">&#40;</span>userobject<span style="color: black;">&#41;</span>
        selectionkey = channel.<span style="color: black;">register</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">selector</span>, jmask<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span><span style="color: black;">&#91;</span>channel<span style="color: black;">&#93;</span> = <span style="color: black;">&#40;</span>userobject, selectionkey<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> unregister<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, userobject<span style="color: black;">&#41;</span>:
        channel = <span style="color: #008000;">self</span>._getselectable<span style="color: black;">&#40;</span>userobject<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span><span style="color: black;">&#91;</span>channel<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">cancel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">del</span> <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span><span style="color: black;">&#91;</span>channel<span style="color: black;">&#93;</span></pre></div></div>

<hr /><a name="poll"></a><br />
<h2>An implementation of the poll method</h2>
<p>
                We are now in a position to define the <b>poll()</b> method of poll objects. The return value from this function should be a list of tuples, containing (channel, event mask), where <b>event mask</b> has bits set for all events that occurred on the channel. Since the event mask returned from the internal java.nio.channels.Selector object will possibly contain the extended java events OP_ACCEPT and OP_CONNECT, these should be mapped to the python events POLLOUT and POLLIN respectively.
            </p>
<p>
                The cpython <b>poll.poll()</b> method takes a timeout parameter, which means different things depending on its value. Java uses separate methods to represent these different timeout scenarios. The mapping from one to the other is given in this table.
            </p>
<table border="1">
<tr>
<th>Timeout value</th>
<th>Cpython meaning</th>
<th>Java equivalent</th>
</tr>
<tr class="tabodd">
<td>None</td>
<td>The poll call is to block until at least one channel is ready for operation.</td>
<td><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/Selector.html#select()">Selector.select()</a></td>
</tr>
<tr class="tabeven">
<td>Negative value</td>
<td>Same as timeout value of None</td>
<td><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/Selector.html#select()">Selector.select()</a></td>
</tr>
<tr class="tabodd">
<td>Positive value</td>
<td>The value gives the timeout value <b>in millseconds</b>.</td>
<td><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/Selector.html#select(long)">Selector.select(long)</a></td>
</tr>
<tr class="tabeven">
<td>Zero</td>
<td>The value gives a timeout value of zero milliseconds.</td>
<td><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/Selector.html#selectNow()">Selector.selectNow()</a></td>
</tr>
</table>
<p>
                Therefore, different methods of the internal Selector object will have to be called, depending on the timeout value specified.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> poll:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> poll<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, timeout=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> timeout <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span> <span style="color: #ff7700;font-weight:bold;">or</span> timeout <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">0</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">selector</span>.<span style="color: #dc143c;">select</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> timeout == <span style="color: #ff4500;">0</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">selector</span>.<span style="color: black;">selectNow</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #808080; font-style: italic;"># No multiplication required: both cpython and java use millisecond timeouts</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">selector</span>.<span style="color: #dc143c;">select</span><span style="color: black;">&#40;</span>timeout<span style="color: black;">&#41;</span>
        selectedkeys = <span style="color: #008000;">self</span>.<span style="color: black;">selector</span>.<span style="color: black;">selectedKeys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># is this thread-safe?</span>
        results = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> k <span style="color: #ff7700;font-weight:bold;">in</span> selectedkeys: <span style="color: #808080; font-style: italic;"># Naive implementation, returned list is actually a java.util.Set</span>
            jmask = k.<span style="color: black;">readyOps</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            pymask = <span style="color: #ff4500;">0</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> jmask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_READ: pymask |= POLLIN
            <span style="color: #ff7700;font-weight:bold;">if</span> jmask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_WRITE: pymask |= POLLOUT
            <span style="color: #ff7700;font-weight:bold;">if</span> jmask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_ACCEPT: pymask |= POLLIN
            <span style="color: #ff7700;font-weight:bold;">if</span> jmask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_CONNECT: pymask |= POLLOUT
            <span style="color: #808080; font-style: italic;"># Now return the original userobject, and the return event mask</span>
            <span style="color: #808080; font-style: italic;"># A python 2.2 generator would be sweet here</span>
            results.<span style="color: black;">append</span><span style="color: black;">&#40;</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span><span style="color: black;">&#91;</span>k.<span style="color: black;">channel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, pymask<span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> results</pre></div></div>

<hr /><a name="outofband"></a><br />
<h2>How to deal with Out-Of-Band data</h2>
<p>
                In cpython, it is possible to check for the presence of <b>Out-Of-Band</b> data on a channel. <a href="http://www.listproc.bucknell.edu/archives/netbook/200104/msg00003.html">Out-of-Band</a> data, also known as <b>priority</b> data or <b>urgent</b> data, is a TCP feature whereby bytes can be sent on a socket which bypass the normal sequencing restrictions imposed on data sent through a socket.
            </p>
<p>
            	However, although this is a built-in feature of TCP sockets, such out-of-band data is rarely used in actual protocol implementations. Nonetheless, there may be software out there which uses this facility. The readiness status for presence of this data is checked by passing the flag <b>POLLPRI</b> when registering the channel.
            </p>
<p>
                Currently, the java.nio non-blocking APIs seem to have minimal support for Out-Of-Band data. <b>There are no events masks with which one can register interest in such priority data</b>. This is confirmed on the <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html#setOOBInline(boolean)">documentation page for java.net.Socket.setOOBInline() method</a>, which says: &#8220;<i>Note, only limited support is provided for handling incoming urgent data. In particular, no notification of incoming urgent data is provided and there is no capability to distinguish between normal data and urgent data unless provided by a higher level protocol</i>&#8220;.
            </p>
<p>
                Because of this lack of support for priority/urgent data on the java platform, it is proposed that this form of processing <b>not be supported</b> in this module. If the programmer requires the use of urgent data with jython, i.e. on the java platform, then they will probably be sophisticated enough to bypass this implementation of the select module in jython, and go direct to the java API. A consequent question is whether POLLPRI flags should simply be ignored when used, or should raise an UnsupportedOperation exception.
            </p>
<p>
                If this is deemed to be an unacceptable compromise, then I have no solution to propose for the problem.
            </p>
<hr /><a name="select"></a><br />
<h2>Implementing the select function using poll objects.</h2>
<p>
                Now that we have finished the implementation of poll objects, we can use them to implement the select function, also in the cpython select module.
            </p>
<p>
                The only complexity is that the select function takes separate lists for channels that are to be examined for read and write events. It might be required that the user wants to watch a channel for both read and write events, so a given channel might be present in both lists. This means that if a channel is given in both lists, it must only be registered once with the selector object, using an event mask that checks for both READ and WRITE events.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #dc143c;">select</span> <span style="color: black;">&#40;</span> read_fd_list, write_fd_list, outofband_fd_list<span style="color: black;">&#41;</span>:
	<span style="color: #808080; font-style: italic;"># First create a poll object to do the actual watching.</span>
	pobj = poll<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	<span style="color: #808080; font-style: italic;"># Check the read list</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> fd <span style="color: #ff7700;font-weight:bold;">in</span> read_fd_list:
		mask = POLLIN
		<span style="color: #ff7700;font-weight:bold;">if</span> fd <span style="color: #ff7700;font-weight:bold;">in</span> write_fd_list:
			mask |= POLLOUT
		pobj.<span style="color: black;">register</span><span style="color: black;">&#40;</span>fd, mask<span style="color: black;">&#41;</span>
	<span style="color: #808080; font-style: italic;"># And now the write list</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> fd <span style="color: #ff7700;font-weight:bold;">in</span> write_fd_list:
		<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> fd <span style="color: #ff7700;font-weight:bold;">in</span> read_fd_list: <span style="color: #808080; font-style: italic;"># fds in both have already been registered.</span>
			pobj.<span style="color: black;">register</span><span style="color: black;">&#40;</span>fd, POLLOUT<span style="color: black;">&#41;</span>
	results = poll.<span style="color: black;">poll</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	<span style="color: #808080; font-style: italic;"># Now start preparing the results</span>
	read_ready_list, write_ready_list, oob_ready_list = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> fd, mask <span style="color: #ff7700;font-weight:bold;">in</span> results:
		<span style="color: #ff7700;font-weight:bold;">if</span> mask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> POLLIN:
			read_ready_list.<span style="color: black;">append</span><span style="color: black;">&#40;</span>fd<span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">if</span> mask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> POLLOUT:
			write_ready_list.<span style="color: black;">append</span><span style="color: black;">&#40;</span>fd<span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">return</span> read_ready_list, write_ready_list, oob_ready_list</pre></div></div>

<hr /><a name="untested"></a><br />
<h2>Complete but untested code based on these notes.</h2>
<p>
				The following code <b>should</b> be a complete implementation of the cpython select module, in jython, using java APIs. However, the following are important points
            </p>
<ol>
<li>
<b>Will not work without socket mods</b>. In order for this code to work, a number of modifications would have to be made to the <a href="/asynchronous-networking-for-jython-the-socket-module/">jython socket module</a>. I currently have no plans to make these modifications: I can&#8217;t afford the time. Maybe in a few months.</li>
<li>
<b>Code is completely untested</b>. This code has only been tested for correct syntax. It has <b>never</b> even been run.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/asynchronous-networking-for-jython-the-select-module/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous networking for jython: the asyncore module</title>
		<link>http://jython.xhaus.com/asynchronous-networking-for-jython-the-asyncore-module/</link>
		<comments>http://jython.xhaus.com/asynchronous-networking-for-jython-the-asyncore-module/#comments</comments>
		<pubDate>Fri, 26 Dec 2003 21:00:28 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=117</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>Over the Christmas holidays in 2003, I wrote a design for how <a href="http://en.wikipedia.org/wiki/Asynchronous_I/O">Asynchronous Socket I/O</a> might be implemented in jython, using <a href="http://java.sun.com/j2se/1.4.2/docs/guide/nio/">java.nio</a>. 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.</p>
<p>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.</p>
<ol>
<li>
<a href="/asynchronous-networking-for-jython-overview/">Overview</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-socket-module/">Socket module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-select-module/">Select module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-asyncore-module/">Asyncore module</a>
</li>
</ol>
<p>For documentation on how to use the jython&#8217;s asynchronous socket I/O, see the documentation for the <a href="http://wiki.python.org/jython/NewSocketModule">socket</a>, <a href="http://wiki.python.org/jython/SelectModule">select</a>, <a href="http://www.python.org/doc/2.5/lib/module-asyncore.html">asyncore</a>, and <a href="http://www.python.org/doc/2.5/lib/module-asynchat.html">asynchat</a> modules.</p>
<p><span id="more-117"></span><br />
<hr /><a name="intro"></a><br />
<h2>Introduction</h2>
<p>
				The purpose of this document is to discuss the implementation of the <a href="http://www.python.org/doc/current/lib/module-asyncore.html">cpython asycnore module</a> in jython.
			</p>
<p>
				The purpose of the asyncore module is to add the last piece of the puzzle in asynchronous processing: <b>the dispatcher</b>. A dispatcher is responsible for watching multiple registered channels. When a readiness event occurs on any channel, the dispatcher calls special events of a handler object associated with each channel.
			</p>
<p>
				Important points to note about the existing cpython asyncore module are as follows.
			</p>
<ol>
<li>It is written pure python.</li>
<li>It uses only the interface defined by the cpython select module.</li>
<li>It recreates both the <b>ACCEPT</b> and <b>CONNECT</b> events, even though the cpython select module &#8220;hides&#8221; these events as <b>POLLIN</b> and <b>POLLOUT</b> events.</li>
</ol>
<p>
				There are three main strategies that can be adopted for implementing the asyncore module, along with pros and cons. These are listed in the sections below.
			</p>
<hr /><a name="existing"></a><br />
<h2>Use the existing cpython asyncore module</h2>
<p>
				The simplest and quickest option for providing asyncore support in jython is to use the existing cpython module.  The advantages of this approach include
			</p>
<ol>
<li>No new code need be written</li>
<li>Existing code is widely used, and thus well tested.</li>
</ol>
<p>The disadvantages are</p>
<ol>
<li>Potential for error because of the possibility of different semantics of <b>ACCEPT</b> and <b>CONNECT</b> events on cpython vs. java (on multiple platforms).</li>
<li>Mildly inefficient, because of all the mask translation and dictionary lookups</li>
<li>Existing code is messy because of varying platform support for the <b>select.select()</b> and <b>select.poll()</b> objects in cpython.</li>
</ol>
<hr /><a name="jythonrewrite"></a><br />
<h2>Write a jython specific module, using jython</h2>
<p>
				Another approach is write a jython specific asyncore module, written in jython, but directly using the java.nio APIs. There is quite a close correlation between the models in the cpython asyncore module and java.nio.channels.Selector objects. It is possible to write a more efficient asyncore implemenation by using the java APIs directly. The advantanges of this approach are
			</p>
<ol>
<li>Can be more robust because of java&#8217;s explicit support for <b>ACCEPT</b> and <b>CONNECT</b> events, which can be directly translated to the relevant &#8220;dispatcher&#8221; events.</li>
<li>Can be slightly more efficient, because it avoids a layer of calls to jython implemented <a href="/asynchronous-networking-for-jython-the-select-module/">poll objects</a>.</li>
<li>Asyncore model maps directly onto semantics of a java.nio.channels.Selector (even more than cpython)</li>
<li>&#8220;Dispatcher&#8221; objects can be registered as <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectionKey.html#attach(java.lang.Object)">attached objects</a> to the java.nio.channels.SelectionKeys that represent them. This would make them directly available to the <b>asyncore.loop()</b> function (which would receive a set of java.nio.channels.SelectionKeys, each having the dispatcher as an attachment, which avoids the dictionary lookups involved in poll objects.</li>
<li>Can easily be translated to java later on.</li>
</ol>
<p>The disadvantages are</p>
<ol>
<li>New code needs to be written. Not too much though.</li>
<li>Extensive testing will have to be done to ensure that the new module implements the precise contract of the cpython asyncore module.</li>
</ol>
<p>
				TBD: Must write sample code for a jython asyncore module.
			</p>
<hr /><a name="rewritejava"></a><br />
<h2>Write jython specific module, using java</h2>
<p>
				The last major approach is to, as above, write a jython specific module, but in java. However, this is unlikely to the optimal approach, at least in the short term. Advantages include
			</p>
<ol>
<li>Best possible efficiency</li>
</ol>
<p>The disadvantages are</p>
<ol>
<li>A lot of hard work!</li>
<li>The java/jython object model is likely to change soon.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/asynchronous-networking-for-jython-the-asyncore-module/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
