<?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>schmichael&#039;s blog &#187; Python</title>
	<atom:link href="http://blog.schmichael.com/category/technology/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.schmichael.com</link>
	<description>good good study, day day up</description>
	<lastBuildDate>Sat, 05 Nov 2011 23:13:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>MemoryMapFile Convenience Class for Python</title>
		<link>http://blog.schmichael.com/2011/09/05/memorymapfile-convenience-class-for-python/</link>
		<comments>http://blog.schmichael.com/2011/09/05/memorymapfile-convenience-class-for-python/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 05:54:25 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[mmap]]></category>

		<guid isPermaLink="false">http://blog.schmichael.com/?p=968</guid>
		<description><![CDATA[My obsession with mmap hasn&#8217;t died, but while Python&#8217;s mmap module is a wonderful low level library it&#8217;s a bit hard for a newcomer to use properly. I&#8217;ve started toying with a convenience wrapper class for mmap.mmap (at least the &#8230; <a href="http://blog.schmichael.com/2011/09/05/memorymapfile-convenience-class-for-python/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>My <a href="http://blog.schmichael.com/2011/05/15/sharing-python-data-between-processes-using-mmap/">obsession</a> with <a href="http://en.wikipedia.org/wiki/Mmap">mmap</a> hasn&#8217;t died, but while <a href="http://docs.python.org/library/mmap">Python&#8217;s mmap module</a> is a wonderful low level library it&#8217;s a bit hard for a newcomer to use properly.</p>
<p>I&#8217;ve started toying with a convenience wrapper class for <code>mmap.mmap</code> (at least the Unix version):<br />
<script src="https://gist.github.com/1196686.js?file=memorymap.py"></script></p>
<p>My original goal was to automatically <a href="http://docs.python.org/library/mmap#mmap.resize">grow</a> the mmap whenever the user attempts to write beyond the current size of the mmap file, but that&#8217;s going to take carefully wrapping quite a few methods (<code>write</code>, <code>__setitem__</code>, and maybe get/read methods too).</p>
<p>If it becomes useful, I may use it in <a href="https://github.com/schmichael/mmstats">mmstats</a>.</p>
<p>Feedback welcome!</p>
<p><strong>Update:</strong> Discovered the hard way (segfaults) that resizing mmaps is tricky: the region can be moved but data will be copied. However, any existing pointers (from ctypes.<type>.from_buffer in my case) will now point to freed memory and segfault upon use.</p>
<p>tl;dr &#8211; If at all possible, precompute the size of your mmap before using it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2011/09/05/memorymapfile-convenience-class-for-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sharing Python data between processes using mmap</title>
		<link>http://blog.schmichael.com/2011/05/15/sharing-python-data-between-processes-using-mmap/</link>
		<comments>http://blog.schmichael.com/2011/05/15/sharing-python-data-between-processes-using-mmap/#comments</comments>
		<pubDate>Mon, 16 May 2011 04:28:29 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[ctypes]]></category>
		<category><![CDATA[mmap]]></category>
		<category><![CDATA[struct]]></category>

		<guid isPermaLink="false">http://blog.schmichael.com/?p=947</guid>
		<description><![CDATA[I&#8217;ve been toying with an idea of exposing statistics for a Python application via shared memory to keep the performance impact on the application as low as possible. The goal being an application could passively expose a number of metrics &#8230; <a href="http://blog.schmichael.com/2011/05/15/sharing-python-data-between-processes-using-mmap/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been toying with an idea of exposing statistics for a Python application via shared memory to keep the performance impact on the application as low as possible. The goal being an application could passively expose a number of metrics that could either be periodically polled via <a href="http://munin-monitoring.org/">munin</a>/<a href="http://www.icinga.org/">Icinga</a>/etc plugins or interactive tools when diagnosing issues on a system.</p>
<p>But first things first: I need to put data into <a href="http://en.wikipedia.org/wiki/Shared_memory">shared memory</a> from Python. <a href="http://en.wikipedia.org/wiki/Mmap">mmap</a> is an excellent widely-implemented POSIX system call for creating a shared memory space backed by an on-disk file.</p>
<p>Usually in the UNIX world you have 2 ways of accessing/manipulating data: memory addresses or streams (files). Manipulating data via memory addresses means <a href="http://en.wikipedia.org/wiki/Pointer_%28computing%29">pointers</a>, offsets, <a href="http://en.wikipedia.org/wiki/Malloc">malloc/free</a>, etc. Stream interfaces manipulate data via <a href="http://en.wikipedia.org/wiki/System_call">read/write/seek system calls</a> for files and <a href="http://en.wikipedia.org/wiki/Berkeley_sockets">send/recv/etc for sockets</a>.</p>
<p>mmap gives you both interfaces. A memory mapped file can be manipulated via read/write/seek or by directly accessing its mapped memory region. The advantage of the latter is that this memory region is in userspace &#8212; meaning you can manipulate a file without incurring the overhead of write system calls for every manipulation.</p>
<p>Anyway, enough exposition, let&#8217;s see some code. <small>(Despite mmap&#8217;s nice featureset, I&#8217;m only using it as a simple memory sharing mechanism anyway.)</small> The following code shares a tiny bit of data between 2 Python processes using the excellent <a href="http://docs.python.org/library/mmap">mmap module in the stdlib</a>. <code>a.py</code> writes to the memory mapped region, and <code>b.py</code> reads the data out. <a href="http://docs.python.org/library/ctypes">ctypes</a> allows for an easy way to create values in a memory mapped region and manipulate them like &#8220;normal&#8221; Python objects.</p>
<p><em>These code samples were written using Python 2.7 on Linux. They should work fine on any POSIX system, but Windows users will have to change the mmap calls to match the Windows API.</em></p>
<p><strong>a.py</strong></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #ff7700;font-weight:bold;">import</span> ctypes
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">mmap</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">struct</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># Create new empty file to back memory map on disk</span>
    fd = <span style="color: #dc143c;">os</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/tmp/mmaptest'</span>, <span style="color: #dc143c;">os</span>.<span style="color: black;">O_CREAT</span> | <span style="color: #dc143c;">os</span>.<span style="color: black;">O_TRUNC</span> | <span style="color: #dc143c;">os</span>.<span style="color: black;">O_RDWR</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Zero out the file to insure it's the right size</span>
    <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span>fd, <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\x</span>00'</span> <span style="color: #66cc66;">*</span> <span style="color: #dc143c;">mmap</span>.<span style="color: black;">PAGESIZE</span><span style="color: black;">&#41;</span> == <span style="color: #dc143c;">mmap</span>.<span style="color: black;">PAGESIZE</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Create the mmap instace with the following params:</span>
    <span style="color: #808080; font-style: italic;"># fd: File descriptor which backs the mapping or -1 for anonymous mapping</span>
    <span style="color: #808080; font-style: italic;"># length: Must in multiples of PAGESIZE (usually 4 KB)</span>
    <span style="color: #808080; font-style: italic;"># flags: MAP_SHARED means other processes can share this mmap</span>
    <span style="color: #808080; font-style: italic;"># prot: PROT_WRITE means this process can write to this mmap</span>
    buf = <span style="color: #dc143c;">mmap</span>.<span style="color: #dc143c;">mmap</span><span style="color: black;">&#40;</span>fd, <span style="color: #dc143c;">mmap</span>.<span style="color: black;">PAGESIZE</span>, <span style="color: #dc143c;">mmap</span>.<span style="color: black;">MAP_SHARED</span>, <span style="color: #dc143c;">mmap</span>.<span style="color: black;">PROT_WRITE</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Now create an int in the memory mapping</span>
    i = ctypes.<span style="color: black;">c_int</span>.<span style="color: black;">from_buffer</span><span style="color: black;">&#40;</span>buf<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Set a value</span>
    i.<span style="color: black;">value</span> = <span style="color: #ff4500;">10</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># And manipulate it for kicks</span>
    i.<span style="color: black;">value</span> += <span style="color: #ff4500;">1</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">assert</span> i.<span style="color: black;">value</span> == <span style="color: #ff4500;">11</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Before we create a new value, we need to find the offset of the next free</span>
    <span style="color: #808080; font-style: italic;"># memory address within the mmap</span>
    offset = <span style="color: #dc143c;">struct</span>.<span style="color: black;">calcsize</span><span style="color: black;">&#40;</span>i._type_<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># The offset should be uninitialized ('\x00')</span>
    <span style="color: #ff7700;font-weight:bold;">assert</span> buf<span style="color: black;">&#91;</span>offset<span style="color: black;">&#93;</span> == <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\x</span>00'</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Now ceate a string containing 'foo' by first creating a c_char array</span>
    s_type = ctypes.<span style="color: black;">c_char</span> <span style="color: #66cc66;">*</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'foo'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Now create the ctypes instance</span>
    s = s_type.<span style="color: black;">from_buffer</span><span style="color: black;">&#40;</span>buf, offset<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># And finally set it</span>
    s.<span style="color: black;">raw</span> = <span style="color: #483d8b;">'foo'</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'First 10 bytes of memory mapping: %r'</span> <span style="color: #66cc66;">%</span> buf<span style="color: black;">&#91;</span>:<span style="color: #ff4500;">10</span><span style="color: black;">&#93;</span>
    <span style="color: #008000;">raw_input</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Now run b.py and press ENTER'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">print</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Changing i'</span>
    i.<span style="color: black;">value</span> <span style="color: #66cc66;">*</span>= i.<span style="color: black;">value</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Changing s'</span>
    s.<span style="color: black;">raw</span> = <span style="color: #483d8b;">'bar'</span>
&nbsp;
    new_i = <span style="color: #008000;">raw_input</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Enter a new value for i: '</span><span style="color: black;">&#41;</span>
    i.<span style="color: black;">value</span> = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>new_i<span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p><strong>b.py</strong></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;">mmap</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">struct</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># Open the file for reading</span>
    fd = <span style="color: #dc143c;">os</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/tmp/mmaptest'</span>, <span style="color: #dc143c;">os</span>.<span style="color: black;">O_RDONLY</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Memory map the file</span>
    buf = <span style="color: #dc143c;">mmap</span>.<span style="color: #dc143c;">mmap</span><span style="color: black;">&#40;</span>fd, <span style="color: #dc143c;">mmap</span>.<span style="color: black;">PAGESIZE</span>, <span style="color: #dc143c;">mmap</span>.<span style="color: black;">MAP_SHARED</span>, <span style="color: #dc143c;">mmap</span>.<span style="color: black;">PROT_READ</span><span style="color: black;">&#41;</span>
&nbsp;
    i = <span style="color: #008000;">None</span>
    s = <span style="color: #008000;">None</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff4500;">1</span>:
        new_i, = <span style="color: #dc143c;">struct</span>.<span style="color: black;">unpack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'i'</span>, buf<span style="color: black;">&#91;</span>:<span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
        new_s, = <span style="color: #dc143c;">struct</span>.<span style="color: black;">unpack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'3s'</span>, buf<span style="color: black;">&#91;</span><span style="color: #ff4500;">4</span>:<span style="color: #ff4500;">7</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> i <span style="color: #66cc66;">!</span>= new_i <span style="color: #ff7700;font-weight:bold;">or</span> s <span style="color: #66cc66;">!</span>= new_s:
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'i: %s =&gt; %d'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>i, new_i<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'s: %s =&gt; %s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>s, new_s<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Press Ctrl-C to exit'</span>
            i = new_i
            s = new_s
&nbsp;
        <span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p><small>(Note that I cruelly don&#8217;t clean up /tmp/mmaptest after the scripts finished. Consider it a 4KB tax for anyone who runs arbitrary code they found on the Internet without reading it first.)</small></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2011/05/15/sharing-python-data-between-processes-using-mmap/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>signalfd</title>
		<link>http://blog.schmichael.com/2011/02/20/signalfd/</link>
		<comments>http://blog.schmichael.com/2011/02/20/signalfd/#comments</comments>
		<pubDate>Mon, 21 Feb 2011 06:50:07 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.schmichael.com/?p=920</guid>
		<description><![CDATA[This article covers signalfd, a system call only available on Linux. If anyone knows of an equivalent for OSX or BSDs,* please let me know. It&#8217;d be great to create a compatibility layer. Writing asynchronous IO code is fun; handling &#8230; <a href="http://blog.schmichael.com/2011/02/20/signalfd/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>This article covers </em>signalfd<em>, a system call only available on Linux. If anyone knows of an equivalent for OSX or BSDs,<abbrev title="If there's something like signalfd for Windows, I'm sorry but I really couldn't care less.">*</abbrev> please <a href="http://blog.schmichael.com/about-me/">let me know</a>. It&#8217;d be great to create a compatibility layer.</em></p>
<p>Writing asynchronous IO code is fun; handling signals is not. <a href="http://www.kernel.org/doc/man-pages/online/pages/man2/signalfd.2.html">signalfd</a> allows you to move your signal handling code into your main event loop instead of hooking up global handlers and using the featureless <a href="http://docs.python.org/library/signal#signal.set_wakeup_fd">set_wakeup_fd</a> function to break the main loop.</p>
<p>Luckily <a href="https://launchpad.net/python-signalfd">Jean-Paul Calderone had already created a great Python wrapper for the signalfd and sigprocmask system calls</a>. Unfortunately it doesn&#8217;t include a way to parse the siginfo_t structure which contains all the useful information about the signal you&#8217;re handling.</p>
<p>I&#8217;ve added a helper to do just that in a branch:</p>
<p><a href="https://code.launchpad.net/~schmichael/python-signalfd/helpers">https://code.launchpad.net/~schmichael/python-signalfd/helpers</a></p>
<p>A sample program would look like:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">select</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">signal</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> signalfd
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> sigfdtest<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># Catch them all!</span>
    sigs = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> attr <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">dir</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">signal</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> attr.<span style="color: black;">startswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'SIG'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #ff7700;font-weight:bold;">not</span> attr.<span style="color: black;">startswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'SIG_'</span><span style="color: black;">&#41;</span>:
            sigs.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">signal</span>, attr<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    sfd = signalfd.<span style="color: black;">create_signalfd</span><span style="color: black;">&#40;</span>sigs<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Capturing: %r'</span> <span style="color: #66cc66;">%</span> <span style="color: #008000;">sorted</span><span style="color: black;">&#40;</span>sigs<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff4500;">1</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'selecting - pid: %d'</span> <span style="color: #66cc66;">%</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">getpid</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        r = <span style="color: #dc143c;">select</span>.<span style="color: #dc143c;">select</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>sfd<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: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> s <span style="color: #ff7700;font-weight:bold;">in</span> r:
            <span style="color: #ff7700;font-weight:bold;">assert</span> s <span style="color: #ff7700;font-weight:bold;">is</span> sfd, <span style="color: #483d8b;">'Python nicely re-uses the fd instance'</span>
            sig = signalfd.<span style="color: black;">read_signalfd</span><span style="color: black;">&#40;</span>sfd<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">print</span> sig
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    sigfdtest<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>When run you can throw some signals at it:</p>
<pre>
Capturing: [6, 14, 7, 17, 17, 18, 8, 1, 4, 2, 29, 6, 9, 13, 29, 27, 30, 3, 64, 34, 11, 19, 31, 15, 5, 20, 21, 22, 23, 10, 12, 26, 28, 24, 25]
selecting - pid: 6523
^CSIGINT
selecting - pid: 6523
^CSIGINT
selecting - pid: 6523
SIGHUP
selecting - pid: 6523
Killed
</pre>
<p>Of course you&#8217;ll need to use an uninterpretable signal like KILL to exit.</p>
<p><a href="http://bugs.python.org/issue8407">Jean-Paul attempted to get signalfd included in Python 2.7&#8242;s signal module, and it was slated for inclusion in 3.2</a>. However, given that <a href="http://www.python.org/download/releases/3.2/">3.2</a> was just <a href="http://docs.python.org/release/3.2/library/signal">released without it</a>, I&#8217;m guessing the attempt to get this functionality into Python&#8217;s stdlib has been forgotten.</p>
<p>Up next: <a href="http://www.kernel.org/doc/man-pages/online/pages/man2/eventfd.2.html">eventfd</a> perhaps?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2011/02/20/signalfd/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Deploying Python behind Nginx Talk Slides</title>
		<link>http://blog.schmichael.com/2011/01/25/deploying-python-behind-nginx-talk-slides/</link>
		<comments>http://blog.schmichael.com/2011/01/25/deploying-python-behind-nginx-talk-slides/#comments</comments>
		<pubDate>Tue, 25 Jan 2011 18:52:13 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[pdxpython]]></category>
		<category><![CDATA[presentation]]></category>
		<category><![CDATA[slides]]></category>
		<category><![CDATA[wsgi]]></category>

		<guid isPermaLink="false">http://blog.schmichael.com/?p=889</guid>
		<description><![CDATA[I gave a talk on deploying Python WSGI apps behind nginx at the Portland Python User Group meeting on January 11th and finally got around to publishing the slides: schmingx. I should mention Jason Kirtland informed me after the meeting &#8230; <a href="http://blog.schmichael.com/2011/01/25/deploying-python-behind-nginx-talk-slides/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I gave a talk on deploying Python WSGI apps behind <a href="http://wiki.nginx.org/">nginx</a> at the <a href="http://wiki.python.org/moin/PortlandPythonUserGroup">Portland Python User Group</a> meeting on January 11th and finally got around to publishing the slides: <a href="https://docs.google.com/present/edit?id=0Ab7GDIugV1qCZGR6c3d6YnJfMTA1aGRtZmJxYzI&#038;hl=en">schmingx</a>.</p>
<p>I should mention <a href="http://discorporate.us/jek/">Jason Kirtland</a> informed me after the meeting that <a href="http://www.fastcgi.com/devkit/doc/fcgi-spec.html">FastCGI</a> supports <a href="http://www.fastcgi.com/devkit/doc/fcgi-spec.html#S3.5">persistent connections (and a host of other features)</a> between a load balancer and backend app servers.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2011/01/25/deploying-python-behind-nginx-talk-slides/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Making Server-Side MongoDB Functions Less Awkward</title>
		<link>http://blog.schmichael.com/2010/01/11/making-server-side-mongodb-functions-less-awkward/</link>
		<comments>http://blog.schmichael.com/2010/01/11/making-server-side-mongodb-functions-less-awkward/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 00:54:19 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[pymongo]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/?p=796</guid>
		<description><![CDATA[I&#8217;ve recently switched my project at work to use MongoDB for the user database and a few other datasets. Currently I don&#8217;t use many JavaScript functions, but when I do I like to store them on the server so that &#8230; <a href="http://blog.schmichael.com/2010/01/11/making-server-side-mongodb-functions-less-awkward/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently switched my project at work to use MongoDB for the user database and a few other datasets.</p>
<p>Currently I don&#8217;t use many JavaScript functions, but when I do I like to store them on the server so that they&#8217;re accessible when I&#8217;m poking around in a console.</p>
<p>I use something similar to the following function to load all of my JS functions onto the server when my app starts:</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;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> pymongo
<span style="color: #ff7700;font-weight:bold;">import</span> pkg_resources
&nbsp;
<span style="color: #808080; font-style: italic;"># Relative to distribution's root</span>
SCRIPT_DIR = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'model'</span>, <span style="color: #483d8b;">'js'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> init_js<span style="color: black;">&#40;</span>db<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'Initializes server-side javascript functions'</span><span style="color: #483d8b;">''</span>
    scripts = <span style="color: #008000;">filter</span><span style="color: black;">&#40;</span>
            <span style="color: #ff7700;font-weight:bold;">lambda</span> f: f.<span style="color: black;">endswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.js'</span><span style="color: black;">&#41;</span>,
            pkg_resources.<span style="color: black;">resource_listdir</span><span style="color: black;">&#40;</span>__name__, SCRIPT_DIR<span style="color: black;">&#41;</span>
        <span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> script <span style="color: #ff7700;font-weight:bold;">in</span> scripts:
        <span style="color: #808080; font-style: italic;"># Name the function after the script name</span>
        func_name, _ = script.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.'</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        script_path = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>SCRIPT_DIR, script<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Create a pymongo Code object</span>
        <span style="color: #808080; font-style: italic;"># otherwise it will be stored as a string</span>
        <span style="color: #dc143c;">code</span> = pymongo.<span style="color: #dc143c;">code</span>.<span style="color: black;">Code</span><span style="color: black;">&#40;</span>
                pkg_resources.<span style="color: black;">resource_string</span><span style="color: black;">&#40;</span>__name__, script_path<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Upsert the function</span>
        db.<span style="color: black;">system</span>.<span style="color: black;">js</span>.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span> <span style="color: #483d8b;">'_id'</span>: func_name, <span style="color: #483d8b;">'value'</span>: <span style="color: #dc143c;">code</span>, <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>However, using server-side functions from Python is awkward at best.  Say I have the JavaScript function:</p>
<p><strong>add.js</strong></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>x<span style="color: #339933;">,</span> y<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> x <span style="color: #339933;">+</span> y<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>To run that function via PyMongo requires wrapping the function call with placeholder parameters in a Code object and passing in values as a dict:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">var1 = <span style="color: #ff4500;">1</span>
var2 = <span style="color: #ff4500;">2</span>
result = db.<span style="color: #008000;">eval</span><span style="color: black;">&#40;</span>pymongo.<span style="color: #dc143c;">code</span>.<span style="color: black;">Code</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'add(a, b)'</span>, <span style="color: black;">&#123;</span><span style="color: #483d8b;">'a'</span>: var1, <span style="color: #483d8b;">'b'</span>: var2,<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> result == <span style="color: #ff4500;">3</span></pre></div></div>

<p><strong>Update:</strong> See <a href="http://michael.susens-schurter.com/blog/2010/01/11/making-server-side-mongodb-functions-less-awkward/comment-page-1/#comment-68027">MongoDB dev Mike Dirolf comment</a> to see a much more concise way of executing server-side functions.</p>
<p>Bearable for simple functions, but having to manually map parameters to values is tiresome and error prone with longer function signatures.</p>
<p>What I wanted was something more natural like:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">var1 = <span style="color: #ff4500;">1</span>
var2 = <span style="color: #ff4500;">2</span>
result = db.<span style="color: black;">add</span><span style="color: black;">&#40;</span>var1, var2<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> result == <span style="color: #ff4500;">3</span></pre></div></div>

<p>I use a simple PyMongo Database object wrapper to make my life easier:</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;">string</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> pymongo.<span style="color: #dc143c;">code</span> <span style="color: #ff7700;font-weight:bold;">import</span> Code
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> ServerSideFunctions<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    <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>, db<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">db</span> = db
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> func_wrapper<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, func<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'Returns a closure for calling a server-side function.'</span><span style="color: #483d8b;">''</span>
        params = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># To keep params ordered</span>
        kwargs = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
        <span style="color: #ff7700;font-weight:bold;">def</span> server_side_func<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>:
            <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'Calls server side function with positional arguments.'</span><span style="color: #483d8b;">''</span>
            <span style="color: #808080; font-style: italic;"># Could be removed with better param generating logic</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>args<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span>.<span style="color: black;">letters</span><span style="color: black;">&#41;</span>:
                <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">TypeError</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s() takes at most %d arguments (%d given)'</span>
                        <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>func, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span>.<span style="color: black;">letters</span><span style="color: black;">&#41;</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>args<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
            <span style="color: #808080; font-style: italic;"># Prepare arguments</span>
            <span style="color: #ff7700;font-weight:bold;">for</span> k, v <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">zip</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span>.<span style="color: black;">letters</span>, args<span style="color: black;">&#41;</span>:
                kwargs<span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span> = v
                params.<span style="color: black;">append</span><span style="color: black;">&#40;</span>k<span style="color: black;">&#41;</span> 
&nbsp;
            <span style="color: #808080; font-style: italic;"># Prepare code object</span>
            <span style="color: #dc143c;">code</span> = Code<span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s(%s)'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>func, <span style="color: #483d8b;">', '</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>params<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, kwargs<span style="color: black;">&#41;</span>
&nbsp;
            <span style="color: #808080; font-style: italic;"># Return result of server-side function</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">db</span>.<span style="color: #008000;">eval</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">code</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> server_side_func
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__getattr__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, func<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'Return a closure for calling server-side function named `func`'</span><span style="color: #483d8b;">''</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">func_wrapper</span><span style="color: black;">&#40;</span>func<span style="color: black;">&#41;</span>
&nbsp;
dbjs = ServerSideFunctions<span style="color: black;">&#40;</span><span style="color: #483d8b;">'foo'</span><span style="color: black;">&#41;</span>
var1 = <span style="color: #ff4500;">1</span>
var2 = <span style="color: #ff4500;">2</span>
result = dbjs.<span style="color: black;">add</span><span style="color: black;">&#40;</span>var1, var2<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> result == <span style="color: #ff4500;">3</span></pre></div></div>

<p>I&#8217;m tempted to monkey-patch PyMongo&#8217;s Database class to add a ServerSideFunctions instance directly as a js attribute, so then I could drop the confusing <code>dbjs</code> variable and just use:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">assert</span> db.<span style="color: black;">js</span>.<span style="color: black;">add</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>,<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">3</span></pre></div></div>

<p>If someone knows of a better way to access server-side MongoDB functions from Python, please let me know!</p>
<p><small>I modified this code to remove code specific to my project, so please let me know if there are errors.</small></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2010/01/11/making-server-side-mongodb-functions-less-awkward/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>lxml vs. ElementTree</title>
		<link>http://blog.schmichael.com/2009/10/14/lxml-vs-elementtree/</link>
		<comments>http://blog.schmichael.com/2009/10/14/lxml-vs-elementtree/#comments</comments>
		<pubDate>Wed, 14 Oct 2009 23:18:31 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[benchmarks]]></category>
		<category><![CDATA[ElementTree]]></category>
		<category><![CDATA[lxml]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/?p=736</guid>
		<description><![CDATA[While lxml has some excellent benchmarks about the speed of lxml.etree vs. ElementTree, I wanted to run some tests that were as close as possible to my own use case (fairly simple multi-megabyte XML files). Here are the results of &#8230; <a href="http://blog.schmichael.com/2009/10/14/lxml-vs-elementtree/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>While lxml has some <a href="http://codespeak.net/lxml/performance.html">excellent benchmarks about the speed of lxml.etree vs. ElementTree</a>, I wanted to run some tests that were as close as possible to my own use case (fairly simple multi-megabyte XML files).</p>
<p>Here are the results of my little test script <a href="http://blog.schmichael.com/files/lxml-v-etree.py-remove-me">lxml-v-etree.py</a> (times are in milliseconds):</p>
<pre>
name           generate | tostring | total | write | parse | find | total
------------------------+----------+-------+-------+-------+------+------
xml.cElementTree    132 |   2430   |  2562 |  2433 |   158 |   58 |   216
xml.cElementTree    112 |   2384   |  2497 |  2387 |   158 |   25 |   183
xml.cElementTree    113 |   2393   |  2507 |  2396 |   161 |   25 |   187
xml.ElementTree     591 |   2571   |  3163 |  2574 |  3613 |   25 |  3638
xml.ElementTree     619 |   2567   |  3187 |  2570 |  3589 |   55 |  3644
xml.ElementTree     609 |   2578   |  3188 |  2581 |  3564 |   55 |  3619
lxml                333 |     75   |   409 |    82 |   200 |    0 |   201
lxml                355 |     93   |   448 |    95 |   182 |   32 |   214
lxml                310 |     94   |   404 |    96 |   156 |   56 |   213
------------------------+----------+-------+-------+-------+------+------
name           generate | tostring | total | write | parse | find | total
------------------------+----------+-------+-------+-------+------+------
</pre>
<p>Note that the first &#8220;total&#8221; is &#8220;generate + tostring&#8221; while the second &#8220;total&#8221; is for the 2 parsing related tests (previous 2 columns summed).</p>
<p>My parsing tests are basically &#8220;etree.parse&#8221; and then running &#8220;Element.getchildren()&#8221; 3 times, which is ridiculously simplistic and should probably be ignored.  My writing tests are far more thorough/realistic.</p>
<p>I&#8217;m running Python 2.6.2 with lxml 2.1.5 and libxml2 2.6.32 on Ubuntu 9.04 x86_64.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2009/10/14/lxml-vs-elementtree/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

