<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>ionel's codelog</title>
	<atom:link href="http://ionelmc.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://ionelmc.wordpress.com</link>
	<description>Just another tech mumbo-jumbo weblog</description>
	<lastBuildDate>Mon, 20 May 2013 16:53:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='ionelmc.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/54fca241e7919a91039163e33b9a45c1?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>ionel's codelog</title>
		<link>http://ionelmc.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://ionelmc.wordpress.com/osd.xml" title="ionel&#039;s codelog" />
	<atom:link rel='hub' href='http://ionelmc.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Old Ubuntu 10.04 on Hyper-V</title>
		<link>http://ionelmc.wordpress.com/2013/03/11/old-ubuntu-10-04-on-hyper-v/</link>
		<comments>http://ionelmc.wordpress.com/2013/03/11/old-ubuntu-10-04-on-hyper-v/#comments</comments>
		<pubDate>Mon, 11 Mar 2013 13:12:46 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[hyperv]]></category>
		<category><![CDATA[piix4]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=218</guid>
		<description><![CDATA[If you have to install 10.04 in a Hyper-V you might have some trouble if you want network. I&#8217;ve tried 11.10 and it has the same problem. Only 12.04 works out of the box with no fixups. The first thing to do is to always use the legacy network adapter. If you use the normal [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=218&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>If you have to install 10.04 in a Hyper-V you might have some trouble if you want network. I&#8217;ve tried 11.10 and it has the same problem. Only 12.04 works out of the box with no fixups.</p>
<p>The first thing to do is to always use the legacy network adapter. If you use the normal one and activate the hv_netvsc module the vm won&#8217;t boot anymore (some kernel failure at boot). It will look like this:<br />
<a href="http://ionelmc.files.wordpress.com/2013/03/ubuntu-10-04-crash-at-boot.png"><img class="alignnone size-thumbnail wp-image-219" alt="Screenshot of ubuntu crashing at boot on Hyper-V" src="http://ionelmc.files.wordpress.com/2013/03/ubuntu-10-04-crash-at-boot.png?w=150&#038;h=93" width="150" height="93" /></a></p>
<p>Now, the first thing to do is disable vga16fb in the install: in the install menu press F6 and then add &#8220;vga16fb.modeset=0&#8243; to the boot options. This will speed up the display a lot. Eg:<br />
<a href="http://ionelmc.files.wordpress.com/2013/03/ubuntu-10-04-install.png"><img class="alignnone size-thumbnail wp-image-220" alt="ubuntu-10.04-install" src="http://ionelmc.files.wordpress.com/2013/03/ubuntu-10-04-install.png?w=150&#038;h=112" width="150" height="112" /></a></p>
<p>After the install disable again: <code>echo blacklist vga16fb | sudo tee -a /etc/modprobe.d/blacklist-framebuffer.conf</code></p>
<p>Ubuntu 10.04 has the <a title="IC" href="http://blogs.technet.com/b/port25/archive/2009/07/22/introduction-to-the-linux-integration-components.aspx">IC</a> modules but they are not active by default. They aren&#8217;t even supported but they seem to work. Do the standard kernel module dance:</p>
<p style="padding-left:30px;">in /etc/initramfs-tools/modules add:</p>
<p><code style="padding-left:60px;">hv_vmbus</code><br />
<code style="padding-left:60px;">hv_storvsc</code><br />
<code style="padding-left:60px;">hv_blkvsc</code><br />
<code style="padding-left:60px;">hv_netvsc</code></p>
<p style="padding-left:30px;">and run <code>update-initramfs –u</code></p>
<p>Make sure you take a snapshot before rebooting (just in case) !</p>
<h3>Bonus:</h3>
<p style="padding-left:30px;">If you get this <code>piix4_smbus 0000:00:07.0: SMBus base address uninitialized - upgrade BIOS or use force_addr=0xaddr</code></p>
<p style="padding-left:30px;">Then <code>sudo nano /etc/modprobe.d/blacklist.conf</code>, add: <code>blacklist i2c_piix4</code> and run <code>update-initramfs -u</code> again.</p>
<br /> Tagged: <a href='http://ionelmc.wordpress.com/tag/hyperv/'>hyperv</a>, <a href='http://ionelmc.wordpress.com/tag/piix4/'>piix4</a>, <a href='http://ionelmc.wordpress.com/tag/ubuntu/'>ubuntu</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/218/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=218&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2013/03/11/old-ubuntu-10-04-on-hyper-v/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>

		<media:content url="http://ionelmc.files.wordpress.com/2013/03/ubuntu-10-04-crash-at-boot.png?w=150" medium="image">
			<media:title type="html">Screenshot of ubuntu crashing at boot on Hyper-V</media:title>
		</media:content>

		<media:content url="http://ionelmc.files.wordpress.com/2013/03/ubuntu-10-04-install.png?w=150" medium="image">
			<media:title type="html">ubuntu-10.04-install</media:title>
		</media:content>
	</item>
		<item>
		<title>Windows 8 doesn&#8217;t let you change the network type ?</title>
		<link>http://ionelmc.wordpress.com/2012/11/18/windows-8-doesnt-let-you-change-the-network-type/</link>
		<comments>http://ionelmc.wordpress.com/2012/11/18/windows-8-doesnt-let-you-change-the-network-type/#comments</comments>
		<pubDate>Sun, 18 Nov 2012 00:09:42 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=213</guid>
		<description><![CDATA[In case you&#8217;ve been feeling adventurous like me and installed Windows 8 you probably also installed Hyper-V cause well, it&#8217;s free and it has way better integration with Windows. Yes, you can make your VM start when Windows starts with VMware too &#8211; but Hyper-V remembers if you had it running before shutdown. And shutdown [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=213&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In case you&#8217;ve been feeling adventurous like me and installed Windows 8 you probably also installed Hyper-V cause well, it&#8217;s free and it has way better integration with Windows. Yes, you can make your VM start when Windows starts with VMware too &#8211; but Hyper-V remembers if you had it running before shutdown. And shutdown works unlike VMware which does poweroff in case you did not reinstall vmware-tools after kernel upgrade (at least with Ubuntu). Could I have gotten something wrong ? Don&#8217;t think so &#8230; cause it works properly on Hyper-V.</p>
<p>Well anyway, the Network and Sharing Center in Windows 8 is quite weird &#8230; could not change the network type (to private) for one virtual Hyper-V adapter even tho I&#8217;ve enabled all user control with <a href="http://www.wincert.net/tips/microsoft-windows/windows-8/3342-how-to-change-network-location-type-in-windows-8">gpedit.msc</a>. To fix it I had to use the Network List Manager API&#8217;s <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa370790%28v=vs.85%29.aspx">SetCategory</a> it seems. There was <a href="http://blogs.technet.com/b/samdrey/archive/2011/10/19/how-to-use-powershell-to-change-the-network-location-type-to-private-or-public.aspx">this</a> PowerShell script that seem to do that but, damn it, I don&#8217;t want to edit the script every time I have the problem. And that PowerShell thing looks awful compared to Python &#8230;</p>
<p>Here&#8217;s a python script that does the right thing: asks the user what network should be made private.</p>
<pre class="brush: python; title: ; notranslate">
import win32com.client
NETWORK_CATEGORIES = {
    1: &quot;PRIVATE&quot;,
    0: &quot;PUBLIC&quot;,
    2: &quot;DOMAIN&quot;
}
m = win32com.client.Dispatch(&quot;{DCB00C01-570F-4A9B-8D69-199FDBA5723B}&quot;)
more = 1
pos = 1
connections = m.GetNetworkConnections()

while more:
    connection, more = connections.Next(pos)
    if connection:
        network = connection.GetNetwork()
        category = network.GetCategory()
        print '%s. &quot;%s&quot; is %s' % (pos, network.GetName(), NETWORK_CATEGORIES[category])
        if not category and raw_input(&quot;Make private [N]&quot;) in ['y', 'Y']:
            network.SetCategory(1)
    pos += 1
</pre>
<p>Now isn&#8217;t this pretty ? (except the shitty iterator-wanna-be api in <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa370706%28v=vs.85%29.aspx">GetNetworkConnections</a> &#8230;)</p>
<br /> Tagged: <a href='http://ionelmc.wordpress.com/tag/python/'>python</a>, <a href='http://ionelmc.wordpress.com/tag/windows/'>windows</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/213/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/213/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=213&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2012/11/18/windows-8-doesnt-let-you-change-the-network-type/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>How to run jmeter over ssh tunnel</title>
		<link>http://ionelmc.wordpress.com/2012/02/16/how-to-run-jmeter-over-ssh-tunnel/</link>
		<comments>http://ionelmc.wordpress.com/2012/02/16/how-to-run-jmeter-over-ssh-tunnel/#comments</comments>
		<pubDate>Thu, 16 Feb 2012 13:43:46 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apache jmeter]]></category>
		<category><![CDATA[load testing]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=199</guid>
		<description><![CDATA[There&#8217;s an old guide to do this here but it&#8217;s pretty outdated. Connecting to the server over ssh tunnel is the easiest way to do this as you would have to open a bunch of firewall ports on the server AND the client otherwise. I&#8217;m assuming you have JRE and Linux on both the server [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=199&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>There&#8217;s an old guide to do this <a href="http://developersblog.espris.sk/2009/10/how-to-jmeter-ssh-tunnel.html">here</a> but it&#8217;s pretty outdated. Connecting to the server over ssh tunnel is the easiest way to do this as you would have to open a bunch of firewall ports on the server AND the client otherwise. I&#8217;m assuming you have JRE and Linux on both the server and client. Should work on other OS with some minor adjustments. See bellow for the putty configuration if you have the client on windows. Note that jmeter recommends that the client and server have the same OS and JRE version.</p>
<p>On the server and client, download and extract somewhere jmeter:</p>
<pre class="brush: bash; title: ; notranslate">
wget http://www.apache.org/dist/jmeter/binaries/apache-jmeter-2.6.tgz
tar -xf apache-jmeter-2.6.tgz
cd apache-jmeter-2.6
</pre>
<p>On the client edit <code>bin/jmeter.properties</code> and add:</p>
<pre class="brush: bash; title: ; notranslate">
remote_hosts=127.0.0.1:55501
client.rmi.localport=55512
mode=Batch
num_sample_threshold=250
</pre>
<p>On the server edit <code>bin/jmeter.properties</code> and add:</p>
<pre class="brush: bash; title: ; notranslate">
server_port=55501
server.rmi.localhostname=127.0.0.1
server.rmi.localport=55511
</pre>
<p>Now connect to the server using this:</p>
<pre class="brush: bash; title: ; notranslate">
ssh -L 55501:127.0.0.1:55501 -L 55511:127.0.0.1:55511 -R 55512:127.0.0.1:55512 user@hostname
</pre>
<p>If you&#8217;re using putty it should look like this: <a href="http://ionelmc.files.wordpress.com/2012/02/putty-port-forwarding.png"><img style="vertical-align:middle;" src="http://ionelmc.files.wordpress.com/2012/02/putty-port-forwarding.png?w=150&#038;h=143" alt="putty port forwarding configuration" title="putty-port-forwarding" width="150" height="143" class="alignnone size-thumbnail wp-image-203" /></a></p>
<p>&nbsp;</p>
<p>Now run:</p>
<pre class="brush: bash; title: ; notranslate">
bin/jmeter-server -Djava.rmi.server.hostname=127.0.0.1
</pre>
<p>And on the client run:</p>
<pre class="brush: bash; title: ; notranslate">
bin/jmeter.sh -Djava.rmi.server.hostname=127.0.0.1
# or
bin/jmeter.sh -Djava.rmi.server.hostname=127.0.0.1 -t /path/to/test-plan.jmx
</pre>
<p>Now you can use the remote node !</p>
<br /> Tagged: <a href='http://ionelmc.wordpress.com/tag/apache-jmeter/'>apache jmeter</a>, <a href='http://ionelmc.wordpress.com/tag/load-testing/'>load testing</a>, <a href='http://ionelmc.wordpress.com/tag/ssh/'>ssh</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/199/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/199/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=199&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2012/02/16/how-to-run-jmeter-over-ssh-tunnel/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>

		<media:content url="http://ionelmc.files.wordpress.com/2012/02/putty-port-forwarding.png?w=150" medium="image">
			<media:title type="html">putty-port-forwarding</media:title>
		</media:content>
	</item>
		<item>
		<title>Tweaks for making django admin faster</title>
		<link>http://ionelmc.wordpress.com/2012/01/19/tweaks-for-making-django-admin-faster/</link>
		<comments>http://ionelmc.wordpress.com/2012/01/19/tweaks-for-making-django-admin-faster/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 20:36:24 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[django admin]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=184</guid>
		<description><![CDATA[Here follow a number of tricks I&#8217;ve employed in the past to make django admin faster. Editable foreign keys in the changelist If you have foreign keys in list_editable django will make 1 database query for each item in the changelist. Quite a lot for a changelist of 100 items. The trick is to cache [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=184&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Here follow a number of tricks I&#8217;ve employed in the past to make django admin faster.</p>
<h3>Editable foreign keys in the changelist</h3>
<p>If you have foreign keys in list_editable django will make 1 database query for each item in the changelist. Quite a lot for a changelist of 100 items. The trick is to cache the choices for that formfield:</p>
<pre class="brush: python; title: ; notranslate">
class MyAdmin(admin.ModelAdmin):
    list_editable = 'myfield',
    def formfield_for_dbfield(self, db_field, **kwargs):
        request = kwargs['request']
        formfield = super(MyAdmin, self).formfield_for_dbfield(db_field, **kwargs)
        if db_field.name == 'myfield':
            myfield_choices_cache = getattr(request, 'myfield_choices_cache', None)
            if myfield_choices_cache is not None:
                formfield.choices = myfield_choices_cache
            else:
                request.myfield_choices_cache = formfield.choices
        return formfield
</pre>
<h3>Foreign keys or many to many fields in admin inlines</h3>
<p>If you have fk of m2m fields on InlineModelAdmin for every object in the formset you&#8217;ll get a database hit. You can avoid this by having something like:</p>
<pre class="brush: python; title: ; notranslate">
class MyAdmin(admin.TabularInline):
    fields = 'myfield',
    def formfield_for_dbfield(self, db_field, **kwargs):
        formfield = super(MyAdmin, self).formfield_for_dbfield(db_field, **kwargs)
        if db_field.name == 'myfield':
            # dirty trick so queryset is evaluated and cached in .choices
            formfield.choices = formfield.choices
        return formfield
</pre>
<h3>Enable template caching </h3>
<p>It&#8217;s amazing how easy it is to forget to add this in your settings:</p>
<pre class="brush: python; title: ; notranslate">
TEMPLATE_LOADERS = (
    ('django.template.loaders.cached.Loader', (
        'django.template.loaders.filesystem.Loader',
        'django.template.loaders.app_directories.Loader',
    )),
)
</pre>
<h3>Use select_related for the edit forms too</h3>
<p>In case you have some readonly fields on the edit form and they need related data to display list_select_related doesn&#8217;t help. Eg:</p>
<pre class="brush: python; title: ; notranslate">
class MyAdmin(admin.ModelAdmin):
    readonly_fields = 'myfield',
    def queryset(self, request):
        return super(MyAdmin, self).queryset(request).select_related('myfield')
</pre>
<h3>Use annotations if possible for function entries list_display instead of making additional queries</h3>
<p>Check the <a href="https://docs.djangoproject.com/en/dev/topics/db/aggregation/">aggregation api</a> to see if you can use this. Here&#8217;s the typical example:</p>
<pre class="brush: python; title: ; notranslate">
class AuthorAdmin(admin.ModelAdmin):
    list_display = 'books_count',
    
    def books_count(self, obj):
        return obj.books_count
    
    def queryset(self, request):
        return super(AuthorAdmin, self).queryset(
            request).annotate(books_count=Count('books'))
</pre>
<p>The models would look like this:</p>
<pre class="brush: python; title: ; notranslate">
class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    name = models.CharField(max_length=100)
    author = models.ForeignKey(Author, related_name=&quot;books&quot;)
</pre>
<h3>Cache the filters from the admin changelist</h3>
<p>This has the obvious tradeoff that you&#8217;ll have stale data in the list of filter but if they don&#8217;t change that often and those distinct queries are killing your database then this will help a lot. Just add a custom change_list.html template in your project (eg: <code>templates/&lt;myapp&gt;/change_list.html</code>):</p>
<pre class="brush: xml; title: ; notranslate">
{% extends &quot;admin/change_list.html&quot; %}
{% load admin_list i18n cache %}

{% block filters %}
    {% cache 300 admin_filters request.GET.items request.path request.user.username %}
        {% if cl.has_filters %}
          &lt;div id=&quot;changelist-filter&quot;&gt;
            &lt;h2&gt;{% trans 'Filter' %}&lt;/h2&gt;
            {% for spec in cl.filter_specs %}{% admin_list_filter cl spec %}{% endfor %}
          &lt;/div&gt;
        {% endif %}
    {% endcache %}
{% endblock %}
</pre>
<h3>Bonus trick</h3>
<pre class="brush: python; title: ; notranslate">
frame = sys._getframe(1)
while frame:
    if frame.f_code.co_name == 'render_change_form':
        if 'request' in frame.f_locals:
            request = frame.f_locals['request']
            break
    frame = frame.f_back
else:
    raise RuntimeError(&quot;Could not find request object.&quot;)

# do stuff with request
</pre>
<p>This could be used in some specific cases (eg: you need the request in a widget&#8217;s render method), as a last resort ofcourse ;) </p>
<p>&#8211;</p>
<p>What did you do to make django admin faster ?</p>
<br /> Tagged: <a href='http://ionelmc.wordpress.com/tag/django/'>django</a>, <a href='http://ionelmc.wordpress.com/tag/django-admin/'>django admin</a>, <a href='http://ionelmc.wordpress.com/tag/python/'>python</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/184/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/184/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=184&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2012/01/19/tweaks-for-making-django-admin-faster/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Drop-in celery AbortableTask replacement</title>
		<link>http://ionelmc.wordpress.com/2011/10/24/drop-in-celery-abortabletask-replacement/</link>
		<comments>http://ionelmc.wordpress.com/2011/10/24/drop-in-celery-abortabletask-replacement/#comments</comments>
		<pubDate>Mon, 24 Oct 2011 14:50:01 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[celery]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=179</guid>
		<description><![CDATA[If you need to report progress updates from the tasks (or you call update_state in the task) you cannot use the bundled AbortableTask from celery.contrib.abortable because it relies on status updates too. That means you&#8217;ll get race conditions if you do that. You can use revokes for aborting tasks but they don&#8217;t give you enough [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=179&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>If you need to report progress updates from the tasks (or you call update_state in the task) you cannot use the bundled AbortableTask from celery.contrib.abortable because it relies on status updates too. That means you&#8217;ll get race conditions if you do that.</p>
<p>You can use revokes for aborting tasks but they don&#8217;t give you enough control and it&#8217;s not guaranteed that your tasks will stop gracefully (or stop at all). Revokes can raise <a href="http://docs.celeryproject.org/en/latest/userguide/workers.html#time-limits">SoftTimeLimitExceeded</a> if enabled (via TERM signal) however it might be tricky to perform cleanup &#8211; if you call C extension the exception will get delayed till the call returns. See the <a href="http://docs.python.org/library/signal.html">signal module docs</a> for what happens when you raise an exception from a signal handler (that&#8217;s what celery does).</p>
<p>Given this, an alternative is to use redis to store the aborted task ids in a redis set. If you use the redis broker you can use this drop-in replacement:</p>
<pre class="brush: python; title: ; notranslate">
from contextlib import contextmanager
import celery
from celery.task.base import Task
from celery.result import AsyncResult

from django.conf import settings

assert settings.BROKER_TRANSPORT == 'redis', &quot;AbortableTask can only work with a 'redis' BROKER_TRANSPORT&quot;
REDIS_KEY = getattr(settings, 'ABORTABLE_REDIS_KEY', 'task-aborts')

@contextmanager
def client_from_pool():
    connection = celery.current_app.pool.acquire()
    try:
        yield connection.default_channel.client
    finally:
        connection.release()

class AbortableAsyncResult(AsyncResult):

    def is_aborted(self):
        with client_from_pool() as client:
            return client.sismember(REDIS_KEY, self.task_id)

    def abort(self):
        with client_from_pool() as client:
            client.sadd(REDIS_KEY, self.task_id)

class AbortableTask(Task):

    @classmethod
    def AsyncResult(cls, task_id):
        return AbortableAsyncResult(task_id, backend=cls.backend,
                                             task_name=cls.name)

    def is_aborted(self, **kwargs):
        task_id = kwargs.get('task_id', self.request.id)
        with client_from_pool() as client:
            return client.sismember(REDIS_KEY, task_id)

    def cleanup(self, **kwargs):
        task_id = kwargs.get('task_id', self.request.id)
        with client_from_pool() as client:
            client.srem(REDIS_KEY, task_id)

    def after_return(self, status, retval, task_id, args, kwargs, einfo):
        self.cleanup(task_id=task_id)
</pre>
<p>This will use the broker&#8217;s connection pool if enabled (you should enable it, just set <a href="http://docs.celeryproject.org/en/latest/configuration.html?highlight=broker_pool_limit#broker-pool-limit">BROKER_POOL_LIMIT</a>).</p>
<br /> Tagged: <a href='http://ionelmc.wordpress.com/tag/celery/'>celery</a>, <a href='http://ionelmc.wordpress.com/tag/django/'>django</a>, <a href='http://ionelmc.wordpress.com/tag/python/'>python</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/179/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/179/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=179&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2011/10/24/drop-in-celery-abortabletask-replacement/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Django pro tip: if you only use the admin</title>
		<link>http://ionelmc.wordpress.com/2011/10/11/django-pro-tip-if-you-only-use-the-admin/</link>
		<comments>http://ionelmc.wordpress.com/2011/10/11/django-pro-tip-if-you-only-use-the-admin/#comments</comments>
		<pubDate>Tue, 11 Oct 2011 10:55:56 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=172</guid>
		<description><![CDATA[If you have a project that only exposes the admin you should just use the 500/404 templates from the admin. Put this in your project&#8217;s urls.py: I wonder why django doesn&#8217;t mention those templates in the docs &#8230; If you have other drop-in apps that need authentication (like rosetta or sentry) bare in mind that [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=172&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>If you have a project that only exposes the admin you should just use the 500/404 templates from the admin.</p>
<p>Put this in your project&#8217;s urls.py:</p>
<pre class="brush: python; title: ; notranslate">
from django.utils.functional import curry
from django.views.defaults import server_error, page_not_found

handler500 = curry(server_error, template_name='admin/500.html')
handler404 = curry(page_not_found, template_name='admin/404.html')
</pre>
<p>I wonder why django doesn&#8217;t mention those templates in the docs &#8230;</p>
<p>If you have other drop-in apps that need authentication (like <a href="http://pypi.python.org/pypi/django-rosetta">rosetta</a> or <a href="http://pypi.python.org/pypi/django-sentry">sentry</a>) bare in mind that the admin doesn&#8217;t have a reusable login view so you must hook one. You should just reuse django admin&#8217;s login template. Put this in the urlpatterns (don&#8217;t forget to match it to <a href="https://docs.djangoproject.com/en/dev/ref/settings/#login-url">LOGIN_URL</a> in the settings):</p>
<pre class="brush: python; title: ; notranslate">
    url(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'admin/login.html'}),
</pre>
<p>You might note that this is not very <a href="http://en.wikipedia.org/wiki/DRY">DRY</a> but actually the LOGIN_URL might differ than the one in the urlpatterns (eg: you mount the django wsgi handler on a non-root path).</p>
<br /> Tagged: <a href='http://ionelmc.wordpress.com/tag/django/'>django</a>, <a href='http://ionelmc.wordpress.com/tag/python/'>python</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/172/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/172/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=172&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2011/10/11/django-pro-tip-if-you-only-use-the-admin/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Tmux scripting</title>
		<link>http://ionelmc.wordpress.com/2011/09/25/tmux-scripting/</link>
		<comments>http://ionelmc.wordpress.com/2011/09/25/tmux-scripting/#comments</comments>
		<pubDate>Sun, 25 Sep 2011 16:07:42 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[celery]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tmux]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=164</guid>
		<description><![CDATA[I usually need to run more than 1 command for some project and got tired of searching through those putty windows for the session I want. So I thought of using a terminal multiplexer like Tmux. I&#8217;m using celery with two queues and I need to run this: manage.py celeryd -Q queueA manage.py celeryd -Q [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=164&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I usually need to run more than 1 command for some project and got tired of searching through those putty windows for the session I want. So I thought of using a terminal multiplexer like <a title="tmux" href="http://tmux.sourceforge.net/">Tmux</a>.</p>
<p>I&#8217;m using celery with two queues and I need to run this:</p>
<ul>
<li>manage.py celeryd -Q queueA</li>
<li>manage.py celeryd -Q queueB</li>
<li>manage.py celerycam -E</li>
</ul>
<p>I need celerycam because it will get those <a href="http://ask.github.com/celery/userguide/monitoring.html?highlight=celerycam#starting-the-monitor">stats in djcelery</a> up to date.</p>
<p>It&#8217;s also a good idea to tail the postgresql log &#8211; when you break your models or database in some cases Django isn&#8217;t very helpful so this helps a lot:</p>
<ul>
<li>tail -f /var/log/postgresql/postgresql-8.4-main.log</li>
</ul>
<p>I use a wide screen so I want a layout like this:</p>
<pre>    +------------------------------------+-------------------+
    |                                    |                   |
    |              runserver             |                   |
    |                                    |     celerycam     |
    +------------------------------------+                   |
    |                                    |                   |
    |               celeryd              +-------------------+
    |                                    |                   |
    +------------------------------------+                   |
    |                                    |   postgresql log  |
    |               celeryd              |                   |
    |                                    |                   |
    +------------------------------------+-------------------+</pre>
<p>I also want to start a new tmux session from the same command so I can close everything easily &#8211; those celeryd&#8217;s don&#8217;t reload automatically :(</p>
<p>You&#8217;d usually run something like:</p>
<pre>tmux new-session "tmux splitw 'command1';  tmux splitw 'command3'; tmux splitw 'command3'; command4"</pre>
<p>but that get&#8217;s rather long and you need to quote and escape, calculate the panel sizes manually (I want equal height) and for the layout above you also need to select the right panels before splitting.</p>
<p>The commands vary across projects (some have more and some have less) &#8211; so how about we make a script:</p>
<pre class="brush: python; title: ; notranslate">
import subprocess

left_commands = [
    &quot;python manage.py runserver&quot;,
    &quot;python manage.py celeryd -Q queueA -c 2 -E -n worker1&quot;,
    &quot;python manage.py celeryd -Q queueB -c 2 -E -n worker2&quot;,
]
right_commands = [
    &quot;python manage.py celerycam&quot;,
    &quot;tail -f /var/log/postgresql/postgresql-8.4-main.log&quot;,
]
session = ''

if right_commands:
    session += 'tmux selectp -t 0; tmux splitw -hd -p 35 \&quot;%s\&quot;; ' % right_commands[-1]
for index, command in enumerate(right_commands[:-1]):
    session += 'tmux selectp -t 1; tmux splitw -d -p %i \&quot;%s\&quot;; ' % (
        100 / (len(right_commands) - index),
        command
    )

for index, command in enumerate(left_commands[1:]):
    session += 'tmux selectp -t 0; tmux splitw -d -p %i \&quot;%s\&quot;; ' % (
        100 / (len(left_commands) - index),
        command
    )
if left_commands:
    session += left_commands[0]

args = [
    'tmux',
    'new-session',
    session,
]
print 'Running ', args
subprocess.call(args)
</pre>
<br /> Tagged: <a href='http://ionelmc.wordpress.com/tag/celery/'>celery</a>, <a href='http://ionelmc.wordpress.com/tag/django/'>django</a>, <a href='http://ionelmc.wordpress.com/tag/python/'>python</a>, <a href='http://ionelmc.wordpress.com/tag/tmux/'>tmux</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/164/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=164&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2011/09/25/tmux-scripting/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Measure your code</title>
		<link>http://ionelmc.wordpress.com/2011/07/03/measure-your-code/</link>
		<comments>http://ionelmc.wordpress.com/2011/07/03/measure-your-code/#comments</comments>
		<pubDate>Sun, 03 Jul 2011 00:01:15 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cyclomatic complexity]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[mccabe]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sloc]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=153</guid>
		<description><![CDATA[I found a cool tool today to measure code: metrics. It measures SLOC, comments and cyclomatic complexity. It&#8217;s easy to install: pip install pygments metrics Run this in your project&#8217;s root: I have a django project so I added \! -path "*/migrations/*.py" to skip any files that are in a migrations dir (I&#8217;d skip the [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=153&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I found a cool tool today to measure code: <a href="http://www.testing-software.org/Tools/metrics/index.html">metrics</a>. It measures SLOC, comments and cyclomatic complexity. It&#8217;s easy to install: <code>pip install pygments metrics</code></p>
<p>Run this in your project&#8217;s root:</p>
<pre class="brush: plain; title: ; notranslate">
metrics -v `find . -type f \( -iname &quot;*.css&quot; -or -iname &quot;*.py&quot; -or -iname &quot;*.js&quot; -or -iname &quot;*.html&quot; -or -iname &quot;*.txt&quot; \) \! -path &quot;*/migrations/*.py&quot; -print`
</pre>
<p>I have a django project so I added <code>\! -path "*/migrations/*.py"</code> to skip any files that are in a migrations dir (I&#8217;d skip the automatically generated <a href="http://south.aeracode.org/">south</a> migrations). </p>
<p>You probably bundle other libraries or apps in your source tree (eg: jquery or that nice django app the author didn&#8217;t bother to make a setup.py script for) so you want to measure only some specific paths. Eg, to collect stats only for files in src/foobar, lib/tools and src/otherbar: </p>
<pre class="brush: plain; title: ; notranslate">
metrics -v `find src/foobar lib/tools src/otherbar -type f \( -iname &quot;*.css&quot; -or -iname &quot;*.py&quot; -or -iname &quot;*.js&quot; -or -iname &quot;*.html&quot; -or -iname &quot;*.txt&quot; \) \! -path &quot;*/migrations/*.py&quot; -print`
</pre>
<p>If you work on multiple projects you can make a script or alias for this:</p>
<pre class="brush: plain; title: ; notranslate">
metrics -v `find \`cat METRICS\` -type f \( -iname &quot;*.css&quot; -or -iname &quot;*.py&quot; -or -iname &quot;*.js&quot; -or -iname &quot;*.html&quot; -or -iname &quot;*.txt&quot; \) \! -path &quot;*/migrations/*.py&quot; -print`
</pre>
<p>And in each project just save a <code>METRICS</code> file with the list of paths.</p>
<p>I get something like this for one random project:</p>
<pre>
Metrics Summary:
Files                       Language        SLOC Comment McCabe
----- ------------------------------ ----------- ------- ------
  129                         Python        4831     289    261
    2                      Text only           0       0      0
   49              HTML+Django/Jinja        1381      19    166
    7                     JavaScript        2204     231    352
   21                            CSS        1839     111      0
----- ------------------------------ ----------- ------- ------
  208                          Total       10255     650    779
</pre>
<p>Do McCabe (aka <a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity">cyclomatic complexity</a>) ratios (<code>McCabe/(SLOC-Comment)</code>) look odd ? (0.17 for javascript and and 0.05 for python).</p>
<p>Do you know other measurement tools adequate for Django projects ? Do tell me and, if possible, how to run it for specific files like above (I&#8217;m lazy :)</p>
<br /> Tagged: <a href='http://ionelmc.wordpress.com/tag/cyclomatic-complexity/'>cyclomatic complexity</a>, <a href='http://ionelmc.wordpress.com/tag/django/'>django</a>, <a href='http://ionelmc.wordpress.com/tag/mccabe/'>mccabe</a>, <a href='http://ionelmc.wordpress.com/tag/python/'>python</a>, <a href='http://ionelmc.wordpress.com/tag/sloc/'>sloc</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/153/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/153/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=153&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2011/07/03/measure-your-code/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Custom app names in the django admin</title>
		<link>http://ionelmc.wordpress.com/2011/06/24/custom-app-names-in-the-django-admin/</link>
		<comments>http://ionelmc.wordpress.com/2011/06/24/custom-app-names-in-the-django-admin/#comments</comments>
		<pubDate>Fri, 24 Jun 2011 21:43:10 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=147</guid>
		<description><![CDATA[EDIT: This approach is flawed &#8211; it will never work in the app_index page (/admin/appname/) and can cause problems with contenttypes queries. You are better off overriding the admin templates (lots of them unfortunately). To avoid hardcoding the app_label in the templates wrap it in trans tags and use the internationalization framework to map the internal [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=147&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<blockquote><p>EDIT: This approach is flawed &#8211; it will never work in the app_index page (/admin/appname/) and can cause problems with contenttypes queries. You are better off overriding the admin templates (lots of them unfortunately). To avoid hardcoding the app_label in the templates wrap it in <a href="https://docs.djangoproject.com/en/dev/topics/i18n/internationalization/#trans-template-tag"><code>trans</code></a> tags and use the internationalization framework to map the internal name to your desired display name.</p></blockquote>
<blockquote><p>EDIT 2: You can also use <a href="https://github.com/bmihelac/django-app-name-translation-in-admin">this</a>.</p></blockquote>
<p>Suppose you have a model like this:</p>
<pre class="brush: python; title: ; notranslate">
class Stuff(models.Model):
    class Meta:
        verbose_name = u'The stuff'
        verbose_name_plural = u'The bunch of stuff'

    ...
</pre>
<p>You have <code>verbose_name</code>, however you want to customise <code>app_label</code> too for different display in admin. Unfortunatelly having some arbitrary string (with spaces) doesn&#8217;t work and it&#8217;s not for display anyway.</p>
<p>Turns out that the admin uses app_label.<a href="http://docs.python.org/library/stdtypes.html?highlight=title#str.title">title</a>() for display so we can make a little hack: str subclass with overriden title method:</p>
<pre class="brush: python; title: ; notranslate">
class string_with_title(str):
    def __new__(cls, value, title):
        instance = str.__new__(cls, value)
        instance._title = title
        return instance

    def title(self):
        return self._title

    __copy__ = lambda self: self
    __deepcopy__ = lambda self, memodict: self
</pre>
<p>Now we can have the model like this:</p>
<pre class="brush: python; title: ; notranslate">
class Stuff(models.Model):
    class Meta:
        app_label = string_with_title(&quot;stuffapp&quot;, &quot;The stuff box&quot;)
        # 'stuffapp' is the name of the django app
        verbose_name = 'The stuff'
        verbose_name_plural = 'The bunch of stuff'

    ...
</pre>
<p>and the admin will show &#8220;The stuff box&#8221; as the app name.</p>
<br /> Tagged: <a href='http://ionelmc.wordpress.com/tag/django/'>django</a>, <a href='http://ionelmc.wordpress.com/tag/python/'>python</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/147/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/147/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=147&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2011/06/24/custom-app-names-in-the-django-admin/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Mercurial tip of the day: tortoisehg&#8217;s shelve</title>
		<link>http://ionelmc.wordpress.com/2011/06/22/mercurial-tip-of-the-day-tortoisehgs-shelve/</link>
		<comments>http://ionelmc.wordpress.com/2011/06/22/mercurial-tip-of-the-day-tortoisehgs-shelve/#comments</comments>
		<pubDate>Wed, 22 Jun 2011 20:48:27 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[mercurial]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=143</guid>
		<description><![CDATA[Shelved your local changes using tortoisehg&#8217;s shelve UI and now you feel silly because tortoisehg won&#8217;t let you apply them because the first hunk is rejected ? No need to feel silly any more, just add this in .hgrc (or mercurial.ini for windows users): [extensions] tortoisehg.util.hgshelve= This is a shelve extension bundled with tortoisehg. Other [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=143&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Shelved your local changes using tortoisehg&#8217;s shelve UI and now you feel silly because tortoisehg won&#8217;t let you apply them because the first hunk is rejected ? No need to feel silly any more, just add this in <code>.hgrc</code> (or <code>mercurial.ini</code> for windows users):</p>
<pre>[extensions]
tortoisehg.util.hgshelve=</pre>
<p>This is a shelve extension bundled with tortoisehg. Other shelve extensions don&#8217;t use the same store as tortoisehg.</p>
<p>Now just run:</p>
<pre>hg unshelve --force</pre>
<p>The rejected hunks will be ignored (you still get the .rej files).</p>
<br /> Tagged: <a href='http://ionelmc.wordpress.com/tag/mercurial/'>mercurial</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/143/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=143&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2011/06/22/mercurial-tip-of-the-day-tortoisehgs-shelve/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Stale formsets and the back button</title>
		<link>http://ionelmc.wordpress.com/2011/03/17/stale-formsets-and-the-back-button/</link>
		<comments>http://ionelmc.wordpress.com/2011/03/17/stale-formsets-and-the-back-button/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 17:57:35 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[forms]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=130</guid>
		<description><![CDATA[I have a problem on one of my projects: I have a page with a form that depends on what is stored in the database. If your using django formsets or have some form that saves over multiple objects you have this problem too. The user saves the form, data gets saved. However, if the [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=130&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I have a problem on one of my projects:</p>
<blockquote><p>I have a page with a form that depends on what is stored in the database. If your using django formsets or have some form that saves over multiple objects you have this problem too.</p>
<p>The user saves the form, data gets saved. However, if the user uses the back button he will get a page with the old form (that expects different data in the database). If the form gets resubmitted all kinds of problems may appear.</p>
<p>I had one case when you could get a <code>ValueError: invalid literal for int() with base 10: ''</code> if you resubmit a formset but instead of a existing object you have a new one. Easy to pull off by a regular user if he has multiple tabs opened.</p></blockquote>
<p>The best solution, I think, is to reload the page when the users goes back in history. Turns out this is easy to pull off with some http headers:</p>
<pre>Cache-Control: no-cache, must-revalidate, <strong>no-store</strong>
Pragma: no-cache</pre>
<p>The &#8220;no-store&#8221; option actually makes browses re-request when using the back button. Also, I&#8217;ve seen people adding &#8220;post-check=0, pre-check=0&#8243; to Cache-Control. Do NOT use those. They are Microsoft extensions to the http protocol, and if set they will actually make Internet Explorer request the page two times ! see <a href="http://blogs.msdn.com/b/ieinternals/archive/2009/07/20/using-post_2d00_check-and-pre_2d00_check-cache-directives.aspx">this</a>.</p>
<p>Here&#8217;s a simple view decorator if you&#8217;re using django:</p>
<pre class="brush: python; title: ; notranslate">
from django.utils.decorators import wraps
def must_revalidate(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        response = func(*args, **kwargs)
        response[&quot;Cache-Control&quot;] = &quot;no-cache, must-revalidate, no-store&quot;
        response[&quot;Pragma&quot;] = &quot;no-cache&quot;
        return response
    return wrapper
</pre>
<p>Having no-store creates some additional load on the server and creates other user experience problems:</p>
<ul>
<li>Users won&#8217;t have the old form data when they go back</li>
<li>Page scroll position isn&#8217;t kept</li>
<li>If the page has other state it isn&#8217;t kept &#8211; but depending on the browser that state might not be cached anyway (eg: dom changes)</li>
</ul>
<p>But I think it&#8217;s still better than surprising the user with different results for a submission with the same form data or having to deal consistently with missing or extra data in the database on the server-side. What do you think ?</p>
<br /> Tagged: <a href='http://ionelmc.wordpress.com/tag/django/'>django</a>, <a href='http://ionelmc.wordpress.com/tag/forms/'>forms</a>, <a href='http://ionelmc.wordpress.com/tag/python/'>python</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/130/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=130&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2011/03/17/stale-formsets-and-the-back-button/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Wondering about django orm caching frameworks</title>
		<link>http://ionelmc.wordpress.com/2010/08/25/wondering-about-django-orm-caching-frameworks/</link>
		<comments>http://ionelmc.wordpress.com/2010/08/25/wondering-about-django-orm-caching-frameworks/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 22:26:35 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=124</guid>
		<description><![CDATA[So briefly looking over the code reveals that: johnny-cache will cache the rows returned by the execution machinery in django&#8217;s sql compiler (monkey-patches the compilers). It looks like it has fancy-pants invalidation (it basically has bulk invalidation through 2-tiered cache key scheme, unlike cache-machine with relies on set_many) and even support for transactions. I&#8217;m using [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=124&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>So briefly looking over the code reveals that:</p>
<ul>
<li><a href="http://bitbucket.org/jmoiron/johnny-cache">johnny-cache</a> will cache the rows returned by the execution machinery in django&#8217;s sql compiler (monkey-patches the compilers). It looks like it has fancy-pants invalidation (it basically has bulk invalidation through 2-tiered cache key scheme, unlike cache-machine with relies on set_many) and even support for transactions. I&#8217;m using this and it&#8217;s awesome.</li>
<li><a href="http://github.com/jbalogh/django-cache-machine">django-cache-machine</a> will cache the result of the <code>QuerySet.iterator</code> method. It seems that it has some limitations: it only (automatically) invalidates on forward relations (FKs) so you have to perform carefull invalidation through your code (eg: you use <code>qs.update()</code>, run queries through models without the custom CachingManager, use <code>Model.create()</code> and whatnot &#8230;). Also, cache-machine will be heavy on the memcached traffic (1 call for every invalidated object, using set_many though &#8230;)</li>
<li><a href="http://github.com/dziegler/django-cachebot">django-cachebot</a> will cache the rows on the same level as cache-machine (at QuerySet.iterator call). Also, it has a very nice feature that will prefetch objects from reverse relations (like FK reverse descriptors and many to many relations &#8211; eg: <code>Group.objects.select_reverse('user_set')</code> and then <code>group.user_set_cache</code> will be equal to <code>group.user_set.all()</code>). Unfortunately the author only tested it on django 1.1 and it needs a django patch to work (the django manager patch is only for 1.1). I really like that select_reverse feature &#8211; unfortunately I can&#8217;t use this on django 1.2 :(</li>
</ul>
<p>So I&#8217;m thinking what I need is johnny-cache for the low level stuff and then some cache-machine to cache some of that &#8220;select_reverse&#8221; feng-shui that I would have to do myself.</p>
<p>Well, I&#8217;m probably missing something here and some <a href="http://simonwillison.net/2010/Mar/11/cachemachine/#c61069">other</a> people should have better comparisons for these frameworks. Any feedback ?</p>
<p>Edit: cachebot&#8217;s select_reverse is based on <a href="http://code.google.com/p/django-selectreverse/">django-selectreverse</a>, however it&#8217;s enhanced to support nested reverse relations (eg, from the docs: <code>Article.objects.select_reverse('book_set','book_set__publisher_set')</code>)</p>
<br /> Tagged: <a href='http://ionelmc.wordpress.com/tag/django/'>django</a>, <a href='http://ionelmc.wordpress.com/tag/python/'>python</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/124/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/124/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=124&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2010/08/25/wondering-about-django-orm-caching-frameworks/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>The final literals vs constructors argument</title>
		<link>http://ionelmc.wordpress.com/2010/02/04/the-final-literals-vs-constructors-argument/</link>
		<comments>http://ionelmc.wordpress.com/2010/02/04/the-final-literals-vs-constructors-argument/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 15:06:13 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=112</guid>
		<description><![CDATA[Seriously now, is there any reason to use constructors instead of literals for empty dicts/lists ? Tagged: python<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=112&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; def literal():
...     a = {}
...     b = []
... 
&gt;&gt;&gt; def builtinconstructor():
...     a = dict()
...     b = list()
... 
&gt;&gt;&gt; import dis
&gt;&gt;&gt; dis.dis(literal)
  3           0 BUILD_MAP                0
              3 STORE_FAST               0 (a)

  4           6 BUILD_LIST               0
              9 STORE_FAST               1 (b)
             12 LOAD_CONST               0 (None)
             15 RETURN_VALUE        
&gt;&gt;&gt; dis.dis(builtinconstructor)
  3           0 LOAD_GLOBAL              0 (dict)
              3 CALL_FUNCTION            0
              6 STORE_FAST               0 (a)

  4           9 LOAD_GLOBAL              1 (list)
             12 CALL_FUNCTION            0
             15 STORE_FAST               1 (b)
             18 LOAD_CONST               0 (None)
             21 RETURN_VALUE        
&gt;&gt;&gt; 
</pre>
<p>Seriously now, is there any reason to use constructors instead of literals for empty dicts/lists ?</p>
<br /> Tagged: <a href='http://ionelmc.wordpress.com/tag/python/'>python</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/112/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=112&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2010/02/04/the-final-literals-vs-constructors-argument/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>The &#8220;yield from&#8221; proposal</title>
		<link>http://ionelmc.wordpress.com/2009/04/10/the-yield-from-proposal/</link>
		<comments>http://ionelmc.wordpress.com/2009/04/10/the-yield-from-proposal/#comments</comments>
		<pubDate>Fri, 10 Apr 2009 10:46:42 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=104</guid>
		<description><![CDATA[There&#8217;s a bit of buzz on the python-ideas mailing list about Greg Ewing&#8217;s proposal for a new keyword &#8220;yield from&#8220;. He has made a draft PEP and patch for python 2.6.1. On short it adds syntactic sugar for generator decomposition and adds a &#8220;return value&#8221; statement in generators (the underlying mechanism for that is a [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=104&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>There&#8217;s a bit of buzz on the <a href="http://groups.google.com/group/python-ideas">python-ideas</a> mailing list about Greg Ewing&#8217;s <a href="http://www.cosc.canterbury.ac.nz/greg.ewing/python/yield-from/">proposal</a> for a new keyword &#8220;<code>yield from</code>&#8220;. He has made a draft PEP and patch for python 2.6.1.</p>
<p>On short it adds syntactic sugar for generator decomposition and adds a &#8220;<code>return value</code>&#8221; statement in generators (the underlying mechanism for that is a <code>StopIteration(value)</code> exception).</p>
<p>Here&#8217;s a straightforward example:</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; def g1():
...     print &quot;Starting g1&quot;
...     yield &quot;g1 ham&quot;
...     result = yield from g2()
...     print &quot;Got result: %r from g2&quot; % result
...     yield &quot;g1 eggs&quot;
...     print &quot;Finishing g1&quot;
...
&gt;&gt;&gt; def g2():
...     print &quot;Starting g2&quot;
...     yield &quot;g2 spam&quot;
...     yield &quot;g2 more spam&quot;
...     print &quot;Finishing g2&quot;
...     return &quot;foobar&quot;
...
&gt;&gt;&gt; for x in g1():
...     print &quot;Yielded&quot;, x
...
Starting g1
Yielded g1 ham
Starting g2
Yielded g2 spam
Yielded g2 more spam
Finishing g2
Got result: 'foobar' from g2
Yielded g1 eggs
Finishing g1
</pre>
<p>There are a bunch of other examples and tests bundled with Greg&#8217;s patch.</p>
<p>I got the patch and it works :). Had to manually rebuild the parser &#8211; make didn&#8217;t do it by itself and I had to run &#8220;<code>make Parser/pgen &amp; make Python/graminit.c &amp; make</code>&#8220;. I wonder why.</p>
<br /> Tagged: python <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/104/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=104&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2009/04/10/the-yield-from-proposal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>cogen and greenlets</title>
		<link>http://ionelmc.wordpress.com/2009/01/19/cogen-and-greenlets/</link>
		<comments>http://ionelmc.wordpress.com/2009/01/19/cogen-and-greenlets/#comments</comments>
		<pubDate>Sun, 18 Jan 2009 22:56:53 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cogen]]></category>
		<category><![CDATA[greenlets]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=97</guid>
		<description><![CDATA[I was playing these days with greenlets and I finally managed to find some time to make and coroutine implementation for cogen that uses the seamless stack switching of greenlets instead of the usual generator yield-based switching. The best part about this is that cogen could support any sort of old code that uses the [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=97&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I was playing these days with greenlets and I finally managed to find some time to make and coroutine implementation for cogen that uses the seamless stack switching of greenlets instead of the usual generator yield-based switching.</p>
<p>The best part about this is that cogen could support any sort of old code that uses the usual file or socket apis in the standard python library.</p>
<p>Unfortunately greenlets don&#8217;t work with python 2.6 right now; let me shamelessly quote this very <em>nice</em> reply I got from one of py.lib&#8217;s (greenlets are part of py.lib) maintainers:</p>
<blockquote><p>&#8220;I mean come on &#8211; it&#8217;s open source, if it works for me on 2.5 why I would bother too much?&#8221;</p></blockquote>
<p>For the love of god, is this the right attitude to run a project these days ?! I mean come on &#8230;</p>
<p>Anyhow, nevermind that.</p>
<p>So back to those coroutines using greenlets &#8211; I named them <em>corolets &#8211; </em>feels like a good name<em> </em>given the fact the the regular generator stuff is named with coroutine and there&#8217;s some need for distinction. I also added some socket wrappers in a module <em>socketlets </em>(<span style="color:#dddddd;">not </span>very inspired). It has a <em>Socket </em>class that provides regular blocking interface and makes use of the good old _fileobject class from the socket module in stdlib for the makefile stuff.</p>
<p>I got those 2 pieces in <a href="http://code.google.com/p/cogen/source/browse/trunk/cogen/magic/corolets.py">cogen.magic.corolets</a> and <a href="http://code.google.com/p/cogen/source/browse/trunk/cogen/magic/socketlets.py">cogen.magic.socketlets</a>. For those who didn&#8217;t understood much here&#8217;s an example:</p>
<pre class="brush: python; title: ; notranslate">
import sys

from cogen.core import schedulers
from cogen.magic.corolets import corolet, yield_
from cogen.magic import socketlets

@corolet
def server():
    srv = socketlets.Socket()
    adr = ('0.0.0.0', len(sys.argv)&gt;1 and int(sys.argv[1]) or 1200)
    srv.bind(adr)
    srv.listen(64)
    while 1:
        print &quot;Listening on&quot;, adr
        conn, addr = srv.accept()
        print &quot;Connection from %s:%s&quot; % addr
        m.add(handler, args=(conn, addr))

@corolet
def handler(sock, addr):
    fh = sock.makefile()
    fh.write(&quot;WELCOME TO ECHO SERVER !\r\n&quot;)
    fh.flush()

    while 1:
        line = fh.readline(1024)
        if line.strip() == 'exit':
            fh.write(&quot;GOOD BYE&quot;)
            fh.close()
            sock.close()
            return
        fh.write(line)
        fh.flush()

m = schedulers.Scheduler()
m.add(server)
m.run()
</pre>
<p>Compare that to the regular generator based example (don&#8217;t miss those yields):</p>
<pre class="brush: python; title: ; notranslate">
import sys

from cogen.core import sockets
from cogen.core import schedulers
from cogen.core.coroutines import coroutine

@coroutine
def server():
    srv = sockets.Socket()
    adr = ('0.0.0.0', len(sys.argv)&gt;1 and int(sys.argv[1]) or 1200)
    srv.bind(adr)
    srv.listen(64)
    while 1:
        print &quot;Listening on&quot;, adr
        conn, addr = yield srv.accept()
        print &quot;Connection from %s:%s&quot; % addr
        m.add(handler, args=(conn, addr))

@coroutine
def handler(sock, addr):
    fh = sock.makefile()
    yield fh.write(&quot;WELCOME TO ECHO SERVER !\r\n&quot;)
    yield fh.flush()

    while 1:
        line = yield fh.readline(1024)
        if line.strip() == 'exit':
            yield fh.write(&quot;GOOD BYE&quot;)
            yield fh.close()
            sock.close()
            return
        yield fh.write(line)
        yield fh.flush()

m = schedulers.Scheduler()
m.add(server)
m.run()
</pre>
<p>It&#8217;s pretty rough right now &#8211; I still need to add tests and check the performance, but I wanted to give an idea of what&#8217;s going on for the braver ones :)</p>
<br /> Tagged: cogen, greenlets, python <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/97/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/97/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=97&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2009/01/19/cogen-and-greenlets/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>ctypes based iocp proactor for cogen</title>
		<link>http://ionelmc.wordpress.com/2008/11/29/ctypes-based-iocp-proactor-for-cogen/</link>
		<comments>http://ionelmc.wordpress.com/2008/11/29/ctypes-based-iocp-proactor-for-cogen/#comments</comments>
		<pubDate>Fri, 28 Nov 2008 23:45:09 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cogen]]></category>
		<category><![CDATA[ctypes]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=85</guid>
		<description><![CDATA[I&#8217;ve finally mannaged to pull off a set of wrappers for using the raw windows iocp api using ctypes, namely wrappers for GetQueuedCompletionStatus, WSARecv, WSASend, AcceptEx, ConnectEx, TransmitFile and the whatever structs and utility calls they need. Writing the wrappers wasn&#8217;t that hard &#8211; but if you aren&#8217;t careful with ctypes you are in a [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=85&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve finally mannaged to pull off a set of wrappers for using the raw windows iocp api using ctypes, namely wrappers for GetQueuedCompletionStatus, WSARecv, WSASend, AcceptEx, ConnectEx, TransmitFile and the whatever structs and utility calls they need.</p>
<p>Writing the wrappers wasn&#8217;t that hard &#8211; but if you aren&#8217;t careful with ctypes you are in a world of gruesome crashes and at least 2 wasted evenings (read nights) debugging why the hell some random allocation fails. Well, for a fact, I still have no idea to why do I own those to wasted nights but thank god it doesn&#8217;t crash on my unittests anymore &#8211; I think I could have figured out why <a href="http://code.google.com/p/cogen/source/diff?spec=svn517&amp;r=514&amp;format=side&amp;path=/trunk/cogen/core/proactors/ctypes_iocp_impl/__init__.py&amp;old_path=/trunk/cogen/core/proactors/ctypes_iocp_impl/__init__.py&amp;old=509#sc_svn514_292">some</a> missing object cleanup resulted in weird crashes if I knew some ctypes internals but eh, I don&#8217;t :(</p>
<p>Take a look at the evil code <a href="http://code.google.com/p/cogen/source/browse/trunk/cogen/core/proactors/ctypes_iocp_impl/__init__.py">here</a> and <a href="http://code.google.com/p/cogen/source/browse/trunk/cogen/core/proactors/ctypes_iocp_impl/api_wrappers.py">here</a>, and punish me for doing such an evil thing with ctypes *malefic laugh* =]</p>
<p>Here&#8217;s a gem:</p>
<pre class="brush: python; title: ; notranslate">
#~ BOOL = SOCKET hSocket, HANDLE hFile, DWORD nNumberOfBytesToWrite, DWORD nNumberOfBytesPerSend, LPOVERLAPPED lpOverlapped,LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, DWORD dwFlags
TransmitFileType = WINFUNCTYPE(BOOL, SOCKET, HANDLE, DWORD, DWORD, POINTER(OVERLAPPED), POINTER(TRANSMIT_FILE_BUFFERS), DWORD)

def _GetTransmitFilePtr(given_socket=None):
    from socket import socket
    bogus_sock = given_socket or socket()
    bogus_bytes = DWORD()
    TransmitFile = TransmitFileType(0)
    ret = WSAIoctl(
        bogus_sock.fileno(), SIO_GET_EXTENSION_FUNCTION_POINTER, byref(WSAID_TRANSMITFILE), sizeof(WSAID_TRANSMITFILE),
        byref(TransmitFile), sizeof(TransmitFile), byref(bogus_bytes), None, None
    )
    return TransmitFile

TransmitFile = _GetTransmitFilePtr()
</pre>
<p>So far the new proactor works pretty nice in cogen.</p>
<br /> Tagged: cogen, ctypes, python <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/85/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=85&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/11/29/ctypes-based-iocp-proactor-for-cogen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Javascript-Flash socket bridge with haxe</title>
		<link>http://ionelmc.wordpress.com/2008/11/29/flash-socket-bridge-with-haxe/</link>
		<comments>http://ionelmc.wordpress.com/2008/11/29/flash-socket-bridge-with-haxe/#comments</comments>
		<pubDate>Fri, 28 Nov 2008 23:24:12 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[flash socket bridge]]></category>
		<category><![CDATA[haxe]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=80</guid>
		<description><![CDATA[There are a bunch of solutions for making a bridge to use the flash sockets (flash.net.Socket) in javascript, notably socketBridge and jssockets. But I didn&#8217;t like the way they made you write your client code: because you can&#8217;t pass javascript function references through the ExternalInterface you usually pass your callbacks as strings representing the name [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=80&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>There are a bunch of solutions for making a bridge to use the flash sockets (<a href="http://livedocs.adobe.com/flex/2/langref/flash/net/Socket.html">flash.net.Socket</a>) in javascript, notably <a href="http://matthaynes.net/blog/2008/07/17/socketbridge-flash-javascript-socket-bridge/">socketBridge</a> and <a href="http://code.google.com/p/jssockets/">jssockets</a>. But I didn&#8217;t like the way they made you write your client code: because you can&#8217;t pass javascript function references through the ExternalInterface you usually pass your callbacks as strings representing the name of an global object. IMHO, that just sucks so I&#8217;ve made my own mix named HaxeSocketBridge.</p>
<p>You can write the client code like this:</p>
<pre class="brush: jscript; title: ; notranslate">
    var s = new FlashSocket({
        on_data: function(data) {
            document.getElementById('datapanel').value = data;
        },
        on_io_error: function(msg) {
            alert(&quot;IO ERROR: &quot;+msg);
        },
        on_security_error: function(msg) {
            alert(&quot;SECURITY ERROR: &quot;+msg);
        },
        on_close: function(msg) {
            alert(&quot;Connection closed.&quot;);
        },
        on_connect: function() {
            s.write(&quot;GET / HTTP/1.0\r\n\r\n&quot;);
        }
    });
    s.connect('example.com', 80);
</pre>
<p><a href="http://ionel-whatever-code.googlecode.com/svn/trunk/HaxeSocketBridge/test.html">Here</a>&#8216;s the whole example.</p>
<p>How does it work? You can execute arbitrary javascript code though the external interface, so why not execute some boilerplate code and setup a global FlashSocket class that handles all the nasty actionscript-javascript communication.  I&#8217;ve seen this arguably good idea in the <a href="http://www.jimbojw.com/wiki/index.php?title=SWFHttpRequest.hx">SWFHttpRequest</a> bridge. If you do something like this be careful with those damn commas/semicolons or else you&#8217;re in i-dont-know-why-it-breaks hell :)</p>
<p>Here&#8217;s how the guts look like (note that the language is <a href="http://haxe.org/download">haxe</a>):</p>
<pre class="brush: jscript; title: ; notranslate">
        ExternalInterface.addCallback(&quot;connect&quot;, connect);
        ExternalInterface.addCallback(&quot;close&quot;, close);
        ExternalInterface.addCallback(&quot;write&quot;, write);
        ExternalInterface.addCallback(&quot;CAN_I_HAS_SOCKET&quot;, CAN_I_HAS_SOCKET);
        ExternalInterface.call([
        &quot;(function(){&quot;,
            &quot;if (window.FlashSocket) return;&quot;,
            &quot;var Class = function(properties){&quot;,
                &quot;var klass = function(event_handlers){ &quot;,
                    &quot;for (var p in event_handlers) {&quot;,
                        &quot;if (event_handlers.hasOwnProperty(p)) {&quot;,
                            &quot;this[p] = event_handlers[p];&quot;,
                        &quot;}&quot;,
                    &quot;}&quot;,
                    &quot;return this.init.apply(this);&quot;,
                &quot;};&quot;,
                &quot;klass.prototype = properties;&quot;,
                &quot;klass.constructor = arguments.callee;&quot;,
                &quot;return klass;&quot;,
            &quot;};&quot;,
            &quot;window.FlashSocket = new Class({&quot;,
                &quot;init: function(){&quot;,
                    &quot;this._instance = ''+window.FlashSocket._instances.length;&quot;,
                    &quot;window.FlashSocket._instances.push(this);&quot;,
                &quot;},&quot;,
                &quot;close: function(){ &quot;,
                    &quot;window.FlashSocket._instances[this._instance] = null;&quot;,
                    &quot;window.FlashSocket._bridge.close(this._instance );&quot;,
                &quot;},&quot;,
                &quot;write: function(data){ &quot;,
                    &quot;window.FlashSocket._bridge.write(this._instance, data);&quot;,
                &quot;},&quot;,
                &quot;connect: function(host, port) {&quot;,
                    &quot;window.FlashSocket._bridge.connect(this._instance, host, port);&quot;,
                &quot;}&quot;,
            &quot;});&quot;,
            &quot;window.FlashSocket._instances = [];&quot;,
            &quot;var f = function(tag){&quot;,
                &quot;var elems = document.getElementsByTagName(tag);&quot;,
                &quot;for (var i=0; i&lt;elems.length; i++) if (elems[i].CAN_I_HAS_SOCKET) return elems[i];&quot;,
            &quot;};&quot;,
            &quot;window.FlashSocket._bridge = f('embed') || f('object');&quot;,
        &quot;})&quot; ].join('') );
        if (flash.Lib.current.loaderInfo.parameters.onloadcallback != null)
            ExternalInterface.call(flash.Lib.current.loaderInfo.parameters.onloadcallback);
</pre>
<p>The trick is that we can setup a global javascript class-like object from the flash clip.</p>
<p>You can grab the code <a href="http://ionel-whatever-code.googlecode.com/svn/trunk/HaxeSocketBridge/">here</a>. Also, if you test from a local disc you might want to adjust your <a href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html">flash security settings</a>. To compile the .hx file run &#8220;<code>haxe compile.hxml</code>&#8220;.</p>
<p>Now, the only thing I miss is some buffering/readline logic.</p>
<br /> Tagged: flash, flash socket bridge, haxe, sockets <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/80/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=80&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/11/29/flash-socket-bridge-with-haxe/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>setuptools install_requires quirk</title>
		<link>http://ionelmc.wordpress.com/2008/11/03/setuptools-install_requires-quirk/</link>
		<comments>http://ionelmc.wordpress.com/2008/11/03/setuptools-install_requires-quirk/#comments</comments>
		<pubDate>Mon, 03 Nov 2008 20:36:43 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[setuptools]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=75</guid>
		<description><![CDATA[It&#8217;s interesting that having &#8220;dev&#8221; version packages in the install_requires list will fail. Say for example, if you do: It won&#8217;t work: I imagine it would match if the package would literally have the version &#8220;dev&#8221;. One solution is to change the install_requires to ["Pylons==dev,!=foo"] or some other bogus version to match whatever is downloaded [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=75&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>It&#8217;s interesting that having &#8220;<code>dev</code>&#8221; version packages in the <code>install_requires</code> list will fail.</p>
<p>Say for example, if you do:</p>
<pre class="brush: python; title: ; notranslate">
from setuptools import setup
setup(
...
install_requires=[&quot;Pylons==dev&quot;],
...
)
</pre>
<p>It won&#8217;t work:</p>
<pre class="brush: css; title: ; notranslate">
Installed d:\python25\lib\site-packages\pylons-0.9.7rc3dev_20081103-py2.5.egg
Reading http://www.pylonshq.com/download/0.9.7
error: Could not find required distribution Pylons==dev
</pre>
<p>I imagine it would match if the package would literally have the version &#8220;dev&#8221;.</p>
<p>One solution is to change the <code>install_requires</code> to <code>["Pylons==dev,!=foo"]</code> or some other bogus version to match whatever is downloaded for the <code>dev</code> version. &#8220;<code>&gt;=0.1.2.3</code>&#8221; will match for packages that don&#8217;t have tagged versions (won&#8217;t work for example for Pylons &#8220;0.9.7beta3dev-20080422&#8243;).</p>
<p>EDIT: Looks like I was wrong. having &#8220;!=foo&#8221; will work if you already have the package installed but will fail to find the dev package when downloading. Having &#8220;&gt;=0.9.7&#8243; in the requirements will not work because &#8220;0.9.7beta3dev-20080422&#8243; is considered a lower version (prerelease to the final 0.9.7). A solution would be having a requirement like &#8220;&gt;=0.9.7a&#8221;. &#8220;a&#8221; will be lower than &#8220;beta3dev-20080422&#8243;.</p>
<br /> Tagged: python, setuptools <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/75/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=75&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/11/03/setuptools-install_requires-quirk/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Functions are descriptors</title>
		<link>http://ionelmc.wordpress.com/2008/10/26/functions-are-descriptors/</link>
		<comments>http://ionelmc.wordpress.com/2008/10/26/functions-are-descriptors/#comments</comments>
		<pubDate>Sat, 25 Oct 2008 22:51:07 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=73</guid>
		<description><![CDATA[I didn&#8217;t knew that till i&#8217;ve read Ian&#8217;s post on decora-descriptors (I guess I can call them that). Actually it&#8217;s explained in more details here. On short, functions have the __get__ method that make them work as descriptors when they are in a class. I can do this: Neat ! Tagged: python<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=73&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I didn&#8217;t knew that till i&#8217;ve read Ian&#8217;s <a href="http://blog.ianbicking.org/2008/10/24/decorators-and-descriptors/">post</a> on decora-descriptors (I guess I can call them that). Actually it&#8217;s explained in more details <a href="http://blog.ianbicking.org/2008/10/24/decorators-and-descriptors/">here</a>.</p>
<p>On short, functions have the <code>__get__</code> method that make them work as descriptors when they are in a class.</p>
<p>I can do this:</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; class Bar:
...     pass
...
&gt;&gt;&gt; bar = Bar()
&gt;&gt;&gt;
&gt;&gt;&gt; def foo():
...     pass
...
&gt;&gt;&gt; foo
&lt;function foo at 0x00B6F270&gt;
&gt;&gt;&gt;
&gt;&gt;&gt; foo.__get__(None, Bar)
&lt;unbound method Bar.foo&gt;
&gt;&gt;&gt;
&gt;&gt;&gt; foo.__get__(bar, Bar)
&lt;bound method Bar.foo of &lt;__main__.Bar instance at 0x00BCB738&gt;&gt;
</pre>
<p>Neat !</p>
<br /> Tagged: python <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/73/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=73&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/10/26/functions-are-descriptors/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Giving up on Google Appengine</title>
		<link>http://ionelmc.wordpress.com/2008/09/23/giving-up-on-google-appengine/</link>
		<comments>http://ionelmc.wordpress.com/2008/09/23/giving-up-on-google-appengine/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 23:34:17 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[appengine]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=67</guid>
		<description><![CDATA[Quitter&#8217;s journal: After trying for half of week of getting some stuff going on appengine here is what I observed. The runtime is completely different. They do try however to patch the normal python runtime in the sdk to have the same characteristics as the runtime on their servers but differences fall through the cracks. [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=67&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Quitter&#8217;s journal: After <em>trying </em>for half of week of getting some stuff going on appengine here is what I observed.</p>
<p>The runtime is completely different. They do try however to patch the normal python runtime in the sdk to have the same characteristics as the runtime on their servers but differences fall through the cracks. The have some sort of qa process for the sdk (probably to compensate for these differences) &#8211; I bet it must be very cumbersome to maintain it.</p>
<p>In the sdk you have so little python libraries available and what makes matters worse is that they are outdated so you have to do additional evil monkey patching to use newer versions.</p>
<p>Ok, so I started with the idea of a django app &#8211; but I gave up when i found the one in the sdk is very old (0.96) and i still need to zip it (django slightly goes over the 1000 file limit). So if I start zipping stuff I might just as well do it the right way and use eggs and setuptools &#8211; well, I&#8217;ve moved to that idea and still didn&#8217;t work out due to the fact setuptools can <em>barely</em> run in the appengine runtime.</p>
<p>Also, thinking on the zips in retrospective &#8211; they aren&#8217;t such a great idea. Why the hell would i waste cpu cycles on zips ?</p>
<p>And speaking of the 1000 file limit, their filesystem must work real bad with many files.  Guido <a href="http://code.google.com/p/googleappengine/issues/detail?id=161#c38">said</a> on the file limit: &#8220;it exists because of the sheer number of apps. E.g. 1,000,000 apps == 1,000,000,000 files&#8221;. Is 1B files too much ? For Google !?</p>
<p>Come to think of it a bit, the only advantage of appengine is the fact is almost free.</p>
<p>LE: corrected the arithmetic.</p>
<br /> Tagged: appengine, python, rant <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/67/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=67&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/09/23/giving-up-on-google-appengine/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>On the future of cogen coroutine library</title>
		<link>http://ionelmc.wordpress.com/2008/09/15/on-the-future-of-cogen-coroutine-library/</link>
		<comments>http://ionelmc.wordpress.com/2008/09/15/on-the-future-of-cogen-coroutine-library/#comments</comments>
		<pubDate>Mon, 15 Sep 2008 08:03:49 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cogen]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=64</guid>
		<description><![CDATA[The major refactor of the socket stuff is finally in the trunk. The Socket is more in line with the standard socket module in python (there&#8217;s a makefile and a _fileobject for readline just like the standard library). And it looks like performance is still pretty good. The only things I can think of right [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=64&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>The <a href="http://ionelmc.wordpress.com/2008/06/05/rewrite-temptation/">major refactor</a> of the socket stuff is finally in the trunk. The Socket is more in line with the standard socket module in python (there&#8217;s a makefile and a _fileobject for readline just like the standard library). And it looks like performance is still pretty good.</p>
<p>The only things I can think of right now are the unittests for the socket stuff &#8211; they lack good coverage and they were actually made for the previous incompatible cogen socket api. They will be fixed eventually.</p>
<p>Another thing is that i&#8217;m trying to push some patches in the pywin32 module for win32file.TransmitFile and win32file.ConnectEx. But it&#8217;s going <a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1962146&amp;group_id=78018&amp;atid=551956">so slow</a> that I&#8217;m thinking it isn&#8217;t going to work out and I&#8217;d better write a separate module for the GetQueueCompletionStatus, CreateIoCompletionPort, WSASend, WSARecv, ConnectEx, TransmitFile and avoid all that insane overlapped <a href="http://pywin32.cvs.sourceforge.net/pywin32/pywin32/win32/src/win32file.i?view=markup#l_1065">struct hacking</a> that happens in the win32file module. Wadda ya think ?</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/64/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/64/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/64/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=64&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/09/15/on-the-future-of-cogen-coroutine-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Place your bets, Google vs Other browsers</title>
		<link>http://ionelmc.wordpress.com/2008/09/01/place-your-bets-google-vs-other-browsers/</link>
		<comments>http://ionelmc.wordpress.com/2008/09/01/place-your-bets-google-vs-other-browsers/#comments</comments>
		<pubDate>Mon, 01 Sep 2008 22:01:48 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[buzz]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=58</guid>
		<description><![CDATA[Google&#8217;s shiny new browser is almost here: Google Chrome based on WebKit. Featuring a sandbox model for tabs (tough I hope that sandbox will not be a complete process &#8211; as some speculate) and a &#8220;V8&#8243; javascript engine &#8211; according to Joshua &#8220;code is instantly interpreted into machine code&#8221;. Damn, where did he knew that [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=58&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Google&#8217;s shiny new browser is almost here: <a href="http://googleblog.blogspot.com/2008/09/fresh-take-on-browser.html">Google Chrome</a> based on WebKit.</p>
<p>Featuring a sandbox model for tabs (tough I hope that sandbox will not be a complete process &#8211; as some speculate) and a &#8220;V8&#8243; javascript engine &#8211; according to <a href="http://joshuajenkins.com/archives/google-chrome">Joshua</a> &#8220;code is instantly interpreted into machine code&#8221;. Damn, where did he knew that ? Really.</p>
<p>Surely will feature gears and other google mumbo-jumbo (some say it will even have a privacy feature ala IE8 aka the &#8220;porn mode&#8221;). I imagine it will be neat and fast but very unpolished &#8211; as the other google products launched in the &#8220;launch early and iterate&#8221; spirit. Speaking of, meh, app engine it&#8217;s still just a Toy.</p>
<p>I still put my money on the <a href="http://www.mozilla.org/projects/firefox/3.1a1/releasenotes/">Shiretoko</a>. (I hope I&#8217;m wrong tough)</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/58/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/58/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/58/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=58&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/09/01/place-your-bets-google-vs-other-browsers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Shortcuts again</title>
		<link>http://ionelmc.wordpress.com/2008/08/16/shortcuts-again/</link>
		<comments>http://ionelmc.wordpress.com/2008/08/16/shortcuts-again/#comments</comments>
		<pubDate>Sat, 16 Aug 2008 17:25:41 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[greasemonkey]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[userscript]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=51</guid>
		<description><![CDATA[I&#8217;ve added a manage bindings dialog and other minor improvements. Grab the userscript from http://userscripts.org/users/62351/scripts<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=51&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve added a manage bindings dialog and other minor improvements. Grab the userscript from <a href="http://userscripts.org/users/62351/scripts">http://userscripts.org/users/62351/scripts</a></p>
<p><img class="aligncenter" src="http://ionelmc.files.wordpress.com/2008/08/manage_dialog.png?w=665&#038;h=349" alt="" width="665" height="349" /></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/51/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/51/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/51/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=51&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/08/16/shortcuts-again/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>

		<media:content url="http://ionelmc.files.wordpress.com/2008/08/manage_dialog.png" medium="image" />
	</item>
		<item>
		<title>I&#8217;m a shortcut freako</title>
		<link>http://ionelmc.wordpress.com/2008/08/14/im-a-shortcut-freako/</link>
		<comments>http://ionelmc.wordpress.com/2008/08/14/im-a-shortcut-freako/#comments</comments>
		<pubDate>Thu, 14 Aug 2008 20:08:18 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[greasemonkey]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[shortcut]]></category>
		<category><![CDATA[userscript]]></category>
		<category><![CDATA[xpath]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=43</guid>
		<description><![CDATA[I like shortcuts, keyboard shortcuts. I like javascript. I have greasemonkey installed. I navigate lots of sites with buttons/links in uncomfortable positions. Therefore, I must definitely do something about it ! I&#8217;ve made a userscript that offers me a way to bind a key combination to a clickable element chosen by a xpath expression. It [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=43&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I like shortcuts, keyboard shortcuts. I like javascript. I have <a href="http://www.greasespot.net/">greasemonkey</a> installed. I navigate lots of sites with buttons/links in uncomfortable positions. Therefore, I must definitely do something about it !</p>
<p>I&#8217;ve made a userscript that offers me a way to bind a key combination to a clickable element chosen by a xpath expression. It still misses a way to easy edit previous bindings but I&#8217;ll provide it later, I promise!</p>
<p>You can still edit the bindings (well, more likely remove them) via about:config (the &#8216;greasemonkey.scriptvals.ShortcutBinder/Shortcut Binder.bindings&#8217; setting).</p>
<p>Grab the script from <a href="http://userscripts.org/scripts/show/31729">here</a>.</p>
<p>For a quick overview (bunch of screenshots) check this: <a href="http://code.google.com/p/webmonkey-userscripts/wiki/ShortcutBinder">http://code.google.com/p/webmonkey-userscripts/wiki/ShortcutBinder</a></p>
<p>Ah heck, here&#8217;s one quick and dirty:<img class="aligncenter" src="http://ionelmc.files.wordpress.com/2008/08/3.png?w=659&#038;h=539&#038;h=539" alt="" width="659" height="539" /></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/43/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/43/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/43/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=43&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/08/14/im-a-shortcut-freako/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>

		<media:content url="http://ionelmc.files.wordpress.com/2008/08/3.png?w=659&#38;h=539" medium="image" />
	</item>
		<item>
		<title>Finished my formal CS studies &#8211; quite disappointing</title>
		<link>http://ionelmc.wordpress.com/2008/07/10/finished-my-formal-cs-studies-quite-disappointing/</link>
		<comments>http://ionelmc.wordpress.com/2008/07/10/finished-my-formal-cs-studies-quite-disappointing/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 18:51:44 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[school]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=22</guid>
		<description><![CDATA[Finally ! After 4 years of half extremely boring lab-work and excruciating math exams i get a Computer Science diploma. Fuckintastic ! Was it worth it ? Well, for one thing, i get a diploma &#8211; we&#8217;ll see if that really helps me at anything at all. But did it learnt me anything? Little. Set [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=22&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Finally ! After 4 years of half extremely boring lab-work and excruciating math exams i get a Computer Science diploma. Fuckintastic !</p>
<p>Was it worth it ? Well, for one thing, i get a diploma &#8211; we&#8217;ll see if that really helps me at anything at all. But did it learnt me anything? Little.</p>
<p>Set aside the maths this faculty didn&#8217;t learn me shit. You don&#8217;t learn advanced stuff &#8211; from functional to unix programming everything is introductory stuff &#8211; you can finish the faculty with your head empty and your time wasted, easy. Just for a damn diploma.</p>
<p>You&#8217;ll even have to write a project for the diploma thesis, you&#8217;ll have to present it and at the end you&#8217;ll find yourself very unsatisfied because your <em>audience</em> will be clueless (they didn&#8217;t even know what a coroutine is, damn it !) and uninterested (they won&#8217;t even bother to read your paper that took time and effort).</p>
<p>I doubt working though the pile of arrogant, bored teachers &#8211; some not even deserving their degree &#8211; that don&#8217;t give a shit about you was worth giving 4 years of my life. I&#8217;m not saying not to do it &#8211; I&#8217;m saying to have <em>very low</em> expectations.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/22/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/22/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/22/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=22&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/07/10/finished-my-formal-cs-studies-quite-disappointing/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>First flex css hack</title>
		<link>http://ionelmc.wordpress.com/2008/07/08/first-flex-css-hack/</link>
		<comments>http://ionelmc.wordpress.com/2008/07/08/first-flex-css-hack/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 21:11:51 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=21</guid>
		<description><![CDATA[Well, might be not, might be the fact i&#8217;m just doing it wrong. I&#8217;m using flex 2. So here is the problem: I want to add sounds to buttons and whatever from css in a similar fasion to skinning.  I have a mess of all sorts of buttons everywhere and I don&#8217;t want to patch [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=21&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Well, might be not, might be the fact i&#8217;m just doing it wrong. I&#8217;m using flex 2.</p>
<p>So here is the problem: I want to add sounds to buttons and whatever from css in a similar fasion to skinning.  I have a mess of all sorts of buttons everywhere and I don&#8217;t want to patch all of them with a mouseOverEffect, mouseUpEffect or whatever.</p>
<p>I would think having a <code>&lt;mx:SoundEffect source="@Embed(source='blabla.mp3')" id="foo" /&gt;</code> would make this snippet work (but it doesn&#8217;t):</p>
<pre class="brush: css; title: ; notranslate">
Button {
    mouseOverEffect: foo; /* neither does &quot;foo&quot; */
}
</pre>
<p>So what to do ? StyleManager and CSSStyleDeclaration perhaps.</p>
<pre class="brush: jscript; title: ; notranslate">
var myDynStyle:CSSStyleDeclaration;
myDynStyle = new CSSStyleDeclaration('Button');
myDynStyle.setStyle(&quot;mouseUpEffect&quot;, Sounds.clickButtonEffect);
StyleManager.setStyleDeclaration(&quot;Button&quot;, myDynStyle, true);
</pre>
<p>This is very cool. Allows me to set behaviors (via Effects) on whatever object classes.<br />
Except it doesn&#8217;t work.</p>
<p>I&#8217;ve discovered by accident that setting those effect props to some bogus values in the css beforehand (like <code>Button { mouseUpEffect: none; }</code>) makes that programmatic styling work. </p>
<p>I wonder if this is a flex bug, though by the looks of it seems that is a compile-time vs run-time issue &#8211; some stuff that makes the effect work on the buttons is setted only on compile time?</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/21/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/21/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/21/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=21&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/07/08/first-flex-css-hack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Rewrite temptation</title>
		<link>http://ionelmc.wordpress.com/2008/06/05/rewrite-temptation/</link>
		<comments>http://ionelmc.wordpress.com/2008/06/05/rewrite-temptation/#comments</comments>
		<pubDate>Thu, 05 Jun 2008 05:57:53 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cogen]]></category>
		<category><![CDATA[ramblings]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=20</guid>
		<description><![CDATA[Well, not exactly a rewrite, merely a major internal refactor. The thought of cleaning up the socket and reactor internals really nags me. I would move the platform dependant code from the sockets module in the reactors &#8211; so, say, the reactors would have the platform specific code for recv, send, connect, accept instead of [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=20&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Well, not exactly a rewrite, merely a major internal refactor.</p>
<p>The thought of cleaning up the socket and reactor internals really nags me. I would move the platform dependant code from the sockets module in the reactors &#8211; so, say, the reactors would have the platform specific code for recv, send, connect, accept instead of each socket operation class. Also, the fact is that the iocp was added later and the code was <em>patched</em> to support a what was a design scheme based on a reactor pattern &#8211; so adding support for another proactor based api (say, linux&#8217;s aio) would really mudge the internals. Also, moving the readline stuff out of the socket operations in a coroutine would make things real fancy and easy to follow.</p>
<p>Meh, on second thought, i would not have real gain, besides making more easy to add support for another proactor api like aio (wich btw just sucks, it wasn&#8217;t made for sockets &#8211; no support for accept or connect) and priding myself for the fancier internals i would probably get lower performance &#8211; and I still have yet to fine tune the performance part.</p>
<p>Now that I have relieved myself I&#8217;d better concentrate myself on that diploma thesis. =]</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/20/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/20/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/20/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=20&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/06/05/rewrite-temptation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>ClearType is for color blind people</title>
		<link>http://ionelmc.wordpress.com/2008/05/01/cleartype-is-for-color-blind-people/</link>
		<comments>http://ionelmc.wordpress.com/2008/05/01/cleartype-is-for-color-blind-people/#comments</comments>
		<pubDate>Thu, 01 May 2008 22:26:39 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cleartype]]></category>
		<category><![CDATA[fonts]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=15</guid>
		<description><![CDATA[I was going to title it as &#8216;ClearType sucks&#8217; but anyway. ClearType uses a technique named subpixel rendering that absolutely sucks &#8211; at least for me. Say for example i have some black text on white background then the subpixel rendering will make some adjacent pixels have some colors. Take a example, Consolas, a font [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=15&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I was going to title it as &#8216;ClearType sucks&#8217; but anyway.</p>
<p>ClearType uses a technique named subpixel rendering that absolutely sucks &#8211; at least for me. Say for example i have some black text on white background then the subpixel rendering will make some adjacent pixels have some colors. Take a example, Consolas, a font that works only with ClearType:<br />
<img class="aligncenter" src="http://upload.wikimedia.org/wikipedia/commons/3/3f/Consolas-cleartype.png" alt="Consolas ClearType sample" /><br />
That just looks painful for my eyes, i see every colored pixel in something that should had been only black and white (or gray at least) &#8211; it&#8217;s just friggin painful. If you don&#8217;t notice it (well, I might see better than you) look here:<br />
<a href="http://ionelmc.files.wordpress.com/2008/05/wtf-subpixel2.png"><img class="aligncenter size-full wp-image-18" src="http://ionelmc.files.wordpress.com/2008/05/wtf-subpixel2.png?w=595" alt="What\'s with all the colors?!"   /></a><br />
And I&#8217;m not just running on crap hardware &#8211; I think a <a href="http://www.dell.com/content/products/productdetails.aspx/monitor_2407wfp-hc?c=us&amp;l=en&amp;s=corp">Dell 2407WPF-HC</a> is good enough !</p>
<p>I&#8217;ve also tried to <a href="http://www.microsoft.com/typography/ClearTypePowerToy.mspx">tune </a>the ClearType a bit and it still looks like crap.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/15/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/15/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/15/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=15&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/05/01/cleartype-is-for-color-blind-people/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>

		<media:content url="http://upload.wikimedia.org/wikipedia/commons/3/3f/Consolas-cleartype.png" medium="image">
			<media:title type="html">Consolas ClearType sample</media:title>
		</media:content>

		<media:content url="http://ionelmc.files.wordpress.com/2008/05/wtf-subpixel2.png" medium="image">
			<media:title type="html">What\&#039;s with all the colors?!</media:title>
		</media:content>
	</item>
		<item>
		<title>comet chat in pylons (with cogen)</title>
		<link>http://ionelmc.wordpress.com/2008/04/29/comet-chat-in-pylons-with-cogen/</link>
		<comments>http://ionelmc.wordpress.com/2008/04/29/comet-chat-in-pylons-with-cogen/#comments</comments>
		<pubDate>Tue, 29 Apr 2008 20:01:46 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cogen]]></category>
		<category><![CDATA[comet]]></category>
		<category><![CDATA[pylons]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=14</guid>
		<description><![CDATA[There is something very cool about wsgi: asynchronicity at it&#8217;s core ! The spec was made with this in mind &#8211; I absolutely love wsgi. I&#8217;ve been playing recently with pylons and i&#8217;ve made a example chat app &#8211; just a proof-of-concept comet application with long pooling in a pylons app using a custom wsgi [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=14&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>There is something very cool about wsgi: asynchronicity at it&#8217;s core ! The spec was made with this in mind &#8211; I absolutely love wsgi.</p>
<p>I&#8217;ve been playing recently with pylons and i&#8217;ve made a example chat app &#8211; just a proof-of-concept comet application with long pooling in a pylons app using a custom wsgi server (cogen.wsgi).</p>
<p><a href="http://ionelmc.files.wordpress.com/2008/04/chat-sample.png"><img class="alignnone size-medium wp-image-13" src="http://ionelmc.files.wordpress.com/2008/04/chat-sample.png?w=300&#038;h=219" alt="" width="300" height="219" /></a></p>
<p>Here&#8217;s the controller code that give me a feeling I will be burned to the stake for too much magic. =]</p>
<pre class="brush: python; title: ; notranslate">
import logging

from pylons import request, response, session
from pylons import tmpl_context as c
from pylons.controllers.util import abort, redirect_to, url_for

from chatapp.lib.base import BaseController
# import chatapp.model as model

log = logging.getLogger(__name__)
from cogen.core import queue, events
from cogen.core.coroutines import coro
from cogen.core.pubsub import PublishSubscribeQueue
pubsub = PublishSubscribeQueue()

class Client:
    def __init__(self):
        self.messages = queue.Queue(10)
        self.dead = False
    @coro
    def watch(self):
        &quot;&quot;&quot;This is a coroutine that runs permanently for each participant to the
        chat. If the participant has more than 10 unpulled messages this
        coroutine will die.

        `pubsub` is a queue that hosts the messages from all the
        participants.
          * subscribe registers this coro to the queue
          * fetch pulls the recent messages from the queue or waits if there
        are no new ones.

        self.messages is another queue for the frontend comet client (the
        pull action from the ChatController will pop messages from this queue)
        &quot;&quot;&quot;
        yield pubsub.subscribe()
        while 1:
            messages = yield pubsub.fetch()
            try:
                yield self.messages.put_nowait(messages)
            except:
                print 'Client %s is dead.' % self
                self.dead = True
                break
class ChatController(BaseController):

    def push(self):
        &quot;&quot;&quot;This action puts a message in the global queue that all the clients
        will get via the 'pull' action.&quot;&quot;&quot;
        yield request.environ['cogen.call'](pubsub.publish)(
            &quot;%X: %s&quot; % (id(session['client']), request.body)
        )
        # the request.environ['cogen.*'] objects are the the asynchronous
        # wsgi extensions offered by cogen - basicaly they do some magic to
        # make the code here work as a coroutine and still work with any
        # middleware
        yield str(request.environ['cogen.wsgi'].result)

    def pull(self):
        &quot;&quot;&quot;This action does some state checking (adds a object in the session
        that will identify this chat participant and adds a coroutine to manage
        it's state) and gets new messages or bail out in 10 seconds if there are
        no messages.&quot;&quot;&quot;
        if not 'client' in session or session['client'].dead:
            client = Client()
            print 'Adding new client:', client
            session['client'] = client
            session.save()
            yield request.environ['cogen.core'].events.AddCoro(client.watch)
        else:
            client = session['client']

        yield request.environ['cogen.call'](client.messages.get)(timeout=10)

        if isinstance(request.environ['cogen.wsgi'].result, events.OperationTimeout):
            pass
        elif isinstance(request.environ['cogen.wsgi'].result, Exception):
            import traceback
            traceback.print_exception(*request.environ['cogen.wsgi'].exception)
        else:
            yield &quot;%s\r\n&quot;% '\r\n'.join(request.environ['cogen.wsgi'].result)
</pre>
<p>The frontend code is fairly simple:</p>
<pre class="brush: xml; title: ; notranslate">
    &lt;h1&gt;chat powered by &lt;a href=&quot;http://code.google.com/p/cogen/&quot;&gt;cogen&lt;/a&gt;&lt;/h1&gt;
    &lt;form name=&quot;chat&quot;&gt;
    &lt;textarea id=&quot;ouput&quot; name=&quot;output&quot; rows=&quot;10&quot; cols=&quot;80&quot; readonly=&quot;readonly&quot;&gt;&lt;/textarea&gt;&lt;br/&gt;
    &lt;input id=&quot;tosend&quot; name=&quot;tosend&quot; value=&quot;&quot; size=&quot;80&quot;/&gt;
    &lt;/form&gt;
&lt;script language=&quot;javascript&quot;&gt;
    function xhr(url, callback, data) {
        var req = window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHTTP');
        req.onreadystatechange = function() {
            if (req.readyState == 4) {
                if (callback) callback(req);
            }
        }
        req.open(data?&quot;POST&quot;:&quot;GET&quot;, url, true);
        req.send(data);
    }
    function pull(req) {
        if(req.status == 200) {
            document.chat.output.value = req.responseText + document.chat.output.value;
            xhr('/chat/pull', pull)
        } else {
            alert(req.responseText);
        }
    }
    xhr('/chat/pull', pull);
    document.chat.tosend.onkeydown = function (event) {
        event = event || window.event;
        var key = event.which || event.keyCode;
        if (key == 13) {
            xhr('/chat/push', null, document.chat.tosend.value);
            document.chat.tosend.value = '';
        }
    }
    document.chat.onsubmit = function() { return false; }
&lt;/script&gt;
</pre>
<p>I think the javascript part looks fairly obvious, but the controller uses a bunch of magic &#8211; here&#8217;s the workflow:</p>
<ul>
<li>a client load the page and calls the <em>pull </em>page via xhr</li>
<li>the <em>pull</em> page waits 10 sencond for a new message to be posted in the <em>messages</em> queue</li>
<li>another client sends a message via <em>push</em><strong> </strong>page via xhr</li>
<li>the <em>push</em> page adds the message in the <em>pubsub</em> queue</li>
<li>the coroutines (the &#8216;watch&#8217; methods) are waken up and get the new message from the fetch() calls</li>
<li>each &#8216;watch&#8217; coroutine posts that message in the client&#8217;s queue (via <em>messages</em>.put_nowait)</li>
<blockquote>
<li>also, the <em>messages</em> queue is limited to 10 messages so if there are 10 updates and a client doesn&#8217;t get them it&#8217;s associated &#8216;watch&#8217; coroutine will die</li>
</blockquote>
<li></li>
<li>each loading <em>pull</em> page gets that message (via <em>messages</em>.get(timeout=10)) and send it to the client</li>
</ul>
<p>The fairly <a href="http://code.google.com/p/cogen/wiki/Docs_Cogen">obscure cogen docs </a>might also be helpfull :)</p>
<p>Almost forgot, to run this you need a trunk version of cogen (easy_install cogen==dev or check out <a href="http://cogen.googlecode.com/svn/trunk/">http://cogen.googlecode.com/svn/trunk/</a>)<br />
and the ChatApp example (you can view all the code <a href="http://code.google.com/p/cogen/source/browse/trunk/examples/cogen-chat/ChatApp/">here</a> and get it from <a href="http://cogen.googlecode.com/svn/trunk/examples/cogen-chat/">here</a>)</p>
<p>Once you have installed cogen (easy_install or <code>setup.py develop</code>), install the ChatApp (<code>setup.py develop</code>) and start the app with <code>paster serve test.ini</code>. And try finding some bugs (just joking) at <a href="http://127.0.0.1:5000/" rel="nofollow">http://127.0.0.1:5000/</a></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/14/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/14/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/14/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=14&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/04/29/comet-chat-in-pylons-with-cogen/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>

		<media:content url="http://ionelmc.files.wordpress.com/2008/04/chat-sample.png?w=300" medium="image" />
	</item>
		<item>
		<title>setuptools + nosetests oddness</title>
		<link>http://ionelmc.wordpress.com/2008/04/24/setuptools-nosetests-oddness/</link>
		<comments>http://ionelmc.wordpress.com/2008/04/24/setuptools-nosetests-oddness/#comments</comments>
		<pubDate>Thu, 24 Apr 2008 06:52:27 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[nose]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[setuptools]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=11</guid>
		<description><![CDATA[Looks like using setuptools&#8217;s test runner (eg, run python setup.py test) with the nose.collector has some weird issues &#8211; well, unexpected, for me at least. I was using nose with coverage via &#8211;with-coverage option to get some cover reports. But setup.py test borked with &#8220;setup.py: error: no such option: &#8211;cover-package&#8221;. After some digging in the [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=11&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Looks like using setuptools&#8217;s test runner (eg, run <code>python setup.py test</code>) with the nose.collector has some weird issues &#8211; well, unexpected, for me at least.</p>
<p>I was using nose with coverage via &#8211;with-coverage option to get some cover reports. But setup.py test borked with &#8220;setup.py: error: no such option: &#8211;cover-package&#8221;. After some digging in the sources i&#8217;ve found that some plugins aren&#8217;t compatible with setuptools&#8217;s test runner &#8211; you can&#8217;t run post test hooks with that runner apparently (sadly, the coverage plugin is one of them). I wish setuptools had a option to ignore bogus options and show only a warning &#8211; well, on second thought, that&#8217;s not setuptools related at all, the error is raised from optparse.</p>
<p>Luckily, setuptools has aliases for commands and instead of </p>
<pre class="brush: python; title: ; notranslate">
[nosetests]
with-coverage = 1
cover-package = cogen
</pre>
<p>I can do: </p>
<pre class="brush: python; title: ; notranslate">
[aliases]
test = nosetests --cover-package=cogen --with-coverage
</pre>
<p>in setup.cfg.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/11/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/11/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/11/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=11&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/04/24/setuptools-nosetests-oddness/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Qt reactor in cogen</title>
		<link>http://ionelmc.wordpress.com/2008/04/20/qt-reactor-in-cogen/</link>
		<comments>http://ionelmc.wordpress.com/2008/04/20/qt-reactor-in-cogen/#comments</comments>
		<pubDate>Sun, 20 Apr 2008 11:06:00 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cogen]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[qt]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=10</guid>
		<description><![CDATA[I&#8217;ve implemented a reactor to integrate the cogen loop in the qt main loop. You whould use it like this: Though the reactor isn&#8217;t tested, well, unittested &#8211; i have a bunch of tests to keep the code sane. The problem is that Qt is a big nasty monolithic framework, well, it&#8217;s nice if you [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=10&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve implemented a reactor to integrate the cogen loop in the qt main loop.</p>
<p>You whould use it like this:</p>
<pre class="brush: python; title: ; notranslate">
from PyQt4 import QtGui

app = QtGui.QApplication([])
hello = QtGui.QPushButton( &quot;Hello world!&quot; )
hello.resize(100, 30)
hello.show()

from cogen.core import reactors, schedulers
m = schedulers.Scheduler(reactor=reactors.QtReactor)

def lorem_ipsum_app(environ, start_response):
    start_response('200 OK', [('Content-type','text/plain'), ('Content-Length','19')])
    return ['Lorem ipsum dolor..']

server = wsgi.WSGIServer(
  ('0.0.0.0', 9001),
  lorem_ipsum_app,
  m,
)
m.add(server.serve)
m.run()
# voila ! this actualy runs the QApplication loop with the cogen hooks
</pre>
<p>Though the reactor isn&#8217;t tested, well, unittested &#8211; i have a bunch of tests to keep the code sane.<br />
The problem is that Qt is a big nasty monolithic framework, well, it&#8217;s nice if you don&#8217;t need to do any weird stuff &#8211; like running the main application loop in a second thread.</p>
<p>I just don&#8217;t understand why they made this ugly limitation in qt: the application loop must run in the main thread. I&#8217;ll fix those tests somehow, but in the meanwhile i&#8217;ll just continue cursing Qt for making me feel miserable about my unittests.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/10/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/10/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/10/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=10&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/04/20/qt-reactor-in-cogen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Twitter fails at teh interwebs</title>
		<link>http://ionelmc.wordpress.com/2008/04/19/twitter-fails-at-teh-interwebs/</link>
		<comments>http://ionelmc.wordpress.com/2008/04/19/twitter-fails-at-teh-interwebs/#comments</comments>
		<pubDate>Sat, 19 Apr 2008 02:37:40 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=9</guid>
		<description><![CDATA[I mean really, i would run a development site like that. I wonder where they learnt to do web programming since I see a bunch of failures: javascripts aren&#8217;t concatenated, not even compressed &#8211; a lot of unnecessary http requests. static content doesn&#8217;t have proper caching headers &#8211; more unnecessary http requests. slow servers &#8211; [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=9&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I mean really, i would run a development site like that. I wonder where they learnt to do web programming since I see a bunch of failures:</p>
<ul>
<li>javascripts aren&#8217;t concatenated, not even compressed &#8211; a lot of unnecessary http requests.</li>
<li>static content doesn&#8217;t have proper caching headers &#8211; more unnecessary http requests.</li>
<li>slow servers &#8211; i mean really, amazon aws might be cool and neato, but really slow &#8211; i just want my page loaded in 300ms.</li>
</ul>
<p>And those are barely a scratch on the surface &#8211; there&#8217;s a lot of stuff that can be done towards a faster page.</p>
<p>Yes, I&#8217;m the cranky user that doesn&#8217;t like pages that load in 5seconds (yes, 5 god damn seconds!).</p>
<p>Sorry twitter &#8211; you suck. I hope your developers will fix you though &#8211; don&#8217;t worry, I have other stuff to waste my time on.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/9/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/9/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/9/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=9&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/04/19/twitter-fails-at-teh-interwebs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>That history meme</title>
		<link>http://ionelmc.wordpress.com/2008/04/14/that-history-meme/</link>
		<comments>http://ionelmc.wordpress.com/2008/04/14/that-history-meme/#comments</comments>
		<pubDate>Mon, 14 Apr 2008 15:29:08 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=8</guid>
		<description><![CDATA[Python version, shorter than Paddy&#8216;s version: Still not shorter than the bash version:<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=8&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Python version, shorter than <a href="http://paddy3118.blogspot.com/2008/04/that-history-meme-in-python.html">Paddy</a>&#8216;s version:</p>
<pre class="brush: python; title: ; notranslate">
# history|python -c'import sys;c=[i.split()[1] for i in sys.stdin]; [sys.stdout.write(&quot;%s %s\n&quot;%x) for x in sorted(set((c.count(i),i) for i in c), key=lambda (a,b):a)[::-1][:10]]'
198 python
71 ab
37 cat
36 /root/python/bin/python
31 cd
21 nc
21 strace
10 echo
9 history
8 easy_install
</pre>
<p>Still not shorter than the bash version:</p>
<pre class="brush: ruby; title: ; notranslate">
history|awk '{a[$2]++} END{for(i in a){print a[i]&quot; &quot;i}}'|sort -rn|head
</pre>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/8/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/8/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=8&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/04/14/that-history-meme/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>cogen and pylons can play !</title>
		<link>http://ionelmc.wordpress.com/2008/04/11/cogen-and-pylons-can-play/</link>
		<comments>http://ionelmc.wordpress.com/2008/04/11/cogen-and-pylons-can-play/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 16:28:03 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cogen]]></category>
		<category><![CDATA[comet]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=6</guid>
		<description><![CDATA[Just so you know, cogen is a coroutine framework (based on the bidirectional generators from python 2.5) that has a wsgi server with some async extensions. Straight to the point, i&#8217;m going to show the basics by building the backend of a web based (with comet-style ajax) irc client. This is a proof of concept [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=6&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<blockquote><p>Just so you know, <a href="http://code.google.com/p/cogen/">cogen </a>is a coroutine framework (based on the bidirectional generators from python 2.5) that has a wsgi server with some async extensions.</p></blockquote>
<p>Straight to the point, i&#8217;m going to show the basics by building the backend of a web based (with comet-style ajax) irc client. This is a proof of concept and the javascript part of the app will come in a future blog post.</p>
<p>So a async app with cogen works like a streaming app in pylons. Everything is fine if you don&#8217;t use middleware that consumes the appiter (sadly, the ErrorHandler middleware does just that &#8211; and it can&#8217;t be fixed becouse you can&#8217;t report a error after you sent a part of the response to the client).</p>
<p>Grab the latest TIP from pylons (get <a href="http://www.selenic.com/mercurial/wiki/index.cgi/BinaryPackages">Mercurial </a>first):</p>
<pre>hg clone https://www.knowledgetap.com/hg/pylons-dev Pylons</pre>
<p>Grab the latest trunk from paste:</p>
<pre>svn co http://svn.pythonpaste.org/Paste/trunk Paste</pre>
<p>Grab the latest trunk from cogen:</p>
<pre>svn co http://cogen.googlecode.com/svn/trunk/ cogen</pre>
<p>Ok, so install them (usualy a python setup.py develop). Next thing you make a pylons app (paster create -t pylons). And you need to make just 2 changes to de middeware config:</p>
<p>In middleware.py comment out the error middleware like this:</p>
<pre class="brush: python; title: ; notranslate">
# Handle Python exceptions
#~ app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
</pre>
<p>and change the Registry to work with streaming apps:</p>
<pre class="brush: python; title: ; notranslate">
# Establish the Registry for this application
app = RegistryManager(app, streaming=True)
</pre>
<p>You need to change the development.ini, just replace the server:main section with this:</p>
<pre class="brush: python; title: ; notranslate">
[server:main]
use = egg:cogen#http
host = 0.0.0.0
port = 5000
</pre>
<p>Allright, now add a controller (<code>paster controller irc</code>, or something like that). So we&#8217;ll make something extremely simple: we&#8217;ll write a relay that just passes the messages from the server to the client in json format with a timeout of 30 seconds when there no messages arrive (that&#8217;s our comet long-poll update).</p>
<p>Just put this code in controllers/irc.py:</p>
<pre class="brush: python; title: ; notranslate">
import logging

from pylons import request, response, session
from pylons import tmpl_context as c
from pylons.controllers.util import abort, redirect_to, url_for
from pylons.decorators import validate
from formencode import validators
from cogenircapp.lib.base import BaseController
import cogenircapp.model as model

log = logging.getLogger(__name__)

from cogen.core.coroutines import coro, debug_coroutine
from cogen.core import events, sockets
from cogen.core.util import priority
from cogen.core import queue
from cogen.web import async

import simplejson

def parsemsg(s): # stolen from twisted.words
    &quot;&quot;&quot;Breaks a message from an IRC server into its prefix, command, and arguments.
    &quot;&quot;&quot;
    prefix = ''
    trailing = []
    if not s:
        raise Exception(&quot;Empty line.&quot;)
    if s[0] == ':':
        prefix, s = s[1:].split(' ', 1)
    if s.find(' :') != -1:
        s, trailing = s.split(' :', 1)
        args = s.split()
        args.append(trailing)
    else:
        args = s.split()
    command = args.pop(0)
    return prefix, command, args

class Connection:
    def __init__(self, server, reconnect_interval=60, sock_timo=15):
        self.server = server
        self.reconnect_interval = reconnect_interval
        self.connected = False
        self.sock_timo = sock_timo
        self.events = queue.Queue(25) # Max 25 pending events, well, messages
                    # from the server. After that we'll lose the connection.

    @coro
    def pull(self):
        &quot;&quot;&quot;This coroutine handles the server connection, does a basic parse on
        the received messages and put them in a queue named events.
        The controllers pull method will take the messages from that queue.
        &quot;&quot;&quot;
        self.sock = sockets.Socket()
        while not self.connected:
            try:
                addr = self.server.split(':')
                if len(addr) &lt; 2:
                    addr.append(6667)
                else:
                    addr[1] = int(addr[1])
                yield self.events.put_nowait(('', 'CONNECTING', ''))
                yield self.sock.connect(tuple(addr), timeout=self.sock_timo)
                self.connected = True
            except events.OperationTimeout, e:
                yield self.events.put_nowait(('', 'CONNECT_TIMEOUT', str(e)))
                yield events.Sleep(self.reconnect_interval)

        yield self.events.put_nowait(('', 'CONNECTED', ''))
        while 1:
            try:
                line = yield self.sock.readline(8192)
                prefix, command, params = parsemsg(line)
                yield self.events.put_nowait((prefix, command, params))
            except Exception, e:
                yield self.events.put_nowait(('', 'ERROR', str(e)))
                break

from pylons.templating import render_mako as render

class IrcController(BaseController):
    &quot;&quot;&quot;
    This controller supports multiple server connections.
    &quot;&quot;&quot;
    def index(self):
        if 'connections' not in session:
            session['connections'] = {}
            session.save()
        return render('index.mako')

    def push(self, id):
        &quot;Sends a message to the specified connection (id)&quot;
        conn = session['connections'].get(id, None)
        if conn:
            yield request.environ['cogen.core'].sockets.WriteAll(conn.sock,
                            request.environ['wsgi.input'].read() +'\r\n')
            if isinstance(request.environ['cogen.wsgi'].result, Exception):
                yield simplejson.dumps(('', 'ERROR', str(e)))
            else:
                yield simplejson.dumps(('', 'PUSH_OK', ''))
        else:
            yield simplejson.dumps(('', 'ERROR', 'Invalid connection id.'))

    def connect(self, server):
        &quot;Connects to a server and return a connection id.&quot;
        conns = session['connections']
        id = str(len(conns))
        conn = Connection(server)
        conns[id] = conn
        yield request.environ['cogen.core'].events.AddCoro(conn.pull)
        yield id

    def pull(self, id):
        &quot;&quot;&quot;Take the messages from the queue and if there are none wait 30
        seconds till returning an empty message.

        Also, cogen's wsgi async extensions are in the environ and prefixed with
        'cogen.'
        &quot;&quot;&quot;
        conn = session['connections'].get(id, None)
        if conn:
            ev_list = []
            while 1:
                # ok, so this might look a bit ugly but the concept is very simple
                #  you yield a special object from the environ that does some magic
                #  and the wsgi server will resume the app when it has the result
                yield request.environ['cogen.call'](conn.events.get_nowait)()
                event = request.environ['cogen.wsgi'].result
                # also, we can't have better exception handling in this wsgi
                # contraption and we need to check the result for exceptions
                if isinstance(event, queue.Empty):
                    break
                elif isinstance(event, Exception):
                    ev_list.append(('', 'ERROR', str(event)))
                    break
                else:
                    ev_list.append(event)
            if ev_list:
                yield simplejson.dumps(ev_list)
            else:
                # if we don't have any updates atm, we'll wait 30 secs for one
                yield request.environ['cogen.call'](conn.events.get)(timeout=30)
                event = request.environ['cogen.wsgi'].result
                if isinstance(event, events.OperationTimeout):
                    yield simplejson.dumps([])
                elif isinstance(event, Exception):
                    yield simplejson.dumps([('', 'ERROR', str(event))])
                else:
                    yield simplejson.dumps([event])
        else:
            yield simplejson.dumps(('', 'ERROR', 'Invalid connection id.'))

</pre>
<p>For the frontend i&#8217;m thinking to use YUI. I&#8217;ll have it finished in a couple of days.</p>
<p>LE: sources are at: <a href="https://cogen.googlecode.com/svn/trunk/examples/cogen-irc" rel="nofollow">https://cogen.googlecode.com/svn/trunk/examples/cogen-irc</a> though the javascript interface needs polishing (a lot of it to get blog-post worthy).</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/6/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/6/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/6/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=6&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/04/11/cogen-and-pylons-can-play/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>Curious difference between epoll, poll, kqueue and select</title>
		<link>http://ionelmc.wordpress.com/2008/04/01/curious-difference-between-epoll-poll-kqueue-and-select/</link>
		<comments>http://ionelmc.wordpress.com/2008/04/01/curious-difference-between-epoll-poll-kqueue-and-select/#comments</comments>
		<pubDate>Tue, 01 Apr 2008 03:57:37 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/?p=4</guid>
		<description><![CDATA[Suppose you have a brand new nonblocking socket and you want to do something with it (i have a connect in mind &#8211; but it&#8217;s irrelevant anyway). So what is your obvious choice for that since the socket is non-blocking ? Use select or poll or whatever ofcourse. Right? NO. Sadly they don&#8217;t work the [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=4&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Suppose you have a brand new nonblocking socket and you want to do something with it (i have a connect in mind &#8211; but it&#8217;s irrelevant anyway). So what is your obvious choice for that since the socket is non-blocking ? Use select or poll or whatever ofcourse. Right? NO.</p>
<p>Sadly they don&#8217;t work the same with unconnected sockets &#8211; i wonder why.</p>
<p>select (win32):</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; import select, socket
&gt;&gt;&gt; s = socket.socket()
&gt;&gt;&gt; select.select([s], [s], [s], 1)
([], [], [])</pre>
<p>select (linux):</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; import select, socket
&gt;&gt;&gt; s = socket.socket()
&gt;&gt;&gt; select.select([s], [s], [s], 1)
([&lt;socket._socketobject&gt;], [&lt;socket._socketobject&gt;], [])</pre>
<p>select (freebsd):</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; import select, socket
&gt;&gt;&gt; s = socket.socket()
&gt;&gt;&gt; select.select([s], [s], [s], 1)
([], [], [])</pre>
<p>Pretty inconsistent eh?poll (linux):</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; import select, socket
&gt;&gt;&gt; poll = select.poll()
&gt;&gt;&gt; s = socket.socket()
&gt;&gt;&gt; poll.register(s.fileno(), select.POLLIN | select.POLLOUT)
&gt;&gt;&gt; (fd, ev), = poll.poll(1000)
&gt;&gt;&gt; ev &amp; select.POLLIN
0
&gt;&gt;&gt; ev &amp; select.POLLOUT
4
&gt;&gt;&gt; ev &amp; select.POLLERR
0
&gt;&gt;&gt; ev &amp; select.POLLHUP
16</pre>
<p>poll (freebsd):</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; import select, socket
&gt;&gt;&gt; poll = select.poll()
&gt;&gt;&gt; s = socket.socket()
&gt;&gt;&gt; poll.register(s.fileno(), select.POLLIN | select.POLLOUT)
&gt;&gt;&gt; (fd, ev), = poll.poll(1000)
Traceback (most recent call last):
  File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
ValueErr1r: need more than 0 values to unpack</pre>
<p>Oh NOES!!!!1 It&#8217;s not portable.<a href="http://pypi.python.org/pypi/py-epoll/1.2">epoll</a>:</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; import epoll, socket
&gt;&gt;&gt; efd = epoll.epoll_create(16)
&gt;&gt;&gt; s = socket.socket()
&gt;&gt;&gt; epoll.epoll_ctl(efd, epoll.EPOLL_CTL_ADD, s.fileno(), epoll.EPOLLIN | epoll.EPOLLOUT)
0
&gt;&gt;&gt; (ev, fd), = epoll.epoll_wait(efd, 16, 1000)
&gt;&gt;&gt; ev &amp; epoll.EPOLLHUP
16
&gt;&gt;&gt; ev &amp; epoll.EPOLLOUT
4</pre>
<p><a href="http://pypi.python.org/pypi/py-kqueue/2.0">kqueue</a>:</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; import kqueue, socket
&gt;&gt;&gt; kq = kqueue.kqueue()
&gt;&gt;&gt; s = socket.socket()
&gt;&gt;&gt; kq.kevent(kqueue.EV_SET(s.fileno(), kqueue.EVFILT_READ | kqueue.EVFILT_WRITE, kqueue.EV_ADD | kqueue.EV_ENABLE))
&gt;&gt;&gt; kq.kevent(None, 16, 1000000000)
[]</pre>
<p>I wonder why are these so inconsistent. One would expect come consistent results for multiplexing a simple thing such a unconnected brand new socket, no?If you think that is horrible &#8211; well, i do &#8211; check out the tricks to check for connection success on non-blocking sockets &#8211; and they don&#8217;t cover win32:</p>
<ul>
<li><a href="http://cr.yp.to/docs/connect.html" rel="nofollow">http://cr.yp.to/docs/connect.html</a></li>
<li><a href="http://www.cyberconf.org/~cynbe/ref/nonblocking-connects.html" rel="nofollow">http://www.cyberconf.org/~cynbe/ref/nonblocking-connects.html</a></li>
</ul>
<p>However, win32 has a much nicer api in the so called overlapped io wich is very different: you don&#8217;t need to check the sockets before making a operation &#8211; you just make the socket call with a overlapped and check for for completed calls (via io completion ports &#8211; <a href="http://msdn2.microsoft.com/en-us/library/aa364986(VS.85).aspx">gqcs</a>). Still, you can use some selects variants (<a href="http://msdn2.microsoft.com/en-us/library/ms741540%28VS.85%29.aspx">WSAAsyncSelect</a>, <a href="http://msdn2.microsoft.com/en-us/library/ms741576%28VS.85%29.aspx">WSAEventSelect</a>, <a href="http://msdn2.microsoft.com/en-us/library/ms740141%28VS.85%29.aspx">select</a>) wich are just as bad.<b><br />
</b></p>
<p>Unfortunately python has a incomplete binding, pywin32 (not that bad &#8211; only <b>ConnectEx </b>and TransmitFile missing) for that and it&#8217;s actually fairly easy to crash your python interpreter with this.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/4/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/4/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/4/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=4&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/04/01/curious-difference-between-epoll-poll-kqueue-and-select/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
		<item>
		<title>cogen: python coroutine library introduction</title>
		<link>http://ionelmc.wordpress.com/2008/03/27/cogen-python-coroutine-library-intro/</link>
		<comments>http://ionelmc.wordpress.com/2008/03/27/cogen-python-coroutine-library-intro/#comments</comments>
		<pubDate>Thu, 27 Mar 2008 12:53:49 +0000</pubDate>
		<dc:creator>Ionel Maries</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cogen]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ionelmc.wordpress.com/2008/03/27/3/</guid>
		<description><![CDATA[Ok, introductory stuff: before python 2.5 generators were just a unidirectional computation structure. That means one could get values out of the generator. In python 2.5 we have the enhancements from PEP 342: Coroutines via Enhanced Generators &#8211; generators have 3 extra methods: sent, throw and close and the yield statement is a expression now. [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=3&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Ok, introductory stuff: before python 2.5 generators were just a unidirectional computation structure. That means one could get values out of the generator. In python 2.5 we have the enhancements from <a href="http://www.python.org/dev/peps/pep-0342/">PEP 342: Coroutines via Enhanced Generators</a> &#8211; generators have 3 extra methods: sent, throw and close and the yield statement is a expression now. So the idea is that the generators are now a bidirectional computation structure: we can get values out and in the generator.<br />
Here&#8217;s a very simple example of what you can do now:</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; def somegenerator():
...     print (yield 1)
...     print (yield 2)
...
&gt;&gt;&gt; g = somegenerator()
&gt;&gt;&gt; print g.next()
1
&gt;&gt;&gt; print g.send('a')
a
2
&gt;&gt;&gt;</pre>
<p>Coroutines are program components that generalize subroutines to allow multiple entry points and suspending and resuming of execution at certain locations, to quote <a href="http://en.wikipedia.org/wiki/Coroutine">wikipedia</a>. So we could look at a generator as a coroutine and the yield expressions as suspend/resume points. Take this example:</p>
<pre class="brush: python; title: ; notranslate">
def somecoroutine():
    data = (yield nonblocking_read(my_socket, nbytes))</pre>
<p>Well, this example is actually from the<a href="http://www.python.org/dev/peps/pep-0342/"> PEP342</a> spec.Here&#8217;s an example that uses cogen:</p>
<pre class="brush: python; title: ; notranslate">
from cogen.core.coroutine import coroutine
from cogen.core.schedulers import Scheduler
from cogen.core.sockets import Socket
from cogen.core.reactors import SelectReactor

@coroutine
def somecoroutine():
    mysocket = Socket() # cogen's socket wrapper
    yield mysocket.connect(('www.google.com',80))
    yield mysocket.writeall(&quot;GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n&quot;)
    result = yield mysocket.read(10240)
    print result

sched = Scheduler(reactor=SelectReactor)
sched.add(somecoroutine)
sched.run() # this is the main loop</pre>
<ul>
<li><span style="font-style:italic;">coroutine</span> is a special decorator that wrapps generators and functions alike in a special <span style="font-style:italic;">Coroutine</span> class. So for example, if you decorate a function that isn&#8217;t actualy a generator nothing bad will happen.</li>
<li><span style="font-style:italic;">Socket </span>is a special wrapper that looks like the regular socket object (well, we actualy have a different flavour for usual recv and send, namely: read, readall, readline, write, writeall) but returns some special objects that we call operations. These operations instruct the cogen scheduler what to do with the coroutine.</li>
<li><span style="font-style:italic;">reactor</span>=SelectReactor &#8211; there are actually 5 reactors: <span style="font-style:italic;">SelectReactor</span>, <span style="font-style:italic;">PollReactor</span>, <span style="font-style:italic;">KQueueReactor</span>, <span style="font-style:italic;">EpollReactor</span>, <span style="font-style:italic;">IOCPProactor</span>. For <span style="font-style:italic;">KQueueReactor </span>and <span style="font-style:italic;">EpollReactor </span>you need C extension modules (that are provided in the lib directory) and for <span style="font-style:italic;">IOCPProactor</span> you need the pywin32 extensions &#8211; also, <span style="font-style:italic;">IOCPProactor </span>is in development atm. The reactor coupled with the socket operations handles all the nasty asynchronous networking code.</li>
</ul>
<p>Also, there are a bunch of examples <a href="http://code.google.com/p/cogen/source/browse/trunk/examples/">here</a>.</p>
<p>Calls to other coroutines need to be made through the scheduler. To call another coroutine you yield a Call operation. Here&#8217;s an example:</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; from cogen.core.coroutine import coroutine
&gt;&gt;&gt; from cogen.core.schedulers import Scheduler
&gt;&gt;&gt; from cogen.core import events
&gt;&gt;&gt;
&gt;&gt;&gt; @coroutine
... def foo():
...     print 'foo'
...     result = yield events.Call(bar, args=(&quot;ham&quot;,))
...     print result
...
&gt;&gt;&gt; @coroutine
... def bar(what):
...     print 'bar'
...     raise StopIteration(&quot;spam, %s and eggs&quot; % what)
...
&gt;&gt;&gt; sched = Scheduler()
&gt;&gt;&gt; sched.add(foo)
&lt;foo Coroutine instance at 0x00D1E6B8 wrapping &lt;function foo at 0x00C01B30&gt;, state: NOTSTARTED&gt;
&gt;&gt;&gt; sched.run()
foo
bar
spam, ham and eggs
&gt;&gt;&gt;</pre>
<p><code>cogen</code> has also other usefull operations. Take for example this using signals:</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; from cogen.core.coroutine import coroutine
&gt;&gt;&gt; from cogen.core.schedulers import Scheduler
&gt;&gt;&gt; from cogen.core import events
&gt;&gt;&gt;
&gt;&gt;&gt; @coroutine
... def foo():
...     yield events.Signal(&quot;bar&quot;, 'spam')
...     yield events.Signal(&quot;bar&quot;, 'ham')
...     yield events.Signal(&quot;bar&quot;, 'eggs')
...     yield events.Sleep(3)
...
&gt;&gt;&gt; @coroutine
... def bar():
...     print (yield events.WaitForSignal(&quot;bar&quot;))
...     print (yield events.WaitForSignal(&quot;bar&quot;))
...     print (yield events.WaitForSignal(&quot;bar&quot;))
...     try:
...         print (yield events.WaitForSignal(&quot;bar&quot;, timeout=2))
...     except events.OperationTimeout:
...         print 'No more stuff !'
...
&gt;&gt;&gt; sched = Scheduler()
&gt;&gt;&gt; sched.add(bar)
&lt;bar Coroutine instance at 0x00D1E6B8 wrapping &lt;function bar at 0x00C551F0&gt;, state: NOTSTARTED&gt;
&gt;&gt;&gt; sched.add(foo)
&lt;foo Coroutine instance at 0x00D1EC90 wrapping &lt;function foo at 0x00C01B30&gt;, state: NOTSTARTED&gt;
&gt;&gt;&gt; sched.run()
spam
ham
eggs
No more stuff !
&gt;&gt;&gt;</pre>
<ul>
<li><code>events.Signal(<span style="font-style:italic;">name</span>, <span style="font-style:italic;">value</span>)</code> &#8211; <span style="font-style:italic;">name </span>is an object that needs to be immutable (strings, tuples, numbers and frozen sets are immutable for example); <span style="font-style:italic;">value </span>is what is yield <code>events.WaitForSignal</code> going to return.<code></code></li>
<li><code>cogen</code>&#8216;s scheduler main loop (<span style="font-style:italic;">run</span>) exits when there is no more stuff to run (no active coroutines, no socket operations waiting etc) &#8211; <code>events.WaitForSignal</code> does not qualify, otherwise the scheduler would run endlessly and nothing would happen (no other coroutines to raise the signal), that is why there is a <code>events.Sleep(3)</code> in <code>foo</code>.</li>
</ul>
<p><code><br />
</code></p>
<p>There&#8217;s a lot more to talk about, so check the docs on <a href="http://code.google.com/p/cogen/wiki/Docs_CogenCoreEvents">events</a> and <a href="http://code.google.com/p/cogen/wiki/Docs_CogenCoreSocketsSocket">sockets</a>, the <a href="http://code.google.com/p/cogen/source/browse/trunk/examples/">examples</a>.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/ionelmc.wordpress.com/3/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/ionelmc.wordpress.com/3/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ionelmc.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ionelmc.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ionelmc.wordpress.com&#038;blog=3292814&#038;post=3&#038;subd=ionelmc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ionelmc.wordpress.com/2008/03/27/cogen-python-coroutine-library-intro/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/83858c3aa798d3fb8e29439ededcf192?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">ionelmc</media:title>
		</media:content>
	</item>
	</channel>
</rss>
