<?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; GNU/Linux</title>
	<atom:link href="http://blog.schmichael.com/category/technology/linux/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>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>Ubuntu 9.10 on a Thinkpad T400</title>
		<link>http://blog.schmichael.com/2009/11/11/ubuntu-9-10-on-a-thinkpad-t400/</link>
		<comments>http://blog.schmichael.com/2009/11/11/ubuntu-9-10-on-a-thinkpad-t400/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 06:11:08 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/?p=746</guid>
		<description><![CDATA[I upgraded from Ubuntu 9.04 to 9.10 on my Lenovo Thinkpad T400 about a week ago, and thought I&#8217;d write down some of my impressions. Good news ATI graphics card with proprietary binary driver &#8211; just works (much better than &#8230; <a href="http://blog.schmichael.com/2009/11/11/ubuntu-9-10-on-a-thinkpad-t400/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I upgraded from Ubuntu 9.04 to <a href="http://www.ubuntu.com/products/whatisubuntu/910features">9.10</a> on my Lenovo Thinkpad T400 about a week ago, and thought I&#8217;d write down some of my impressions.</p>
<p><strong>Good news</strong></p>
<ul>
<li>ATI graphics card with proprietary binary driver &#8211; just works (much better than 9.04 as well).</li>
<li>Suspend &#038; hibernate work flawlessly.</li>
<li>Boots fast.</li>
<li>Upgrade worked flawlessly.</li>
<li>Sound (better volume panel!), wifi, USB, network printer, bluetooth (option to turn it on/off!), webcam, etc. all still work.</li>
<li>New theme is nice.</li>
<li>I manually <a href="http://ext4.wiki.kernel.org/index.php/Ext4_Howto#Converting_an_ext3_filesystem_to_ext4">upgraded my filesystem to ext4</a> and <a href="https://wiki.ubuntu.com/KernelTeam/Grub2Testing">grub from version 1 to 2</a>.  It was a bit scary but worked out fine.  Can&#8217;t really feel a difference, but my laptop is mainly a dumb terminal for running web browsers and ssh.
</ul>
<p><strong><a href="http://live.gnome.org/Empathy">Empathy</a></strong></p>
<p>Ubuntu replaced Pidgin with Empathy as the default IM client in Ubuntu 9.10.  I think because Empathy supports voice/video chat and Pidgin doesn&#8217;t? I&#8217;ve used video chat once in my life and that was through Skype on Linux.  It worked great, but it&#8217;s really not a feature I care about.</p>
<p>So for someone like me who doesn&#8217;t care about Empathy&#8217;s singular advantage over Pidgin, Empathy is a major step backward.  At first it was extremely crashy, but a recent update seems to have fixed that.  However, now it mysteriously loses messages.  I&#8217;m a very light IM user, but it would start silently missing messages a few hours into the day every day.</p>
<p>I&#8217;ve switched back to Pidgin and couldn&#8217;t be happier.</p>
<p><strong>Message Notification applet deal</strong></p>
<p>Empathy integrates with the message notification applet deal along with Evolution.  Other apps may as well, but evidently I don&#8217;t use any of them.  My top panel is 75% whitespace, so the singular benefit of Ubuntu&#8217;s consolidated message notification applet was completely lost on me.</p>
<p>So much like Empathy, I removed this specialized applet as well.  I&#8217;m much happier with per-application icons anyway and fail to see what the benefit of consolidating them is (unless you have a really cramped top panel).</p>
<p><strong>New Theme</strong></p>
<p>I like it, but then I installed Chromium.  Now the bold window titles and expansive title bars in Metacity look bulky and antiquated.  Gnome really needs to evolve their window manager and default UI.  Chrome is an excellent example of how to design a compact, minimal, yet still pleasant and intuitive user interface.</p>
<p><strong><a href="https://wiki.ubuntu.com/SoftwareCenter">Ubuntu Software Center</a></strong></p>
<p>What a curious little replacement for the old Add/Remove Applications program.  I think I see the direction they&#8217;re headed, but it definitely feels like rolled out a beta program to replace a perfectly functional and stable one.</p>
<p>The left pane with expansive whitespace and 2 options <em>hints</em> that there might be more categories in the future, but right now it just looks like a mistake.  Like maybe something isn&#8217;t working properly, and I&#8217;m not seeing all the options I should see.</p>
<p>At any rate, I hope Ubuntu adds an App Store that even includes evil proprietary software.  I&#8217;d love to be able to plunk down a few bucks for a game like <a href="http://braid-game.com/">Braid</a> directly from Ubuntu Software Center.  That&#8217;d be great!  Maybe Canonical could even pocket a few pennies and start making Linux-on-the-desktop profitable.  Now I&#8217;m just dreaming though&#8230;</p>
<p><strong>Bottom Line</strong></p>
<p>9.10 is a solid and safe upgrade for any users of previous versions.  Not sure there&#8217;s anything new to win over users from OS X or Windows though.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2009/11/11/ubuntu-9-10-on-a-thinkpad-t400/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>My Gnome 3.0: A Real Web Desktop</title>
		<link>http://blog.schmichael.com/2009/06/02/my-gnome-30-a-real-web-desktop/</link>
		<comments>http://blog.schmichael.com/2009/06/02/my-gnome-30-a-real-web-desktop/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 01:53:51 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[dropbox]]></category>
		<category><![CDATA[gnome]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/?p=648</guid>
		<description><![CDATA[So I missed the stream of What I Want for Christmas Gnome 3.0 by &#8230; a while, but better late than never!* The Win Essentially what I want for Gnome 3.0 is what Tomboy just got: a web interface called &#8230; <a href="http://blog.schmichael.com/2009/06/02/my-gnome-30-a-real-web-desktop/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So I missed the <a href="http://www.google.com/cse?cx=007525575524326405779%3Ac0gv0y410u0&#038;q=gnome+3.0&#038;cof=FORID%3A0">stream of What I Want for <strike>Christmas</strike> Gnome 3.0</a> by &#8230; a while, but better late than never!*</p>
<p><strong>The Win</strong></p>
<p>Essentially what I want for Gnome 3.0 is what <a href="http://automorphic.blogspot.com/2009/05/tomboy-0151-release-brings-new-online.html">Tomboy just got: a web interface</a> called <a href="http://live.gnome.org/Snowy">Snowy</a>.  Part synchronization, part collaboration, all &#8220;cloud&#8221; for those buzzword minded among us.</p>
<p><strong>The Fail</strong></p>
<p>Luckily there&#8217;s already Conduit which I think does the synchronization bit&#8230;  I say &#8220;I think&#8221; because I&#8217;ve never actually gotten Conduit to work.  I drag &#038; drop F-Spot onto the canvas**, neat.  I drag &#038; drop Network to the right of F-Spot, neat.  Now what?  There&#8217;s no configure option for Network.  Heck, there&#8217;s not even a Remove*** for Network.  I right click and select Synchronize in hopes it will prompt me for details, but instead it happily reports synchronization is finished.  <em>Huh?!</em></p>
<p>I poke around in Preferences hoping for guidance on how to sync to another computer over a network.  Wow.  The first tab is fine, but the other 2 tabs are just long lists of text.  Wait a second, if you scroll <em>horizontally</em> to the right in the Data Providers tab you can see a checkbox to load/unload them!  Why you&#8217;d want this option other than for development, I&#8217;m not sure, but its there if you know where to look.</p>
<p>At this point <em>Conduit has failed to gain my trust, so I give up.</em>  I&#8217;m fine with Pidgin being crash happy or Eclipse being ridiculously complex to configure.  The former isn&#8217;t mission critical and the latter is intended for developers.</p>
<p>However, I&#8217;m expected to entrust all of my files to Conduit.  Files and account information for network resources if I could figure out how to get that to work.  I have pretty high expectations for anything I&#8217;m entrusting my files and passwords too.  Right now Conduit seems more like a demo of GTK+&#8217;s canvas drawing abilities (it is pretty looking) than a powerful synchronization tool.</p>
<p><strong>The Dream</strong></p>
<p><em>My expectations for web enabling Gnome are <strong>insanely</strong> high.</em>  Synchronization isn&#8217;t enough (although it&#8217;d be an excellent start).  I need web enabled collaboration features as well.  I need it to Just Work&trade; as well as be Secure By Default&trade;.</p>
<p>This means:</p>
<ul>
<li>All applications can synchronize their <em>settings</em> and <em>data</em>.</li>
<li>All data has some sort of web viewable format and ideally a way to interact with it on the web as well.</li>
<li>By default all settings and data should be <em>private</em>.</li>
<li>Fine-grained <abbr title="Create Read Update Delete">CRUD</abbr> permissions for all settings and data.  The C<small>reate</small> and U<small>pdate</small> are key here: not only should I be able to give other users the ability to edit my files but Grandma should be able to upload photos to my photo album.</li>
<li>While I&#8217;m dreaming can I add versioning support (<a href="https://www.getdropbox.com/referrals/NTE2ODkwNDk">like Dropbox</a>)?  Cool, thanks. <img src='http://blog.schmichael.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </li>
</ul>
<p><strong>The Implementation</strong></p>
<p>Unfortunately I think Conduit is the wrong way to go.  The concept is sound, but <a href="http://www.jwz.org/doc/worse-is-better.html">Worse Is Better&trade;</a>:  each application needs to be allowed to implement their own integration with the cloud synchronization and collaboration system.  There&#8217;s too many application specific tasks to accomplish intuitive synchronization and collaboration features outside the main application.</p>
<p>Tomboy has had pretty good synchronization for a while now.  <a href="https://labs.mozilla.com/projects/weave/">Firefox is getting it with Weave</a>.</p>
<p>In a way F-Spot and Banshee support 1-way synchronization and collaboration.  F-Spot can upload photos to a variety of services which have all (or at least most) of the features I&#8217;m pining for.  Banshee&#8217;s ability to download Podcasts and music synchronize to iPods (note: I&#8217;ve never used that feature) is a sort of primordial synchronization.  If only <a href="http://idea.opensuse.org/content/ideas/web-interface-to-banshee-library">Banshee Web</a> had survived (and wasn&#8217;t written in ASP.NET, the ickiest of all webdev platforms).  <a href="http://www.abisource.com/wiki/AbiCollab">Abiword has been toying with cloud services for a little while as well.</a></p>
<p>Perhaps Evolution is the poster child for this: I currently use it as a Gmail and Gcal interface sometimes because there are certain use cases for which I prefer it (shocking I know!).  Despite its past reputation for being bloated and buggy, it Just Works&tm; these days and integrates beautifully with the rest of the Gnome desktop (are those calendar events in my system tray calendar?!  amazing!  Pidgin integration?!  <3 Evolution).  Evolution lives completely in the cloud and synchronizes everything locally beautifully (after years and years of effort).</p>
<p><strong>Why Gnome Can Do It</strong></p>
<p>Gimp is actually the first Gnome app to really make me realize working on the web <em>can</em> and <em>should</em> be as easy as working locally.  All it did was utilize Gnome&#8217;s VFS to edit and save images via FTP or SSH.  With Gnome&#8217;s screenshot tool, I can save a screenshot to a web accessible location in 1 keypress and 2 clicks.  Amazing!  Thats almost as fast and easy as using a pastebin tool on the command line for sharing text.</p>
<p>Snowy seems like an excellent poster child for the web interface I&#8217;m whining about.  I haven&#8217;t used it yet, but the very idea that Tomboy already has an open source reference implementation is an excellent start.  3rd parties could implement the protocols and offer competing services.</p>
<p>In an ideal world this would create a revenue stream for open source applications: services like Dropbox could support the synchronization and collaboration protocols and in return support development of the projects.  The more people who use apps that integrate seamlessly with Dropbox, the more people who pay for Dropbox&#8230; or box.net or Amazon or&#8230; you get the idea.</p>
<p><strong>FreeDesktop.org Does What?!</strong></p>
<p>That&#8217;s right, FreeDesktop.org needs to lead the charge here.  Its not enough that the protocols are open, application developers need libraries to make synchronization and collaboration <em>easy</em>.  In that way Conduit is right: each application should not completely reinvent the wheel.</p>
<p>FreeDesktop.org needs to follow Mozilla&#8217;s lead.  Mozilla realized early on that in order for their browser business to succeed, they needed <em>open standards to succeed</em>.  FreeDesktop.org needs to do the same.  A KDE application should be able to synchronize to the same service as a Gnome app (this is where Conduit&#8217;s monolithic-master-synchronization-app model seems too optimistic to succeed).  OSX and Windows apps should be able to use the base synchronization libraries as well, even if they don&#8217;t use GTK+ or QT.</p>
<p>At the end of the day I should be able to sync my photos, documents, and mp3s between my laptop, desktop, cell phone, Kindle, etc as well as any relevant application settings (Tomboy for Kindle?!  yes please!).  &#8230;and so much more.</p>
<p><small>* Not always true.  For example: posting opinions on a piece of software long after the roadmap has been made.</small><br />
<small>** Strike 1 against Conduit: &#8220;Canvas&#8221; isn&#8217;t a very end user friendly term <abbr title="in my humble opinion">IMHO</abbr>.  A minor complaint, but as confusing as the UI already is, it needs all the help it can get.  Perhaps the problem isn&#8217;t the name &#8220;Canvas&#8221; but rather that the fact that it doesn&#8217;t even need to be said.  Remove all references to it and just put a textbox that says &#8220;Drop data providers here.&#8221; when the canvas is empty.  The &#8220;Clear canvas&#8221; option can just be &#8220;Clear&#8221; as there&#8217;s really only 1 thing that can be cleared.</small><br />
<small>*** Strike 1.5: &#8220;Remove&#8221; would be better than &#8220;Delete&#8221;.  Delete makes me wonder if its going to erase my files!  Remove seems more descriptive and precise.  Also, drop &#8220;item&#8221; from the end of each right click menu option.  Its redundant when every option operates on the item you clicked.</small></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2009/06/02/my-gnome-30-a-real-web-desktop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Keeping all your notes in sync with Dropbox and Tomboy</title>
		<link>http://blog.schmichael.com/2009/04/17/in-sync-with-dropbox-and-tomboy/</link>
		<comments>http://blog.schmichael.com/2009/04/17/in-sync-with-dropbox-and-tomboy/#comments</comments>
		<pubDate>Sat, 18 Apr 2009 00:35:47 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Mono/.Net]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[dropbox]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[tomboy]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/?p=630</guid>
		<description><![CDATA[Tomboy is a wonderful note taking program for Gnome. It has some synchronization features built-in, but not everyone has a server to store their notes for synchronizing between multiple computers. Enter Dropbox: a service for synchronizing files between computers. It &#8230; <a href="http://blog.schmichael.com/2009/04/17/in-sync-with-dropbox-and-tomboy/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://projects.gnome.org/tomboy/">Tomboy</a> is a wonderful note taking program for Gnome.  It has some synchronization features built-in, but not everyone has a server to store their notes for synchronizing between multiple computers.</p>
<p>Enter <a href="https://www.getdropbox.com/referrals/NTE2ODkwNDk">Dropbox</a>: a service for synchronizing files between computers.  It works great in Gnome (Windows and Mac OSX as well).</p>
<p>I use Dropbox for synchronizing my Tomboy notes by telling Tomboy to synchronize to a Local Folder: <code>~/Dropbox/Tomboy</code></p>
<p>My one gripe is that you have to go into a note to synchronize.  <a href="http://bugzilla.gnome.org/show_bug.cgi?id=468459">Someone has filed a bug and submitted a patch</a>, so hopefully it will be fixed soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2009/04/17/in-sync-with-dropbox-and-tomboy/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

