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

<channel>
	<title>jessenoller.com &#187; pycon 2009</title>
	<atom:link href="http://jessenoller.com/category/pycon-2009/feed/" rel="self" type="application/rss+xml" />
	<link>http://jessenoller.com</link>
	<description>python, programming and other things</description>
	<lastBuildDate>Wed, 11 Jan 2012 19:01:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>PyCon: Everybody Pays</title>
		<link>http://jessenoller.com/2011/05/25/pycon-everybody-pays/</link>
		<comments>http://jessenoller.com/2011/05/25/pycon-everybody-pays/#comments</comments>
		<pubDate>Wed, 25 May 2011 12:01:29 +0000</pubDate>
		<dc:creator>jesse</dc:creator>
				<category><![CDATA[pycon]]></category>
		<category><![CDATA[pycon 2009]]></category>
		<category><![CDATA[pycon 2010]]></category>
		<category><![CDATA[pycon 2011]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://jessenoller.com/?p=901</guid>
		<description><![CDATA[Preamble
There's been some recent discussion about DjangoCon(.eu &#124; .us) and whether or not speakers should have to pay for admission as well - see Chris Wanstrath's (of Github) tweets (here and here) and this Convore thread for examples. Obviously, as PyCon is the "big dog" so to speak for Python conferences, everyone looks to ...]]></description>
			<content:encoded><![CDATA[<h2>Preamble</h2>
<p>There’s been some recent discussion about DjangoCon(.eu | .us) and whether or not speakers should have to pay for admission as well — see Chris Wanstrath’s (of Github) tweets (<a href="https://twitter.com/#!/defunkt/status/71249188242993153">here</a> and <a href="https://twitter.com/#!/defunkt/status/71249612165484544">here</a>) and <a href="https://convore.com/django-community/should-djangocon-speakers-be-given-free-admission-or-even-paid-for-appearing/">this Convore thread</a> for examples. Obviously, as PyCon is the “big dog” so to speak for Python conferences, everyone looks to “us” for a model to work from, or how we manage things. I’ve seen a lot of poop slung towards the DjangoCon organizers, mainly due to a lack of knowing “why” certain policies (such as “Everyone Pays”) exist for DjangoCon, PyCon, and other conferences.</p>
<p>As co-chair and program committee chair last year, and program committee chair the year before, and now chair for the next two years — I figured it might be good to take a moment to explain the rationale behind PyCon’s approach — as well as some statistics about the budget. I’m not going to state that this policy is perfect; nor that it won’t be changed; I also will not release the budget publicly — I don’t think giving everyone a spreadsheet without the context of the <em>hundreds of man hours of work</em> that go into it is useful, at all.</p>
<p><strong>Important Note</strong>: PyCon is organized and managed by the <em>Python Software Foundation</em> — this means that, as part of being a 501c3 charity, some of the financials from past PyCon is available as part of publicly accessible financial documents of the foundation. You can find those on the <a href="http://www.python.org/psf/records/">PSF’s site</a>.</p>
<p>The same reasoning may not apply to a conference that is organized by a commercial entity or is done for profit. OSCON is a commercial conference, so having speakers get in free is generally expected. DjangoCon.us is in the middle — it is organized for profit by a commercial entity, but it also contributes <em>heavily</em> back to the Django Software Foundation. DjangoCon.eu is managed differently as well.</p>
<p><span id="more-901"></span></p>
<h2>Policy and Financial Aid</h2>
<p>First, what is the “policy” — well, first, it’s not a policy per-se; it’s part policy, and part tradition. The policy is “Everyone pays for a ticket” — attendees, tutorial presenters, organizers (meaning: <strong>all</strong> volunteers, including the chair) and sponsors — everyone pays their way. Yes, this means Van and myself both paid for our own tickets to attend. Everyone is treated as equal — sponsors get free admissions as part of conference sponsorship packages, and keynote speakers may be provided with either compensation or admission depending on the negotiated deal (some keynote speakers cost money, for example).</p>
<p>Now; an interesting aspect of this is that PyCon, as a conference, offers a <em>very generous</em> financial aid program — this means that some attendees, speakers, tutorial presenters, etc have some, or in rare cases, all of their expenses such as flight, hotel and admission provided to them from the PyCon budget. PyCon goes out of it’s way to encourage people to apply for financial aid — even if we can’t cover all of your expenses, we will give you free admission <em>based on need</em>. The FA application process is simple, and straightforward. It’s also very liberal — the only caveat is that speakers at the conference “get bumped to the top” of the applications so that we don’t lose a good talk because of financial need. We also don’t ban anyone from applying (for example, I needed assistance in 2010 even as the PC chair).</p>
<p>We use the FA budget to not only help the “normal” attendees of the conference, we also keep an eye towards diversity — for example in 2010 we had a specific grant program (funded by Google) for women to attend PyCon — which they did in amazing numbers! We also try to help <strong>more</strong> people with less money than <strong>less people</strong> with <strong>more money</strong> — we want to spread assistance out as much as possible. This is why FA requires room-sharing at the conference hotel, this is why we may only cover part of a given applicant’s costs — we want to help <strong>more people</strong>.</p>
<p>As you can guess — since financial aid is a part of the budget, we allocate a set amount of money to this — but, without a solid budget (meaning, admission ticket sales, sponsorships, etc) <em>we can’t have it</em> — it’s actually a dice roll. We can guess at how much FA we can carve out of the budget at the start of the process, and we <strong>will</strong> award that amount — but that means if we have low attendance, don’t book enough rooms, or our catering costs spike, or lack sponsors, the conference can lose not insignificant amounts of money <strong>helping people</strong>. The rub being, you don’t know for sure if this will happen until the <em>conference actually happens</em>.</p>
<p>So, how does “everybody pays” play into this? In two ways. First, it helps hedge our risk, institutionally speaking. PyCon had a good/bad year in 2009 — good for the attendees, but horrendously bad financially. We made various commitments in 2008 just as the markets were peaking, and we lost a lot of money when everything went south. Since then, it has been our budget policy to make sure that our revenues will cover our hard costs even if there is a 15% dip in attendance and a 35% dip in sponsorship.</p>
<p>Second, you may have guessed that the “everybody pays” policy allows us to pad the financial aid budget. This has the direct benefit of bringing more people to the conference, increasing the diversity of people attending, getting a larger proportion of the community together, etc.</p>
<p>I’m happy to say, that on most years, we <em>very happily</em> break our financial aid budget — meaning, if we have a positive outlook, we will <strong>gladly</strong> overspend on financial aid and take less “profit ” for the conference. The point of the conference is the community, it’s not about the conference! We help the community as much as we can by helping to cover the costs of people who would not otherwise be able to attend.</p>
<h2>History and Tradition</h2>
<p>Once you start organizing a conference you start to rapidly realize how costly things can get — and if you don’t have sponsors with giant bags of money, or the conference is not being run for profit (such as OSCON), you can quickly get into trouble if you don’t have a policy in place that will ensure financial viability. PyCon came from very small, humble beginnings but has grown year over year consistently — maintaining the “everyone helps, and everyone pays” tradition originally set forth.</p>
<p>It is my understanding that the policy/tradition has as much to do with financials as it does with “the feel”. No one is treated specially, <strong>we</strong> — meaning the community — put together the conference, <strong>we</strong> are taking the financial risk that comes with it. <strong>We</strong> are in it together, and that means “everyone helps, and everyone pays” — it is the most equitable solution that helps us maintain fairness and the flavor/feel of the conference. When you realize that even Guido has to buy a ticket (even if it was paid for by Google) or that Van Lindberg had to buy one — it suddenly makes you realize that all of us truly believe in the spirit of “we are all in this”.</p>
<p>Speakers; as a an additional guideline, while always paying for a ticket; always pay at the discounted early bird rate <em>no matter when they register</em>. So yes, we do discount them, but no more than anyone else who registers within the early bird window.</p>
<p>As an aside, the “everybody helps” is also part of what makes PyCon special. When people come to other conferences, they frequently come expecting to be coddled and catered to. When people come to PyCon, we hope they come expecting to <strong>contribute</strong>. Having everybody contributing is at the core of the best parts of PyCon — from stuffing bags, to lightning talks, to the wonderful Testing in Python BOF.</p>
<h2>Hard Costs, Stats and Risk</h2>
<p>So what makes up a PyCon budget? Well — Van covered some of it in his wonderful “<a href="http://pycon.blogspot.com/2011/02/pycon-2011-behind-scenes.html">Behind the Scenes</a>” post for PyCon 2011 — but in more detailed terms of percentages of the total costs for the budget:</p>
<ul>
<li><strong>Catering (Food, beverages)</strong>: 54%</li>
<li><strong>Networking</strong>: 5% </li>
<li><strong>Audio/Visual and Video Recording</strong>: 13%</li>
<li><strong>Payments to Tutorial Instructors</strong>: 6%</li>
<li><strong>Misc/PR/Sponsors and Administration</strong>: 16%</li>
<li><strong>Swag</strong>: 2%</li>
<li><strong>Financial Aid</strong>: 4%</li>
</ul>
<p>Catering, plus Financial Aid and video recording is <strong>70% </strong>of the budget alone. The total value “spent” for financial aid alone well exceeds 50,000$ We spend a massive amount of money for audio/visual and the video recording making all of the talks available on the web (see the <a href="http://python.mirocommunity.org/category/conferences">python miro community</a>). Tens of thousands of dollars spent on networking.</p>
<p>We could forgo feeding people — but with a conference that runs from 8am to 6pm for 5 days, that would suck — and people needing to leave to get food would be disruptive and ruin the flow. We <strong>could</strong> forgo recording the videos. We could do a lot of things to cut back and lower the budget numbers so we could give more away (such as comp’ing speaker tickets), but that doesn’t make the risk and costs from the hotel go away.</p>
<ul>
<li>Average Revenue per attendee: ~$300</li>
<li>Average Cost per attendee: ~$465</li>
</ul>
<p>In total — these costs (for 2011) came to <strong>well</strong> <strong>over</strong> <strong>600,000$</strong> — that’s right. Over half a million dollars in hard costs for a conference of 1,380 Pythonistas. Much of the payments, guarantees, deposits, etc have to be put down up front of the actual conference with <em>no guarantee</em> that we will make our sponsorship or attendee numbers. That means, in the case of PyCon — the Python Software Foundation fronts potentially hundreds of thousands of dollars in payments and risk. We also expect these to climb with the move of the conference to Santa Clara.</p>
<p>Conferences are unknowns — you put up a lot of time, energy and money — lots of money — and you hope you hit certain numbers. For example, you make a contract with the hotel that says “we will have X number of people book X number of rooms nights” — if you don’t meet those numbers? The hotel penalizes you a <strong>stunning</strong> amount of money. You make a contact for catering — saying that you will serve X number of meals — and if you don’t hit that? You get penalized. You put a lot of faith in making numbers on:</p>
<ul>
<li>Sponsors — without corporate sponsors, we simply could not exist (at this scale), period.</li>
<li>Attendee Numbers — You expect X number of attendees, broken up into “corporate, individual and Y” rates — corporate rate tickets are where you make the bulk of registration rates.</li>
<li>Hotel Rooms — if you don’t hit your contracted numbers, you <strong>will</strong> take a bath</li>
</ul>
<p>Do you know what happens if, for some reason — say an economic downturn — you don’t make those numbers? Your conference loses over $230,000, possibly more. That 230k number? Right around the amount PyCon 2009 lost, representing a massive financial loss for the Python Software Foundation. Yes, you try to mitigate the risks by careful planning — if you’re lucky, you get some insurance to cover some of the potential losses. PyCon is actually <strong>really</strong> lucky in all of this — we’ve grown enough that we get to leverage economies of scale with the contracts we deal with. Small conferences? Not so much — they get harder in the face of failure, and they don’t have the bargaining power we have..</p>
<p>It’s a delicate balancing act, requiring careful planning and a lot of work to drive attendance and sponsorship — negotiations with Hotels, Catering, Unions, are all things that have to go right in order to make a conference that even stands a chance of not losing you massive amounts of money. In the case of PyCon — a massive loss of money (such as 2009) could cause the foundation to go bankrupt and <strong>dissolve</strong>. As it is, the foundation, already spartan in spending cut back even further to protect itself which represents a net negative for the Python Community.</p>
<h2>Where does the profit go?</h2>
<p>Alright — I’ve outlined the philosophy, the scale and the risk. Now, you’re probably asking where, if we have it, does any profit from the conference go? Easy — straight back into the community.</p>
<p>Whatever profit — really, money left over, goes to cover the initial costs/risks for PyCon the next year, and the years after — it also goes to the Python Software Foundation that in turn, reinvests that money into the community (see the <a href="http://pyfound.blogspot.com/">foundation blog</a>).</p>
<p>Having a healthy positive margin also means we can increase things such as the financial aid budget for the next year, allowing even more Python developers to attend.</p>
<p>Why not run a budget that aims for 0$ +/-?!</p>
<p>Because, that is simply <strong>insane</strong> — you can aim for minimal profit by reinvesting into things such as financial aid, or other perks for the attendees but only <strong>after</strong> you have guaranteed you’re going to make your numbers — see the issue? At best, you budget is a highly refined series of educated guesses. At worst? Someone goes bankrupt — at smaller conferences such as DjangoCon.eu, where some costs and contracts are secured by an individual and their credit card?</p>
<p>That person goes broke, because the entities you signed contracts with <strong>will</strong> get their money.</p>
<p>So, you never, ever aim for a loss, but you also don’t aim for extracting “maximum value” from conference attendees. You aim, you plan, and you hope to provide the best value and experience to attendees and sponsors — you do this through a lot of hard work and sweat. You make sure attendees walk away <strong>raving</strong> about the conference, you make sure you generate the <em>maximum return on investment for the <strong>community</strong><span style="font-style: normal;">. </span></em></p>
<h2><em><span style="font-style: normal;">In Closing</span></em></h2>
<p><em><span style="font-style: normal;">Historically, PyCon has never been aimed at “extracting money” from the community — it could be run a lot more profitably. We could increase ticket rates, reduce FA and walk around in Nascar-esque suits with sponsor logos on them — there’s lots of things that could be done to make PyCon a <strong>massive</strong> profit center for the PSF. We don’t though — why? Because, that defeats the purpose of a community conference, put together <strong>by and for</strong> the community.</span></em></p>
<p><em><span style="font-style: normal;">We take what money we end up with and we sponsor the sprints at PyCon itself, we hold the language and virtual machine summits. The PSF reinvests it into the Python community as a whole (see the <a href="http://pythonsprints.com/">sprints project</a>, for example, or the <a href="http://morepypy.blogspot.com/2011/03/thank-you-to-psf.html">10,000$ check we gave to PyPy</a>). The money is given out in the forms of developer grants, holding sprints, providing sponsorship to smaller Python conferences all over the world, outreach and education initiatives, etc. No one gets a shiny new car or anything — money that comes from the community conference goes back into the community. You can see how much goes where if you peruse the <a href="http://www.python.org/psf/records/board/resolutions/">PSF resolutions page</a>.</span></em></p>
<p>PyCon is beginning to also outstrip the ability for a small group of volunteers to put together — more and more we’ve had to bring on commercial entities (whom we have to pay) to assist in organizing or doing specific things (such as registration, or website development). I fully expect PyCon 2012/2013 to quickly hit the attendance cap meaning we’re going to have more scaling issues and higher costs — this <em>is a fundamentally good thing</em> — PyCon, it is felt, can sustain it’s current feel and quality up to a maximum of 1500–2000 attendees.</p>
<p>We do not have the intention of raising that cap.</p>
<p>Instead, we — as the foundation — intend on encouraging smaller more regional conferences such as <a href="http://www.pyohio.org/">PyOhio</a> to grow — PyCon will continue to be the “big dog” so to speak — but it being the big dog will allow us to further cultivate and pollenate the entire Python community and ecosystem.</p>
<p>Given all of that — as the PyCon chair for the next two years — and being relatively comfortable that we will again, put on a highly successful conference — I am exploring the idea of steeply discounting the cost of tickets for speakers. I feel that not only is the conference viable once again, but that the speakers <strong>do</strong> help make the conference what it is — last year we had over 200 talk and tutorial submissions. All of those speakers submitted talks knowing that they would have to pay for a ticket to attend — but given the positive outlook, I’m comfortable in thinking that we will be able to provide accepted speakers with a discount to <strong>thank them</strong> for their talk.</p>
<p>It’s all about community, and reinvesting in it in the right places, at the right times, and managing your risk. The risks putting on a conference — even a small one (especially a small one) are massive, but the returns — especially when you’re standing on a stage in front of 1380 fellow Python hackers handing a big cardboard check to a fantastic project?</p>
<p>Well, the returns are well worth it.</p>
<p> </p>
<ul>
</ul>
<p class="wp-flattr-button"></p> <p><a href="http://jessenoller.com/?flattrss_redirect&amp;id=901&amp;md5=32f4223d09bf3711dad65cd52ab2a6e2" title="Flattr" target="_blank"><img src="http://jessenoller.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://jessenoller.com/2011/05/25/pycon-everybody-pays/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>PyCon Wrapup or “stop fidgeting”</title>
		<link>http://jessenoller.com/2009/04/07/pycon-wrapup-or-stop-fidgeting/</link>
		<comments>http://jessenoller.com/2009/04/07/pycon-wrapup-or-stop-fidgeting/#comments</comments>
		<pubDate>Tue, 07 Apr 2009 13:25:48 +0000</pubDate>
		<dc:creator>jesse</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[pycon 2009]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://jessenoller.com/?p=579</guid>
		<description><![CDATA[Ah, PyCon 2009 has come and gone. I'm a little late in doing a wrap up - but that's primarily due to the fact I wanted to spend time with the family, and not on the computer since I got back mid-day Thursday of last week. That - and other things in my life ...]]></description>
			<content:encoded><![CDATA[<p><img style="border-color: white" src="http://jessenoller.com/wp-content/uploads/2009/04/3405504555-e4422b42f6.jpg" alt="3405504555_e4422b42f6.jpg" border="0" width="250" height="166" align="left" border="5"/>Ah, PyCon 2009 has come and gone. I’m a little late in doing a wrap up — but that’s primarily due to the fact I wanted to spend time with the family, and not on the computer since I got back mid-day Thursday of last week. That — and other things in my life are a little worse-for-wear, so my brain’s been full of “other stuff” rather than basking in the glow of:</p>
<p><b>The best pycon, ever</b></p>
<p>Yeah, I came out and said it. For me, it was my 4th(?) PyCon, and not to disparage the past, but this one was the best planned, best executed and most fun for me. Sure, it had a few negatives (Chicago being one of them), but by far the pluses outweighed any minuses.</p>
<p>Here’s a summary of things I can remember.</p>
<h2> The summits </h2>
<p>I got in mid-day wednesday and broke into the VM summit. I was immediately slapped with the <a href="http://jessenoller.com/2009/03/26/pycon-unladen-swallow/" target="_blank">unladen-swallow</a> announcement, which made me do a little dance and immediately start pulling down the code. For the most part, since I was past the introduction piece, I sat in back and had interesting discussions with Thomas Wouters, Brett Cannon and others. </p>
<p>Later that night, I sat down and spent some time with unladen swallow — mainly getting LLVM all happy and pulling down the trunk (when I should have been using the released tag). I also spent a fair amount of time massaging my slides for both of my talks. Nothing quite like last minute changes.</p>
<p>The next day was the language summit. Here a bunch of people much smarter than me sat down and discussed the future of the language. I can’t even begin to describe everything that happened — some basic highlights are:</p>
<ul>
<li> Some discussions around making python 2.7 be the last release of the 2.x line. I think the general consensus was to continue to use 2.x as a ramp into 3.0, but in general if migration to (and from) 3.0 was faster/easier, then the adoption barrier for 3.x would be greatly lessened. Most of us finally agreed that the 2.x line should end with 2.7.
<li> On 3.0 — porting issues and pains were discussed, things like 2to3 being slow, lack of incentive (3k being “a better language” notwithstanding) being one of the big issues. Someone (Guido I think) floated the idea that big features only go into the 3.x branch, ergo providing greater upgrade incentive. I don’t think a lot of people disagreed with this and in fact, I took it to heart during the sprints when looking at feature requests for multiprocessing.
<li>Which brings us to 3to2 — several developers expressed that if we had a tool which could translate python3 code to python2, then they could start writing their frameworks/tools in pure python3 and then back port it. I don’t recall anyone disliking this idea — but no one wanted to get the ball rolling. So I raised my hand. In essence, I volunteered to get the ball rolling, which I have done. Benjamin Peterson will be heading it up primarily — but anyone is free to contribute (and some already have). It’s got potential as a google summer of code project.
<li> After that we discussed what CPython can do to make integration/testing easier for alternative implementations. We agreed that being able to mark tests as “cpython only” and breaking things in the repository up in such a way to make integration of the standard library into alternative distributions easier. Brett has more on this, but the essential idea is to compartmentalize the standard library out into a separate project within source control, and have other implementation pull/ingrate that. Anything that’s Jython/CPython/etc specific would be marked/stored appropriately. For example, multiprocessing as it exists today is a CPython artifact, and not needed for say, Jython.
<li> And then there was the packaging discussion. Rather then rehash everything that was discussed, I’ll simply mention that I proposed a much simpler approach. Specifically, I noted that we should simplify the core of distutils, pulling in setuptools feature where appropriate, offer plugin/hooks where appropriate, standardize on a simple, extensible metadata format and <b>remove</b> any of the “non core” bells and whistles from distutils. In essence my argument was that things like RPM building, easy_install, virtualenv, and so on simply do not belong in core python, rather they belong outside of the core, where consumers/developers can tailor solutions to suit their needs. Ultimately disutils can help them, and make the APIs/Plugins/Metadata standard but it should not be a fully fledged “package manager” or build utility.
</ul>
<p>Ultimately, the summits were a ton of fun, and being lucky enough to be invited was really great for me. At the end I was worried about people being tired of my chirping up, but it was resoundingly a success.</p>
<h2> The conference </h2>
<p>This is where things begin to blur — hopping in between hotels, lightning talks, hallway discussions — it was insane. Add to that my fear/stress about both of my talks, and I simply can’t fit everything that happened in my brain.</p>
<p>I think I started the day in “How to Give a Python Talk” by AMK — which was great, if disheartening simply due to the fact that I had made some of the mistakes he pointed out in my talks. Ergo more slide hacking. After that it was hallway discussions and hitting up “How Python is developed” by Brett — I was going to heckle him, but I played nice.</p>
<p>Then there was the Python VMs panel, which I swapped out of and into the “Building an Automated QA Infrastructure using Open-Source Python Tools” — which can be summed up as “Yay buildbot” (I’m hard to impress, I’ve built a few of these by now). I then hit up the Twisted/AMPQ talk but ducked out early to go prep for my talk.</p>
<p>Then, it was my multiprocessing talk time. You can see the full video <a href="http://pycon.blip.tv/file/1947354/" target="_blank">here</a>, I think it went well, and feedback has been positive. Given I’ve done variations on this talk elsewhere, I was a little more confident in myself. I think I could have slowed down in some parts, and stopped fidgeting as well as a few other nits. I had some great conversations with users of the package as well as people new to it which pretty much absorbed all my time until dinner. I think I hit up the lightning talks — but I can’t remember.</p>
<p>The next day, was the now infamous <b>LINDBERG’D</b> lightning talk (<a href="http://pycon.blip.tv/file/1931026/" target="_blank">video here</a>) — for those who don’t know — Yes, Van knew — he even wrote the legal disclaimer I have in my slides. Basically, Brett and I had stayed up until what — 1am one night laughing about this idea of sending Van (who isn’t very threatening) after commenters on the internet. The day after we stayed up laughing at this (much to the dismay of our neighbors) I hit Van up for some text and let him in on it. <b>No, it wasn’t serious</b> (people asked). Yes, I was also voted in with a pile of other people into the PSF. Good times.</p>
<p>Afterward, the guidonote and then know I saw the state of django talk, as well as Jack’s “Class Decorators: Radically Simple” — which was fantastic (although I saw a variation at the boston python meetup the week before). I dropped in on the ORM panel, and the GAE talk (which was disappointing). Then I hit Bob’s “Drop ACID and think about data” which was awesome. I again ducked out to double check my stuff for my distributed systems talk. Also on saturday was the “<a href="http://us.pycon.org/2009/openspace/WritingAboutPython/" target="_blank">Writing About Python</a>” BoF, which was cool, but in which I may have over-expressed several <b>cough</b> strong opinions.</p>
<p>The video of my second talk is <a href="http://pycon.blip.tv/file/1947511/" target="_blank">here</a>. This one, my lack of confidence is apparent, and I’m still fidgeting. I think part of my problem is I like to express with my hands, almost like a spastic air traffic control man and holding the mic/trying not to fidget made my body just sort of spaz. This time though, I rushed from my talk into Alex Martelli’s excellent “Abstractions as Leverage” talk. After that, more people found me and picked my brain.</p>
<p>I can’t stress how awesome Alex’s talk was — much of my hallway discussion time was spent discussing abstractions (especially around distributed systems) with him.</p>
<p>We’ll see how my call for some cohesion and a real “django for distributed systems” call in my second talk goes. Everyone I have spoken to likes the idea and had a lot of great feedback, but lord knows I don’t have the time to lead it up right now, maybe soon. </p>
<p>Late saturday, was the teach me web testing BoF which I ducked into, and then past that the Testing In Python BoF which provided me much in the way of fun, ideas, discussions and uh. Beer. Yeah. I can’t exactly remember what I said when Titus put me on the spot to discuss “what sucks about testing in python”. But I do remember having some great laughs. I think the heckling got recursive at one point, not sure though.</p>
<p>Sunday came, and with it, my sorry attempt to sit in the “Functional Testing Tools in Python” panel — which was thwarted by a 45 minute bloody nose. Apparently Titus talked a lot, so I don’t think I missed anything. End of main con.</p>
<p>Before I move into the sprints — I want to point out that I had <b>fantastic</b> hallway discussions with tons of people — people I look up to, and people I’ve never met before. I had excellent lunches with groups of people ranging from the highly experienced to someone who has learned python a week before. I can’t say enough about the simple fact that you get to relax, hang out and just talk with all of these people. Python is defined by it’s community — and ours is pretty awesome.</p>
<h2> The sprints </h2>
<p>Monday morning, I was off to the python core sprint. I immediately started hacking on multiprocessing bugs — I think all told, I managed to close around 12 or so bugs by the time thursday morning came around. The sprint was awesome simply due to the fact I could look across the room/table and ask any number of core developers questions. Martin Van Loewis came to my rescue/aid a few times, and being able to bounce ideas off of everyone is pure unbridled awesome.</p>
<p>Having dedicated face to face time to beat on these bugs and share information/debate things is immeasurable. I also got access to <a href="http://www.snakebite.org/" target="_blank">snakebite</a> thanks to Trent, who is still working out the kinks. Alas, even having access did not make cross-platform support (mainly the BSDs) any easier for multiprocessing. I spent a good chunk of my time futzing with virtual machines so I could do further work — I ended up cutting that short because I wanted to fix things at the sprints: not fart around with tool chains.</p>
<p>Other than hacking until late at night through the sprints, there’s was quite a fun night where bourbon flowed, and many partook — much fun was had by all. There’s nothing quite like having drinks and making awful threading/process/compiler jokes. </p>
<p>Bug fixes/patch work for multiprocessing:</p>
<ul>
<li> <a href="http://bugs.python.org/issue5002" target="_blank">multiprocessing/pipe_connection.c compiler warning (conn_poll)</a>
<li> <a href="http://bugs.python.org/issue3770" target="_blank">test_multiprocessing fails on systems with HAVE_SEM_OPEN=0</a>
<li> <a href="http://bugs.python.org/issue3110" target="_blank">Multiprocessing package build problem on Solaris 10</a>
<li> <a href="http://bugs.python.org/issue5261" target="_blank">with lock fails on multiprocessing</a>
<li> <a href="http://bugs.python.org/issue5570" target="_blank">Bus error when calling .poll() on a closed Connection from multiprocessing.Pipe()</a>
<li> <a href="http://bugs.python.org/issue5177" target="_blank">multiprocessing: SocketListener should use SO_REUSEADDR</a>
<li> <a href="http://bugs.python.org/issue5574" target="_blank">multiprocessing queues.py doesn’t include JoinableQueue in its __all__ list</a>
<li> <a href="http://bugs.python.org/issue5400" target="_blank">patches for multiprocessing module on NetBSD</a>
<li> <a href="http://bugs.python.org/issue3270" target="_blank">test_multiprocessing: test_listener_client flakiness</a>
<li> <a href="http://bugs.python.org/issue5545" target="_blank">multiprocessing: switch to autoconf detection of platform values</a>: This one was a bear. All the props in the world go out to Martin Van Loewis for guiding me through getting this done.
<li> <a href="http://bugs.python.org/issue3551" target="_blank">multiprocessing.Pipe terminates with ERROR_NO_SYSTEM_RESOURCES if large data is sent (win2000)</a>
<li> <a href="http://bugs.python.org/issue5585" target="_blank">implement initializer for multiprocessing.BaseManager.start()</a>
</ul>
<h2>In Summary</h2>
<p>PyCon is simply getting better — I’m looking forward to Atlanta next year, if nothing more than for better weather. I got to talk to a lot of great people — Collin Winter, Thomas Wouters, Brett Cannon (be careful, he’s an odd one), Guido, Alex Martelli and many others. Having many hallway discussions with language users and encouraging them to get involved — PyCon is AwesomeCon — no where else do you get to hear so much great information, discussions and points of view.</p>
<p>All of the videos for this pycon are going up on <a href="http://pycon.blip.tv/" target="_blank">pycon.blip.tv</a>.</p>
<p>It was a great time, and I can’t thank everyone involved enough.</p>
<p class="wp-flattr-button"></p>]]></content:encoded>
			<wfw:commentRss>http://jessenoller.com/2009/04/07/pycon-wrapup-or-stop-fidgeting/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>PyCon: Concurrency/Distributed systems talk slides online</title>
		<link>http://jessenoller.com/2009/03/28/pycon-concurrencydistributed-systems-talk-slides-online/</link>
		<comments>http://jessenoller.com/2009/03/28/pycon-concurrencydistributed-systems-talk-slides-online/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 21:28:50 +0000</pubDate>
		<dc:creator>jesse</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[pycon 2009]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://jessenoller.com/?p=574</guid>
		<description><![CDATA[
Slides from my intro to Concurrency/Distributed systems talk @pycon 2009 are here. Also up on the pycon site here]]></description>
			<content:encoded><![CDATA[<p><!--noadsense--><br />
Slides from my intro to Concurrency/Distributed systems talk @pycon 2009 are <a href="http://jessenoller.com//code/pycon_jnoller_distributed.pdf" target="_blank">here</a>. Also up on the pycon site <a href="http://us.pycon.org/2009/conference/schedule/event/69/" target="_blank">here</a></p>
<p class="wp-flattr-button"></p>]]></content:encoded>
			<wfw:commentRss>http://jessenoller.com/2009/03/28/pycon-concurrencydistributed-systems-talk-slides-online/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PyCon: Multiprocessing Talk Slides</title>
		<link>http://jessenoller.com/2009/03/27/pycon-multiprocessing-talk-slides/</link>
		<comments>http://jessenoller.com/2009/03/27/pycon-multiprocessing-talk-slides/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 21:59:22 +0000</pubDate>
		<dc:creator>jesse</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[pycon 2009]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://jessenoller.com/?p=568</guid>
		<description><![CDATA[
Slides from my intro to multiprocessing talk @pycon 2009 are here. Also up on the pycon site here]]></description>
			<content:encoded><![CDATA[<p><!--noadsense--><br />
Slides from my intro to multiprocessing talk @pycon 2009 are <a href="http://jessenoller.com/code/pycon_jnoller_multiprocessing.pdf" target="_blank">here</a>. Also up on the pycon site <a href="http://us.pycon.org/2009/conference/schedule/event/31/" target="_blank">here</a></p>
<p class="wp-flattr-button"></p>]]></content:encoded>
			<wfw:commentRss>http://jessenoller.com/2009/03/27/pycon-multiprocessing-talk-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stackless: You got your coroutines in my subroutines.</title>
		<link>http://jessenoller.com/2009/02/23/stackless-you-got-your-coroutines-in-my-subroutines/</link>
		<comments>http://jessenoller.com/2009/02/23/stackless-you-got-your-coroutines-in-my-subroutines/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 20:43:33 +0000</pubDate>
		<dc:creator>jesse</dc:creator>
				<category><![CDATA[concurrency]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[pycon 2009]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://jessenoller.com/?p=495</guid>
		<description><![CDATA[Note:This is another post in what I hope will be a series leading up to my concurrency/distributed systems talk at PyCon. I'm steadily working through experimenting with and learning the various frameworks/libraries in the python ecosystem.

I reserve the right (and probably will) to revise these entries based on feedback from people (mainly the author(s) ...]]></description>
			<content:encoded><![CDATA[<p><b>Note:</b>This is another post in what I hope will be a series leading up to my concurrency/distributed systems talk at PyCon. I’m steadily working through experimenting with and learning the various frameworks/libraries in the python ecosystem.</p>
<p>I reserve the right (and probably will) to revise these entries based on feedback from people (mainly the author(s) of said tool(s)). I will also add additional bits and pieces as I learn and explore more.<b>/Note</b></p>
<p>Stackless python — here’s another big one on the pile — is much more than a library, or a framework which runs on CPython — Stackless is actually a  modified version of the CPython interpreter. It’s much more than just a C-extension. Stackless is in use by various people and companies — most notably, it’s in use by CCP Games, makers of Eve Online (see <a href="http://www.stackless.com/Members/rmtew/News%20Archive/newsPyCon2006Pres">this</a> pycon presentation). In fact, CCP Games is a large part of why Stackless is still around today.</p>
<p><span id="more-495"></span></p>
<p>I say that intentionally — quoting the readme in the Stackless/ directory of the distribution(<a href="http://svn.python.org/view/stackless/trunk/Stackless/readme.txt?view=markup" target="_blank">here</a>):</p>
<blockquote><p>
In 2003, the fabulous PyPy porject was started, which is still<br />
performing very well. I have implemented Stackless for PyPy<br />
(with lots of support from Armin), and it is so incredibly<br />
much nicer. No more fiddling with existing calling conventions,<br />
no compromizes, everything that needs to be stackless also is.</p>
<p>Unfortuantely, PyPy is still not fast and complete enough to<br />
take over. This means, my users are still whining for an update<br />
all the time CPython gets an update.<br />
And maintaining this code gets more and more a nightmare for<br />
me, since I have the nice PyPy version, and I hate hacking this<br />
clumsy C code again and again.
</p></blockquote>
<p>The original author, Christian Tismer largely moved onto PyPy, which is still largely in it infancy (although I read through bits of the code base frequently, it’s pretty), and further development has largely been stalled minus the improvements Richard M. Tew (CCP Games) and others have done. There’s still life in it.</p>
<p>Fundamentally, Stackless modifies the interpreter internals a bit to modify the way that the C call stack is manipulated/used as well as to add other other nice bits Stackless offers (<a href="http://en.wikipedia.org/wiki/Call_stack">call stack</a>). Stackless simply doesn’t use the C call stack — all told, each microthread only has a few kilobytes of overhead, which is awesome.</p>
<p>It adds something called microthreads and does other patching to python-core. Normal OS/Posix threads require a fair amount of resources to create and run — in the case of Python, each thread has to get its own stack, this costs memory. With Stackless’ microthread support — you get “threads”, but threads which cost a significantly less, and potentially execute faster due to context switching improvements (no need to go from user-&gt;kernel-&gt;user and so on).</p>
<p><b>Point of Order</b>: Before I continue, I want to clear up a common misconception I’ve heard — Stackless, does not in any way, remove the Global Interpreter Lock. No sir. It’s still there. Lurking. Waiting to steal your candy. Also, it still has a stack, so it’s not truly “stackless”.</p>
<p>So, microthreads are smaller and require less OS hand holding for context switching, and ultimately can (and are) scheduled by the interpreter, rather than the operating system.</p>
<p><b>install note for os/x users</b>: You need to pass the “–enable-stacklessfewerregisters” to configure, otherwise, make pukes on you.</p>
<p>Stackless is a basic implementation of these — for a simple resource example usage example, I wrote a simple script which spawns 2,000 threads (sorry windows) and 2,000 tasklets. I watched the memory usage of both:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p495code1'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4951"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p495code1"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">threading</span>
<span style="color: #ff7700;font-weight:bold;">def</span> func<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">120</span><span style="color: black;">&#41;</span>
&nbsp;
threads = <span style="color: black;">&#91;</span><span style="color: #dc143c;">threading</span>.<span style="color: black;">Thread</span><span style="color: black;">&#40;</span>target=func<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2000</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> threads:
    i.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> threads:
    i.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>For the threaded script — the resident size was 42M and the virtual size was 1037. Versus the stackless version:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p495code2'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4952"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p495code2"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
<span style="color: #ff7700;font-weight:bold;">import</span> stackless
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> func<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">120</span><span style="color: black;">&#41;</span>:
        <span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        stackless.<span style="color: black;">schedule</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2000</span><span style="color: black;">&#41;</span>:
    stackless.<span style="color: black;">tasklet</span><span style="color: black;">&#40;</span>func<span style="color: black;">&#41;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
stackless.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Stackless had a resident size of 3416K and a virtual size of 22M — virtually microscopic versus the heavier thread version. Obviously, they are not line for line comparisons — the Stackless version, like other cooperative multitasking systems requires that each tasklet be a good citizen, and not block execution forever, instead rescheduling itself or otherwise yielding to allow for others to run. If a tasklet blocks on a socket, everyone blocks on that tasklet.</p>
<p>Someone asked me to track the linear growth of the threaded numbers vs. the tasklet numbers. Since I’m a sucker, I thought I’d take him up on it (OS/X 10.5, 4GB of ram, Core 2 Duo):</p>
<p><b>Threads</b>:</p>
<table border="1">
<th>Num Threads</th>
<th>Resident Size</th>
<th>Virtual Size</th>
<tr>
<td>2</td>
<td>3412K</td>
<td>23M</td>
</tr>
<tr>
<td>200</td>
<td>7336K</td>
<td>123M</td>
</tr>
<tr>
<td>2,000</td>
<td>42M</td>
<td>1037M</td>
</tr>
</table>
<p><b>Tasklets</b>:</p>
<table border="1">
<th>Num Tasklets</th>
<th>Resident Size</th>
<th>Virtual Size</th>
<tr>
<td>2</td>
<td>3128K</td>
<td>21M</td>
</tr>
<tr>
<td>200</td>
<td>3164K</td>
<td>21M</td>
</tr>
<tr>
<td>2,000</td>
<td>3408K</td>
<td>22M</td>
</tr>
<tr>
<td><b>20,000</b></td>
<td>5920K</td>
<td>24M</td>
</tr>
<tr>
<td><b>100,000</b></td>
<td>17M</td>
<td>34M</td>
</tr>
</table>
<p><i>One note — the Stackless numbers should be low, but not this low (from my understanding, and review from others), anyone have any ideas?</i></p>
<p>There’s the numbers — lots of threads is going to consume lots of ram. With stackless, a given tasklet is only a few kilobytes in average size and therefore the memory footprint is small when you start raising the count. Additionally, note the two counts at the bottom of the tasklets table; you can’t spawn that many threads (depending on your OS and configuration) and even if you could, the memory footprint would be costly.</p>
<p>Now, in the age of cheap-ass-ram, where you can trick out a desktop or server with 16GB sticks, people might argue “so what” — but on machines where memory is constrained, such as smaller notebooks, embedded devices, or game consoles — this is a critical thing to take into consideration. </p>
<p>If you look at the stackless code, there is another big thing to realize; Stackless like other frameworks or systems which use an scheduler built into the interpreter gives you the benefit/task of scheduling when your tasklets/components/etc execute. This gives you more control, but more responsibility. Stackless offers both cooperative and preemptive scheduling, however the preemptive scheduling doesn’t feel right. <a href="http://www.stackless.com/wiki/Scheduling">more on scheduling here</a></p>
<p>So, we’ve determined that stackless tasklets are smaller, right? Pretty simple.</p>
<p>If you’ve read the other things I’ve written on Kamaelia/Twisted/etc, you’ll recognize the concepts within Stackless pretty quickly — a tasklet is a component, a thread of work and tasklets intercommunicate via channels. For example, here’s a little example of two tasklets communicating:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p495code3'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4953"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p495code3"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> stackless
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> chicken<span style="color: black;">&#40;</span>channel<span style="color: black;">&#41;</span>:
    channel.<span style="color: black;">send</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'cluck'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> egg<span style="color: black;">&#40;</span>channel<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> channel.<span style="color: black;">receive</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
channel = stackless.<span style="color: black;">channel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
stackless.<span style="color: black;">tasklet</span><span style="color: black;">&#40;</span>chicken<span style="color: black;">&#41;</span><span style="color: black;">&#40;</span>channel<span style="color: black;">&#41;</span>
stackless.<span style="color: black;">tasklet</span><span style="color: black;">&#40;</span>egg<span style="color: black;">&#41;</span><span style="color: black;">&#40;</span>channel<span style="color: black;">&#41;</span>
stackless.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Pretty easy, and a tiny amount of code. The concept of tasklets/microthreads isn’t a new one — in fact, it’s how Erlang gets it’s groove on — Erlang doesn’t use native OS threads, instead, it uses microthreads scheduled by the Erlang compiler. However, <i>they are not directly comparable</i>. Stackless isn’t running across cores — Erlang does, stackless, due to the GIL, has to obey the same rules as the rest of python-core. For more on “erlang v. stackless”, see <a href="http://www.reddit.com/r/programming/comments/u2ng/ask_reddit_are_taskletschannels_in_stackless">this</a>.</p>
<p>Oh, and you can share normal object via the channel too:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p495code4'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4954"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code" id="p495code4"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> stackless
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> yes<span style="color: black;">&#40;</span>channel<span style="color: black;">&#41;</span>:
    x = channel.<span style="color: black;">receive</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    x.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'yes'</span><span style="color: black;">&#41;</span>
    channel.<span style="color: black;">send</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> no<span style="color: black;">&#40;</span>channel<span style="color: black;">&#41;</span>:
    x = channel.<span style="color: black;">receive</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    x.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'no'</span><span style="color: black;">&#41;</span>
    channel.<span style="color: black;">send</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
&nbsp;
channel = stackless.<span style="color: black;">channel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
stackless.<span style="color: black;">tasklet</span><span style="color: black;">&#40;</span>yes<span style="color: black;">&#41;</span><span style="color: black;">&#40;</span>channel<span style="color: black;">&#41;</span>
stackless.<span style="color: black;">tasklet</span><span style="color: black;">&#40;</span>no<span style="color: black;">&#41;</span><span style="color: black;">&#40;</span>channel<span style="color: black;">&#41;</span>
channel.<span style="color: black;">send</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
stackless.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> channel.<span style="color: black;">receive</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Moving on, Stackless offers something else — the ability to pickle tasklets. This means you can pickle up a tasklet and send it over the wire to another machine and then unpickle it and continue running it — channels get pickled too. Locally, this means to can save it to disk, and then resume state easily.</p>
<p>You could use this to generate a tasklet which listened on a port for data on the local machine, and passed the data off the wire to the channel — when you pickled the channel or the tasklets with that channel in scope, and sent it over the wire, they would pick up listening on the same port <b>number</b> on the remote machine. You loose current sessions, yes, but you could also detect active sessions and handle those gracefully.</p>
<p>This is nice for say, a component you wanted to be able to easily send to other machines to help load balancing. In theory, you could auto-detect new servers being added to a cluster, and when that server came up into a “ready” state, send it the daemon it should handle — and the tasklets would pick up where they left off (minus the sessions).</p>
<p>Otherwise, pickling channels and tasklets could be used for a few things — you have to think of them in terms of coroutines (<a href="http://en.wikipedia.org/wiki/Coroutine#Implementations_for_Python">here</a>) — you should be able to suspend processing state and then simply resume where you left off. If you’ve got python brains — picke-able generators. You could put them in a database; but the use of that escapes me at the moment.</p>
<p>Oh — and pickled tasklets and channels can be shared amongst different architectures too, as long as that architecture is running the same version of Stackless, and supports Stackless.</p>
<p>To continue on — if you wanted to add threads into the mix as well — Stackless tasklets can be run within Python threads, however those tasklets are local to that thread, and each thread gets it’s own scheduler. Your main application thread has it’s own scheduler, and so on.</p>
<p>Stackless’ tasklet/channel system is quite nice, however note that I’m not saying Stackless is the only way into this magical world — it’s not, especially with a plethora of coroutine/greenlet/etc packages for python today, and the continued work towards making generators more awesome. I’m just showing what Stackless can/could do.</p>
<p>The primitives within Stackless are nice — frankly, I’d like a light weight green thread implementation in python core on which we could build a nice Actor library, as well as support the lower memory footprint/etc. However, in order to use these primitives within Stackless — you’d find yourself building your own abstraction layer/framework (for example, <a href="http://pypi.python.org/pypi/concurrence">concurrence</a>) to really get a lot of mileage out of it. This is why people run twisted on top of it, CCP Games has the uthread library (which you can see <a href="http://svn.python.org/view/stackless/sandbox/libraries/uthread-ccp/uthread.py?view=markup">here</a>) and so on.</p>
<p>The cost of a deployment of Stackless can not be underestimated though — it’s got some magic assembler code within it, which isn’t the most portable of goods (versus OSes, compiler versions, compilers, etc). Some platforms simply aren’t supported due to this. Not to mention, it’s an entirely new interpreter, which has a cost much higher than that of an extension module.</p>
<p>A few people who I’ve been talking with asked me the simple question — “Why hasn’t any of this been pushed into python-core”. Well, in short — it was never really proposed (by Christian), and the changes within Stackless — the last serious discussion was from 2007 (see <a href="http://mail.python.org/pipermail/python-dev/2007-February/071037.html">this</a>).</p>
<p>With Stackless, it’s difficult — I think there is a perceived complexity about the code and then there is real complexity. I suspect both of these are high in the case of Stackless due to the nature of the problem it is trying to solve; namely bolting a feature like this onto an interpreter <b>not meant for it</b>. I think that due to this, and due to Christian and others moving onto the greener pastures of PyPy — inclusion into core simply won’t happen.</p>
<p><b>Resources:</b></p>
<ul>
<li> <a href="http://www.onlamp.com/pub/a/python/2002/02/14/pythonnews.html">http://www.onlamp.com/pub/a/python/2002/02/14/pythonnews.html</a>
<li> <a href="http://www.python.org/dev/peps/pep-0219/">http://www.python.org/dev/peps/pep-0219/</a>
<li> <a href="http://www.python.org/dev/peps/pep-0255/">http://www.python.org/dev/peps/pep-0255/</a>
<li> <a href="http://muharem.wordpress.com/2007/07/31/erlang-vs-stackless-python-a-first-benchmark/">http://muharem.wordpress.com/2007/07/31/erlang-vs-stackless-python-a-first-benchmark/</a>
<li> <a href="http://www.ibm.com/developerworks/library/l-pythrd.html">http://www.ibm.com/developerworks/library/l-pythrd.html</a>
<li> <a href="http://mail.python.org/pipermail/python-dev/2007-February/071037.html">http://mail.python.org/pipermail/python-dev/2007-February/071037.html</a>
<li> <a href="http://members.verizon.net/olsongt/stackless/why_stackless.html">http://members.verizon.net/olsongt/stackless/why_stackless.html</a>
<li> <a href="http://code.google.com/p/stacklessexamples/wiki/StacklessExamples">http://code.google.com/p/stacklessexamples/wiki/StacklessExamples</a>
<li> <a href="http://islab.org/stackless/">http://islab.org/stackless/</a>
</ul>
<p class="wp-flattr-button"></p>]]></content:encoded>
			<wfw:commentRss>http://jessenoller.com/2009/02/23/stackless-you-got-your-coroutines-in-my-subroutines/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>PyCon 2009: In ur brain, giving you the pythons</title>
		<link>http://jessenoller.com/2009/02/21/pycon-2009-in-ur-brain-giving-you-the-pythons/</link>
		<comments>http://jessenoller.com/2009/02/21/pycon-2009-in-ur-brain-giving-you-the-pythons/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 19:48:10 +0000</pubDate>
		<dc:creator>jesse</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[pycon 2009]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://jessenoller.com/?p=489</guid>
		<description><![CDATA[ I, along with a whole heck of a lot of other people will be attending PyCon in march. You should know about this by now, unless you're living under a rock, or in a shoebox (I like shoeboxes). 

PyCon 09 is turning out to be one of the ones I am most excited ...]]></description>
			<content:encoded><![CDATA[<p><a href="http://us.pycon.org/"><img src="http://us.pycon.org/media/2009/public/pycon2009-horizontal-large-215x135.png" alt="PyCon 2009: Chicago"></a> I, along with a whole heck of a lot of other people will be attending PyCon in march. You should know about this by now, unless you’re living under a rock, or in a shoebox (I like shoeboxes). </p>
<p>PyCon 09 is turning out to be one of the ones I am most excited about in some time — barring the fact they let me actually stand up and speak about something, there’s a ton of other excellent and exciting things going on.</p>
<p>I will be doing two talks — “Introduction to Multiprocessing in Python” on Friday, at 3:20 PM, and “Concurrency and Distributed Computing with Python Today” at 3:20 PM Saturday. </p>
<p>The former talk is easy, given it will be focused on introducing the multiprocessing module to the masses, and taking questions about it (be gentle, I just work here). The latter is a much bigger beast. I’ve been blogging about my research in my pycon 2009 category, and I still have a pile of things to keep adding to that. The talk will attempt to differentiate concurrency from distributed systems, and show the various toolkits/frameworks/etc in the ecosystem today, to help you build both types of systems.</p>
<p>Given both talks are 45 minutes in length, I will be publishing my talk notes (my slides are not going to be heavy weight) and other information here.</p>
<p>In addition to me speaking, which may or may not be exciting, there’s one helluva ton of other talks which simply look awesome. </p>
<p>My schedule looks like this:</p>
<ul>
<li> Thursday: Python Language Summit, where I will endeavor to be smart.
<li> Friday: How to give a python talk
<li> Friday: Using Windmill
<li> Friday: Introduction to Python Profiling or How Python is Developed, to harass Brett.
<li> Friday: Panel — Python VMs
<li> Friday: Building an Automated QA infrastructure using Open Source Tools
<li> Friday: Twisted, AMQP and Thrift: Bridging messaging and RPC for building scalable distributed applications
<li> Friday: My Talk (I figure I should go to it)
<li> Friday: A Whirlwind Excursion through Writing a C Extension or Challenges and Opportunities for Python
<li> Thursday: Plugins and monkeypatching: increasing flexibility, dealing with inflexibility
<li> Saturday: The (lack of) design patterns in Python or the Pinax talk
<li> Saturday: Class Decorators: Radically Simple
<li> Saturday: Panel: Object Relational Mappers: Philosophies and Design Decisions.
<li> Saturday: Drop ACID and think about data (I wonder if we can take this literally, if he has scary slides though, we all might trip balls)
<li> Saturday: My Talk, which is up against Bruce Eckel and Raymond H — I expect no one to show up.
<li> Sunday: Panel: Functional Testing Tools in Python
<li> Sunday: Designing a web framework: Django’s design decisions
</ul>
<p>This doesn’t even cover the open space discussions which I might attend — including the “<a href="http://us.pycon.org/2009/openspace/WritingAboutPython/" target="_blank">Writing About Python</a>” one Doug Hellmann is putting together as well as the “<a href="http://us.pycon.org/2009/openspace/teachme-webtesting/" target="_blank">Teach Me Web Testing</a>” one by Steve Holden.</p>
<p>After the main conference, I’ll be sticking around until Thursday morning for the sprints, at which point I should be sufficiently burned out on python stuff, I will fully convert over to being a full time burger flipper.</p>
<p>Right now there are 620 registered people <b>who made their attendance public</b> I don’t know how many there are in total.</p>
<p>Hope to see you there!</p>
<div style="text-align:center;"><img src="http://jessenoller.com/wp-content/uploads/2009/02/funny-pictures-cat-dog-paper-bag-shrubbery-holy-grail.jpg" alt="funny-pictures-cat-dog-paper-bag-shrubbery-holy-grail.jpg" border="0" width="500" height="329" /></div>
<p class="wp-flattr-button"></p>]]></content:encoded>
			<wfw:commentRss>http://jessenoller.com/2009/02/21/pycon-2009-in-ur-brain-giving-you-the-pythons/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Twisted — hello, asynchronous programming</title>
		<link>http://jessenoller.com/2009/02/11/twisted-hello-asynchronous-programming/</link>
		<comments>http://jessenoller.com/2009/02/11/twisted-hello-asynchronous-programming/#comments</comments>
		<pubDate>Thu, 12 Feb 2009 01:22:14 +0000</pubDate>
		<dc:creator>jesse</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[pycon 2009]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://jessenoller.com/?p=477</guid>
		<description><![CDATA[ 

Note:This is the third post in what I hope will be a series leading up to my concurrency/distributed systems talk at PyCon. I'm steadily working through experimenting with and learning the various frameworks/libraries in the python ecosystem.

I reserve the right (and probably will) to revise these entries based on feedback from people (mainly ...]]></description>
			<content:encoded><![CDATA[
<p><b>Note:</b>This is the third post in what I hope will be a series leading up to my concurrency/distributed systems talk at PyCon. I’m steadily working through experimenting with and learning the various frameworks/libraries in the python ecosystem.</p>
<p>I reserve the right (and probably will) to revise these entries based on feedback from people (mainly the author(s) of said tool(s)). I will also add additional bits and pieces as I learn and explore more. Additionally, thanks to glyph for giving me a hell of a lot of feedback.<b>/Note</b></p>
<p>Twisted is the 800 lbs gorilla of the “concurrency” frameworks. It’s been around for awhile, has a large following — it’s used by everyone from Apple (<a href="http://www.macosforge.org/" target="_blank">iCal server</a>) to Buildbot <a href="http://buildbot.net/trac" target="_blank">Buildbot</a>. It has a literal ton of sub projects and other “semi attached appendages”.<br />
<span id="more-477"></span><br />
Twisted can be daunting for almost everyone — while it is conceptually simple, the docs and examples could be more approachable. People look at Twisted as an all-or-nothing bet when considering it for their applications, which to an extent, it is.</p>
<p>But if I am going to do a concurrency/distributed systems talk — I can’t ignore one of the most widely used and original frameworks in this space.</p>
<p>So, as always — these are my semi-rough notes diving into Twisted-core. Like Kamaelia, I am going to side step the asteroid ring which surrounds Twisted (or tentacles… I can’t decide which to use) and delve into the core.</p>
<p>Moving along — Twisted is based around asynchronous programming — a model for adding a great deal of concurrency to your application via non blocking calls or isolating blocking calls “elsewhere”. This is largely the same approach that GUI toolkits use wherein a given event is assigned something to run when an “event” occurs, such as a button click or data is available. Glyph sent me a very simple side-by-side:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p477code5'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4775"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p477code5"><pre class="python" style="font-family:monospace;">    reactor.<span style="color: black;">listenTCP</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">8080</span>, someFactory<span style="color: black;">&#41;</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p477code6'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4776"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p477code6"><pre class="python" style="font-family:monospace;">    button.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'clicked'</span>, someCallback<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>This shows the essential aspect of asynchronus/event-driven systems — you tell x that when y occurs, call z. It really is conceptually simple. The main loop of the application simply focuses on constructing these relationships, and executing the callbacks when the event occurs.</p>
<p>Twisted’s focus is on network-based applications — these mesh well with the idea of non-blocking I/O, where you have to fundamentally chunk your work up into small pieces which take a very short time to execute. Networked apps spend most of their time waiting for data to come in over the wire. Twisted also has faculties to isolate CPU intensive and/or blocking calls within threads or processes.</p>
<p>I’m going to focus on two of the core components — Deferreds and the Reactor, this should help illustrate what the core paradigm is.</p>
<p>Deferreds are a core component of Twisted — a deferred in the simplest terms is an object that when created, represents some Thing which will eventually return Something or Error — a placeholder for something in the future. The way you handle Something or Error is you tell the deferred that if it gets Something, it should call consume_function, otherwise — if it gets an Error, it should call error_function. Easy!</p>
<p>Take the below for example — read_mail and error_function are what’s known as callbacks — a function which is called by something else when something occurs (I hate me for writing that).</p>
<p>Callbacks are really simple, as illustrated here:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p477code7'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4777"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code" id="p477code7"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">def</span> read_mail<span style="color: black;">&#40;</span>mailitems<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> mailitems
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> read_error<span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">Exception</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'error: %s'</span> <span style="color: #66cc66;">%</span> error<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> wait_for_mail<span style="color: black;">&#40;</span>callback, errback<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            mail = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">isfile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'mail'</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> mail:
                callback<span style="color: black;">&#40;</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'mail'</span>,<span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span>.<span style="color: black;">readlines</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #ff7700;font-weight:bold;">pass</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">Exception</span>, e:
            errback<span style="color: black;">&#40;</span>e<span style="color: black;">&#41;</span>
&nbsp;
wait_for_mail<span style="color: black;">&#40;</span>read_mail, read_error<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Sidenote: Callbacks are stupid easy with python. I love them. Heck, you can pickle a callback and shoot it over the wire to another machine. Callbacks are cool. You should watch Alex Martelli’s <a href="http://www.youtube.com/watch?v=LCZRJStwkKM" target="_blank">callback talk on youtube</a>.</p>
<p>In any case, you tell a deferred (the object which represents a promise of something) what to do when data is returned — you do this by generating a deferred, and then adding callbacks onto it — note that the function wait_for_mail needs to <b>return</b> a deferred. In this toy example, I want to just look for a “mail file” on disk, and then if it exists, return a string to the callback:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p477code8'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4778"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code" id="p477code8"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">internet</span> <span style="color: #ff7700;font-weight:bold;">import</span> reactor, defer
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> read_mail<span style="color: black;">&#40;</span>mailitems<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> mailitems
    reactor.<span style="color: black;">stop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> wait_for_mail<span style="color: black;">&#40;</span>d=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> d:
        d = defer.<span style="color: black;">Deferred</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">isfile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'mail'</span><span style="color: black;">&#41;</span>:
        reactor.<span style="color: black;">callLater</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, wait_for_mail, d<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        d.<span style="color: black;">callback</span><span style="color: black;">&#40;</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'mail'</span>,<span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span>.<span style="color: black;">readlines</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> d
&nbsp;
deferred = wait_for_mail<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
deferred.<span style="color: black;">addCallback</span><span style="color: black;">&#40;</span>read_mail<span style="color: black;">&#41;</span>
reactor.<span style="color: black;">callLater</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">60</span>, reactor.<span style="color: black;">stop</span><span style="color: black;">&#41;</span>
reactor.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>I wanted to keep this as simple as possible, as it illustrates some things that fundamentally tripped me up at first.</p>
<p>First typically, if you were to solve a problem — say, polling a mailbox, you might do this:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p477code9'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4779"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code" id="p477code9"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">sys</span>, <span style="color: #dc143c;">threading</span>, <span style="color: #dc143c;">time</span>
<span style="color: #ff7700;font-weight:bold;">def</span> read_mail<span style="color: black;">&#40;</span>mailitems<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> mailitems
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> wait_for_mail<span style="color: black;">&#40;</span>reader<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">isfile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'mail'</span><span style="color: black;">&#41;</span>:
        <span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span>.1<span style="color: black;">&#41;</span>
&nbsp;
    reader<span style="color: black;">&#40;</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'mail'</span>,<span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span>.<span style="color: black;">readlines</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
t = <span style="color: #dc143c;">threading</span>.<span style="color: black;">Thread</span><span style="color: black;">&#40;</span>target=wait_for_mail, args=<span style="color: black;">&#40;</span>read_mail,<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
t.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
t.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Or some other pattern of spawning a thread and then waiting for that thread to chuck the data back to you. The thread gets out of your way, and doesn’t force the main part of the program to block, sort of. In fact, with Twisted, the main part of your application <b>is required</b> not to block.</p>
<p>As a point of order, you could do the same thing with Twisted like this:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p477code10'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47710"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p477code10"><pre class="python" style="font-family:monospace;">...
<span style="color: black;">d</span> = deferToThread<span style="color: black;">&#40;</span>wait_for_mail<span style="color: black;">&#41;</span>
...</pre></td></tr></table></div>

<p>Threads are the common way of pushing blocking work off to the side — most of us have had to do it at one point or another. In the Twisted world, this has to be turned on it’s head a bit.</p>
<p>In Twisted, you have to split your problem into small, individual functions/methods — ideally, you isolate the really blocking part (say, waiting for a file to appear) in it’s very own function. You make the non blocking parts — say checking initial existence and constructing the deferred object run as quickly as possible, and then return the deferred — a promise of data to come via the slow method. The slow part in the threading example is the time.sleep().</p>
<p>You then <b>schedule</b> that blocking call to run, it shouldn’t block, but rather it should poll for data or changes in it’s buffer(s) and either reschedule itself to run if there is no data, or return the data if there is. This event is time based — but the same applies to adding a callback to a non-time-based item, such as setting up something which listen on a socket for data.</p>
<p>The fact you schedule work within the reactor tripped me up at first. I was thinking in blocking terms though (Twisted has a faculty for passing blocking work off to threads via the deferToThread call) — the function kept wanting to block instead of polling, or looking for state change. Everything needs to be scheduled in one way or another.</p>
<p>Glyph wisely pointed out that this is a common issue with people rethinking concurrency in terms of “discrete events”. For example, most people are content to think about concurrency in terms of workers “who are off doing things”. In theory, those workers are “always doing something” — in reality, the operating system is simply suspending your worker(s) until an interrupt (i.e.) discreet event occurs, which causes the worker(s)/app unblock.</p>
<p>Glyph suggest the following as a good example using generator syntax:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p477code11'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47711"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code" id="p477code11"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">internet</span>.<span style="color: black;">defer</span> <span style="color: #ff7700;font-weight:bold;">import</span> inlineCallbacks, returnValue
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">internet</span>.<span style="color: black;">task</span> <span style="color: #ff7700;font-weight:bold;">import</span> deferLater
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">internet</span> <span style="color: #ff7700;font-weight:bold;">import</span> reactor
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> deferredSleep<span style="color: black;">&#40;</span>howLong<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> deferLater<span style="color: black;">&#40;</span>reactor, howLong, <span style="color: #ff7700;font-weight:bold;">lambda</span> : <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>
&nbsp;
@inlineCallbacks
<span style="color: #ff7700;font-weight:bold;">def</span> wait_for_mail<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">isfile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'mail'</span><span style="color: black;">&#41;</span>:
            returnValue<span style="color: black;">&#40;</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'mail'</span>,<span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span>.<span style="color: black;">readlines</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">yield</span> deferredSleep<span style="color: black;">&#40;</span><span style="color: #ff4500;">1.0</span><span style="color: black;">&#41;</span>
&nbsp;
@inlineCallbacks
<span style="color: #ff7700;font-weight:bold;">def</span> check_mail<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    mail = <span style="color: #ff7700;font-weight:bold;">yield</span> wait_for_mail<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'got mail'</span>, mail</pre></td></tr></table></div>

<p>The example he provided is interesting — it has no “scheduling” involved, and instead it uses something I didn’t see originally — <a href="http://twistedmatrix.com/documents/current/api/twisted.internet.task.html">deferLater</a> and <a href="http://twistedmatrix.com/documents/current/api/twisted.internet.defer.html#inlineCallbacks">inlineCallback</a>, inlineCallback accepts a function as an argument, that function can yield a deffered or call returnValue, essentially anywhere where you would normally block, you simply yield. In this case, we simply call deferLater if the file doesn’t exist, which tells the reactor to re-run this some time in the future.</p>
<p>Before I move off the basic view of deferreds — there’s something to note, deferreds can accept a chain of callbacks:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p477code12'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47712"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code" id="p477code12"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">internet</span> <span style="color: #ff7700;font-weight:bold;">import</span> reactor, defer
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> read_mail<span style="color: black;">&#40;</span>mailitems<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> mailitems
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;this %s is junk&quot;</span> <span style="color: #66cc66;">%</span> mailitems
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> shred_mail<span style="color: black;">&#40;</span>mailitems<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'buzzzzz: %s'</span> <span style="color: #66cc66;">%</span> mailitems
    reactor.<span style="color: black;">stop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> wait_for_mail<span style="color: black;">&#40;</span>d=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> d:
        d = defer.<span style="color: black;">Deferred</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">isfile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'mail'</span><span style="color: black;">&#41;</span>:
        reactor.<span style="color: black;">callLater</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, wait_for_mail, d<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        d.<span style="color: black;">callback</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'letter'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> d
&nbsp;
deferred = wait_for_mail<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
deferred.<span style="color: black;">addCallback</span><span style="color: black;">&#40;</span>read_mail<span style="color: black;">&#41;</span>
deferred.<span style="color: black;">addCallback</span><span style="color: black;">&#40;</span>shred_mail<span style="color: black;">&#41;</span>
reactor.<span style="color: black;">callLater</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">60</span>, reactor.<span style="color: black;">stop</span><span style="color: black;">&#41;</span>
reactor.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>And the output:</p>
<pre>
letter
buzzzzz: this letter is junk
</pre>
<p>This allows each callback chained onto a deferred to alter the data in some form — the modified data is passed to the next callback in the chain. It’s not really magic. It’s simply a series of functions to call when an event occurs.</p>
<p>One thing to keep in mind when thinking about Twisted — Twisted is <b>single threaded</b>. Ok, not really — sort of. Glyph called me out on this, and rightly so. In reality all I/O in Twisted is single-threaded, most Twisted APIs are not thread safe and deferred callback chains execute in a single thread… But — Twisted does support both threads and processes. There is no reason why you can’t use a library which uses threads in your twisted application for example. You can use threads with twisted, so don’t worry too much about that.</p>
<p>On the other hand, if your entire application is a thread-spawnfest, you might want to reconsider — the design of your app, that is. /flamebait</p>
<p>All code executes in the main thread of a single python process, which is why when discussing deferreds and blocking calls, it is so important to break your problem down into the smallest steps possible and isolate/rework blocking code into deferred actions.</p>
<p>Onto the reactor then.</p>
<p>The reactor is the event loop mechanism for Twisted. It takes care of executing all of the various timed actions and the execution of the callback/errback stack. Timed actions can be deferreds, etc. Deferreds are simply objects executed by the Reactor.</p>
<p>You’ll notice in the example above, we didn’t create an instance of the reactor, instead we just imported it. If you look at Twisted.internet.reactor — you’ll see this removes any previous instances of reactor in sys.modules and then calls install() on the target reactor. This means the reactor is a singleton, all future imports/calls will always refer to this reactor.</p>
<p>Now, the documentation in internet.reactor mentions that new application code should pass around an instance of a reactor — this moves away from the reactor-as-a-singleton (the simple behavior) and into something a bit more interesting. Glyph pointed out the obvious usefulness for this — testability, you can pass in a reactor rather than grabbing it from the global, you have more control.</p>
<p>You can also use this to group a series of actions both timed and otherwise, connections/etc within a given reactor, and then create a meta-reactor to control the multiple reactors. Reactors, all the way down.</p>
<p>See, Twisted has multiple types of reactors — there are reactors based on select (the default), GTK, Cocoa (PyObjc), etc. Each reactor manages the scheduling and execution of the tasks added to it in it’s on unique style, but implement a common <a href="http://twistedmatrix.com/documents/8.2.0/api/twisted.internet.interfaces.html">interface</a>. Application code should not <b>care</b> what reactor is running — the reactor is an abstraction above other, some operating system optimized polling/looping mechanisms. For example, GTK+ looping and polling, select on Linux/etc.</p>
<p>Quoting Glyph:</p>
<blockquote><p>The idea of all this is that Twisted code is at the top of the food chain.<br />
GTK+ networking code can only run in GTK+ programs, kqueue networking code can<br />
only run on FreeBSD machines, but Twisted networking code can run anywhere it<br />
can get its hands on something that looks even vaguely like select().  If you<br />
want a Windows desktop program and a UNIX server program to run the same<br />
networking code, but have radically different event APIs under the covers for<br />
good performance, Twisted has you covered.</p></blockquote>
<p>You can install a given reactor by doing the from twisted.xxx.reactor_name and calling the install() method (which is all twisted.internet.reactor does). The preferred method is to use the “–reactor” argument to the twistd/trial tools.</p>
<p>Twisted is fundamentally a networking stack: it’s built to solve non computationally intensive tasks that require a lot of waiting and polling for data: networking fits perfectly into this. With additions — it can also serve as a platform for computationally intensive/distributed applications. For example, the <a href="https://launchpad.net/ampoule/">ampoule</a> add on.</p>
<p>In the networking sense: Twisted is perfect as long as you can deconstruct and rethink the way you solve day to day problems, remove or rethink blocking code, switch your application model to something event/message driven.</p>
<p>Admittedly; Twisted isn’t for me (right now) — but with time, it could be, and it could work great for your application today. It has libraries for just about any protocol you could possibly ask for. It’s code base is <b>huge</b> and actually has some pretty cool code inside of it. The catch is — you don’t port an application <b>to</b> Twisted: You write a Twisted application in most cases.</p>
<p>However; it can also be hard to approach — both within the code, and the documentation. You see questions pop up all the time “I think Twisted does this” — and while it probably does it could take you awhile just to grok what it is to be Twisted.</p>
<p>For example — dumb down the examples. While the finger tutorial is “the introduction” starting down on a level where you take a normal, single threaded application (perhaps using generators), port it to threads, point out the issues there, and then port it to twisted, using as little “twisted magic” as possible.</p>
<p>This isn’t to say it’s impossible to grok; but helping walk people through learning how to begin to think asynchronously, rather than explaining the esoteric or the One True way of doing something, consider the positive feedback that Steve Holden’s “Teach Me Twisted” got (summary <a href="http://catherinedevlin.blogspot.com/2008/03/teach-me-twisted.html">here</a>). Assume most people can’t spell asynchronous, and build it up.</p>
<p>The Django documentation is probably one of my favorite examples of this — it starts very simple and very approachable and walks the user through everything “from the beginning”.</p>
<h3>Related Links</h3>
<ul>
<li><a href="http://stackoverflow.com/questions/80617/asychronous-programming-in-python-twisted/81456#81456" target="_blank">http://stackoverflow.com/questions/80617/asychronous-programming-in-python-twisted/81456#81456</a>
<li> <a href="http://www.usenix.org/events/usenix03/tech/freenix03/full_papers/lefkowitz/lefkowitz_html/index.html" target="_blank">http://www.usenix.org/events/usenix03/tech/freenix03/full_papers/lefkowitz/lefkowitz_html/index.html</a>
<li> <a href="http://mumak.net/stuff/Twisted-intro.html" target="_blank">http://mumak.net/stuff/Twisted-intro.html</a>
<li> <a href="http://sluggo.scrapping.cc/python/Twisted_finger_gentle.txt" target="_blank">http://sluggo.scrapping.cc/python/Twisted_finger_gentle.txt</a>
<li> <a href="http://Twistedmatrix.com/projects/core/documentation/howto/defer.html" target="_blank">http://Twistedmatrix.com/projects/core/documentation/howto/defer.html</a>
<li><a href="http://Twistedmatrix.com/projects/core/documentation/howto/gendefer.html" target="_blank"> http://Twistedmatrix.com/projects/core/documentation/howto/gendefer.html</a>
<li> <a href="http://Twistedmatrix.com/projects/core/documentation/howto/async.html" target="_blank">http://Twistedmatrix.com/projects/core/documentation/howto/async.html</a>
<li><a href="http://Twistedmatrix.com/projects/core/documentation/howto/reactor-basics.html" target="_blank">http://Twistedmatrix.com/projects/core/documentation/howto/reactor-basics.html</a>
<li><a href="http://www.nightmare.com/pythonwin/async_sockets.html" target="_blank">http://www.nightmare.com/pythonwin/async_sockets.html</a>
<li><a href="http://enthusiasm.cozy.org/archives/2009/02/twisted-nevermind" target="_blank">http://enthusiasm.cozy.org/archives/2009/02/twisted-nevermind</a>
</ul>
<p class="wp-flattr-button"></p>]]></content:encoded>
			<wfw:commentRss>http://jessenoller.com/2009/02/11/twisted-hello-asynchronous-programming/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Circuits: event driven components.</title>
		<link>http://jessenoller.com/2009/01/31/circuits-event-driven-components/</link>
		<comments>http://jessenoller.com/2009/01/31/circuits-event-driven-components/#comments</comments>
		<pubDate>Sat, 31 Jan 2009 17:32:38 +0000</pubDate>
		<dc:creator>jesse</dc:creator>
				<category><![CDATA[concurrency]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[pycon 2009]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://jessenoller.com/?p=407</guid>
		<description><![CDATA[Next up in the GBLOSTR (great big list of stuff to review) is the Circuits library by James Mills (here and here)  I'm familiar only with James Mills' posts on python-list, but more recently, I know he's been working on getting some level of multiprocessing into circuits - circuits was already on my ...]]></description>
			<content:encoded><![CDATA[<p>Next up in the GBLOSTR (great big list of stuff to review) is the Circuits library by James Mills (<a href="http://pypi.python.org/pypi/circuits" target="_blank">here</a> and <a href="http://freehg.org/u/prologic/circuits/" target="_blank">here</a>)  I’m familiar only with James Mills’ posts on python-list, but more recently, I know he’s been working on getting some level of multiprocessing into circuits — circuits was already on my research list, but I bumped it up on the queue because we started chatting.</p>
<p>Let me state this: these are slightly cleaned up versions of my notes as I am learning these modules — some of them have higher learning curves for me than others.</p>
<p>Circuits is, well — an event based “framework” (again, note the small f) based around the concept of Components (big C!) consuming/reacting and in turn generating events — all asynchronously.</p>
<p>James’ goals seem pretty simple — build something with no external dependencies, that’s compact (I should say, the core.py is &lt; 500 lines) and that makes it easy to build scalable messaging based (event based) systems. Did he succeed — don’t know! Let’s dig in.</p>
<p><span id="more-407"></span></p>
<p><b>Note</b>:Given his site is/was down at the time of this writing, I simply cloned the hg repo (<a href="http://freehg.org/u/prologic/circuits/" target="_blank">here</a>) and used that for all the code and documentation, which is why I am going to sparse on direct links to the documentation. Also note, that pulling from tip introduces dependencies on python 2.6.</p>
<p>Starting with the quickstart — always a good place to jump to, James outlines the very basics — as in, the very, very basics via a simple code example, which I have paraphrased, renamed the objects of and… you get the picture:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code13'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40713"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code" id="p407code13"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> circuits <span style="color: #ff7700;font-weight:bold;">import</span> listener, Event, Component, Manager
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> AnEvent<span style="color: black;">&#40;</span>Event<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;AnEvent Event&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> TheComponent<span style="color: black;">&#40;</span>Component<span style="color: black;">&#41;</span>:
&nbsp;
    @listener<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;anevent&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> on_anevent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;hello, I got an event&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    manager = Manager<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    thecomponent = TheComponent<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    manager += thecomponent
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>:
        manager.<span style="color: black;">push</span><span style="color: black;">&#40;</span>AnEvent<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">&quot;anevent&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            manager.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">KeyboardInterrupt</span>:
            <span style="color: #ff7700;font-weight:bold;">break</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>And of course, if you run this — you see “hello, I got an event” print 10 times. Simple! But here there be magic, so let’s break it down. First, the events.</p>
<p>Here, we subclass and generate a new event:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code14'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40714"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p407code14"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> AnEvent<span style="color: black;">&#40;</span>Event<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;AnEvent Event&quot;</span></pre></td></tr></table></div>

<p>If you look in core.py, you’ll find that Event is a container — there’s some magic here at first glance — but really all this does (see __new__) is construct a new object of the passed in class, and chain any arguments into attributes. The rest is just accessing and comparison — for example:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code15'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40715"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p407code15"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">from</span> circuits <span style="color: #ff7700;font-weight:bold;">import</span> Event          
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">class</span> x<span style="color: black;">&#40;</span>Event<span style="color: black;">&#41;</span>:
... 	<span style="color: #483d8b;">&quot;an x event&quot;</span>
... 
<span style="color: #66cc66;">&gt;&gt;&gt;</span> y = x<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>,<span style="color: #ff4500;">2</span>,<span style="color: #ff4500;">3</span>,<span style="color: #ff4500;">4</span>,arg_one=<span style="color: #483d8b;">'foo'</span>,arg_two=<span style="color: #483d8b;">'bar'</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span> y
<span style="color: #66cc66;">&lt;</span>x/ <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">4</span>, arg_two=bar, arg_one=foo<span style="color: black;">&#41;</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span></pre></td></tr></table></div>

<p>This means, that you can pass in any number of positional arguments and keyword arguments, and they’ll be packed into your event. More on this later.</p>
<p>Moving on, the next thing we define is TheComponent:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code16'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40716"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p407code16"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> TheComponent<span style="color: black;">&#40;</span>Component<span style="color: black;">&#41;</span>:
&nbsp;
    @listener<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;anevent&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> on_anevent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;hello, I got an event&quot;</span></pre></td></tr></table></div>

<p>The parent class of this object is a little bit more magical. James doesn’t seem shy of the metaprogramming:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code17'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40717"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p407code17"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Component<span style="color: black;">&#40;</span>BaseComponent<span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #0000cd;">__metaclass__</span> = HandlersType</pre></td></tr></table></div>

<p>Nuts. Right above it though is the definition of BaseComponent which is slightly simpler but reveals something interesting — each component can be passed in a channel, and the default is None (more on channels in a bit). Additionally, we see BaseComponent is a subclass of a Manager. Components are managers, and managers are components. </p>
<p>Finkle is einhorn, einhorn is Finkle!</p>
<p>The metaclass does magical object construction stuff and method management/etc. Dragons.</p>
<p>So, the superclass has two addition methods — register() and unregister() which control the component’s registration with the manager (more later). Otherwise, it doesn’t have a lot else, except for the on_anevent() method we’ve added.</p>
<p>And made fancy with a decorator (mandatory pieces of flair)!</p>
<p>This code bit:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code18'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40718"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p407code18"><pre class="python" style="font-family:monospace;">    @listener<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;anevent&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> on_anevent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;hello, I got an event&quot;</span></pre></td></tr></table></div>

<p>Essentially means “this method reacts to this event” — so, let’s look at the listener decorator a bit. The decorator is in core.py, and the docstring explains a lot more about the various arguments the decorator can take, but not very clearly. I guess you had to be there.</p>
<p>The one thing you notice though, is that the decorator adds some method attributes to your method — things like f.type, f.target, etc. And then something called f.br, the use of which isn’t clear to me right now. You can however have a single handler listen for multiple events:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code19'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40719"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p407code19"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> TheComponent<span style="color: black;">&#40;</span>Component<span style="color: black;">&#41;</span>:
&nbsp;
    @listener<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;foobar&quot;</span>, <span style="color: #483d8b;">&quot;anevent&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> on_anevent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;i listen for foobar and anevent&quot;</span></pre></td></tr></table></div>

<p><b>note</b>: James explained the .br attribute:<br />
<blockquote>
handler.br is used in the BaseComponent’s send(…), and iter(…). It is used to determine which “branch” to follow. The args and kwargs of an Event are intelligently applied to an event handler depending on the signature of the event handler. (It took some time to get right — but basically it means you can’t go wrong!)
</p></blockquote>
<p>In short — we now have a registered listener for an event named “anevent” — when an event is pushed (more on this later). More recently James altered it so that if you define a component, any method which doesn’t start with a _ in the name will explicitly become an event handler of “listener” type and listens on a channel which is based off the method name.</p>
<p>We can refactor the original code like this:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code20'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40720"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p407code20"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> TheComponent<span style="color: black;">&#40;</span>Component<span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> anevent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;hello, I got an event&quot;</span></pre></td></tr></table></div>

<p>And it works just as well — which is a nice improvement. Here’s the note from James on this:</p>
<blockquote><p>
Basically, the new HandlersType (metclass) means that every method defined in a sub-classes Component that have not been previously defined as event handlers with the @listener decorator or do not start with a _, are automagically turned into event handlers listening on a channel that is the name of the method.</p>
<p>The use of the @listener decorator is still required for:</p>
<ul>
<li>Defining filters
<li>Defining event handlers listening on multiple channels.
<li>Defining event handlers listening on foreign targets.
</ul>
</blockquote>
<p>Next up is the main function — here we instantiate a new Manager object, which if you look at the code of this, you’ll notice right off the bat that there’s a startling number of __ method overloading. Which explains this line:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code21'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40721"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p407code21"><pre class="python" style="font-family:monospace;">    manager += thecomponent</pre></td></tr></table></div>

<p>This is handled by the manager’s __iadd__ method:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code22'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40722"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p407code22"><pre class="python" style="font-family:monospace;">    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__iadd__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, y<span style="color: black;">&#41;</span>:
        y.<span style="color: black;">register</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">manager</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">hasattr</span><span style="color: black;">&#40;</span>y, <span style="color: #483d8b;">&quot;registered&quot;</span><span style="color: black;">&#41;</span>:
            y.<span style="color: black;">registered</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span></pre></td></tr></table></div>

<p>This means that when you append it onto the manager (something more explicit would be nice — brevity and terseness be damned) it calls the register function on the component. Reading through that method is actually quite telling as it introspects the current object (a component) and extracts the callable methods and then pulls out the handlers/channels for a given event and calls .add on the manager. A given component may have multiple listeners for a given event inside of a component:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code23'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40723"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p407code23"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> TheComponent<span style="color: black;">&#40;</span>Component<span style="color: black;">&#41;</span>:
&nbsp;
    @listener<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;foobar&quot;</span>, <span style="color: #483d8b;">&quot;anevent&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> on_anevent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;i listen for foobar and anevent&quot;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> anevent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;hello, I got an event&quot;</span></pre></td></tr></table></div>

<p>These handlers are all registered with the manager. Now, something I want to clear up is that when you declare:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code24'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40724"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p407code24"><pre class="python" style="font-family:monospace;">    @listener<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;anevent&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> on_anevent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;hello, I got an event&quot;</span></pre></td></tr></table></div>

<p>The “anevent” defines the <b>channel</b> that listener listens on. It’s easy to say “listens for events” — but really what this is is a subscription to a channel. This means you can define a listener with, well — no event:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code25'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40725"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p407code25"><pre class="python" style="font-family:monospace;">    @listener<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #008000;">all</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;i listen for everything&quot;</span></pre></td></tr></table></div>

<p>It’s like having all the premium channels. </p>
<p>Back to the manager though (the above was a light bulb going off in my head) — next we see that we “push” events into the manager. This is actually pretty simple:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code26'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40726"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code" id="p407code26"><pre class="python" style="font-family:monospace;">    <span style="color: #ff7700;font-weight:bold;">def</span> push<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event, channel, target=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;E.push(event, channel, target=None) -&gt; None
&nbsp;
        Push the given event onto the given channel.
        This will queue the event up to be processed later
        by flushEvents. If target is given, the event will
        be queued for processing by the component given by
        target.
        &quot;&quot;&quot;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">manager</span> == <span style="color: #008000;">self</span>:
            <span style="color: #008000;">self</span>._queue.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>event, channel, target<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">manager</span>.<span style="color: black;">push</span><span style="color: black;">&#40;</span>event, channel, target<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>This means we can push events into the manager, and target them at a specific component. The definition of an event in the case of a listener is actually the creation of a <b>channel</b>.</p>
<p>The push method exposes something else — it seems possible to create a manager which is actually a pointer to another manager (a proxy) alas, I don’t see how to do that. Hooray!</p>
<p>So, we can create new events and push them into the manager which pipes them off to the channels who have assigned listeners. Easy! We flush the manager’s queue so all events are pushed to the components, and we’re done.</p>
<p>So what can we use these basics for? Easy — building components which stack on top of each other which contain other components which subscribe to a given event. In the examples directory, James has done an excellent job showcasing a lot of problems which he solves using the core circuits library. In fact, the examples explain a lot more about how things work than the core code itself.</p>
<p>One of the questions I had in working though all of this, is what happens if you define a general event — can the handler gain access to arguments within the event? Does it need to? Is it simply sufficient for a listener on a given channel to know the name/type of an event and react to it?</p>
<p>The answer is, well, yesandno. Let’s say we do this:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code27'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40727"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code" id="p407code27"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> circuits <span style="color: #ff7700;font-weight:bold;">import</span> listener, Event, Component, Manager
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> AnEvent<span style="color: black;">&#40;</span>Event<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;AnEvent Event&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> TheComponent<span style="color: black;">&#40;</span>Component<span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> anevent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> args, kwargs
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    manager = Manager<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    thecomponent = TheComponent<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    manager += thecomponent
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>:
        manager.<span style="color: black;">push</span><span style="color: black;">&#40;</span>AnEvent<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>,<span style="color: #ff4500;">2</span>,<span style="color: #ff4500;">3</span>, no=<span style="color: #483d8b;">'yes'</span>, yes=<span style="color: #008000;">False</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">&quot;anevent&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            manager.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">KeyboardInterrupt</span>:
            <span style="color: #ff7700;font-weight:bold;">break</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>You would see:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code28'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40728"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p407code28"><pre class="python" style="font-family:monospace;"><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'yes'</span>: <span style="color: #008000;">False</span>, <span style="color: #483d8b;">'no'</span>: <span style="color: #483d8b;">'yes'</span><span style="color: black;">&#125;</span>
<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'yes'</span>: <span style="color: #008000;">False</span>, <span style="color: #483d8b;">'no'</span>: <span style="color: #483d8b;">'yes'</span><span style="color: black;">&#125;</span>
<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'yes'</span>: <span style="color: #008000;">False</span>, <span style="color: #483d8b;">'no'</span>: <span style="color: #483d8b;">'yes'</span><span style="color: black;">&#125;</span>
<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'yes'</span>: <span style="color: #008000;">False</span>, <span style="color: #483d8b;">'no'</span>: <span style="color: #483d8b;">'yes'</span><span style="color: black;">&#125;</span>
<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'yes'</span>: <span style="color: #008000;">False</span>, <span style="color: #483d8b;">'no'</span>: <span style="color: #483d8b;">'yes'</span><span style="color: black;">&#125;</span>
<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'yes'</span>: <span style="color: #008000;">False</span>, <span style="color: #483d8b;">'no'</span>: <span style="color: #483d8b;">'yes'</span><span style="color: black;">&#125;</span>
<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'yes'</span>: <span style="color: #008000;">False</span>, <span style="color: #483d8b;">'no'</span>: <span style="color: #483d8b;">'yes'</span><span style="color: black;">&#125;</span>
<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'yes'</span>: <span style="color: #008000;">False</span>, <span style="color: #483d8b;">'no'</span>: <span style="color: #483d8b;">'yes'</span><span style="color: black;">&#125;</span>
<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'yes'</span>: <span style="color: #008000;">False</span>, <span style="color: #483d8b;">'no'</span>: <span style="color: #483d8b;">'yes'</span><span style="color: black;">&#125;</span>
<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'yes'</span>: <span style="color: #008000;">False</span>, <span style="color: #483d8b;">'no'</span>: <span style="color: #483d8b;">'yes'</span><span style="color: black;">&#125;</span></pre></td></tr></table></div>

<p>Awesome. The arguments the event is created with are passed directly into the listener for that, so as long as you have the right signature on the method, you should be golden.</p>
<p>Which leaves us with a basic question — if messages have to be pushed into the manager on a given channel, how do we build something which is an event generator? In other words — how do we make something which “listens” and then generates the matching events.</p>
<p>To know that — we look in the lib/ directory (which the examples make prodigious use of) and we’ll focus on io.py which listens on stdin:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code29'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40729"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code" id="p407code29"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> circuits <span style="color: #ff7700;font-weight:bold;">import</span> listener, Event, Component, Manager
<span style="color: #ff7700;font-weight:bold;">from</span> circuits.<span style="color: black;">lib</span>.<span style="color: black;">io</span> <span style="color: #ff7700;font-weight:bold;">import</span> Stdin
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> DogBot<span style="color: black;">&#40;</span>Stdin<span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> read<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> args, kwargs
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    manager = Manager<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    dog = DogBot<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    manager += dog
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            manager.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            dog.<span style="color: black;">poll</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">KeyboardInterrupt</span>:
            <span style="color: #ff7700;font-weight:bold;">break</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>All this does is create a new component which listens for the read event that Stdin generates and then prints off what we see coming in off the command line:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code30'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40730"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p407code30"><pre class="python" style="font-family:monospace;">thumper:circuits jesse$ python2.6 dog.<span style="color: black;">py</span> 
a line <span style="color: #ff7700;font-weight:bold;">is</span> one argument
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'a line is one argument<span style="color: #000099; font-weight: bold;">\n</span>'</span>,<span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span></pre></td></tr></table></div>

<p>That means the read event needs to parse the passed in line and then (re)issue and event for some other listener to manage. Let’s define some addition events:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code31'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40731"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code" id="p407code31"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Sit<span style="color: black;">&#40;</span>Event<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Sit event, no args &quot;&quot;&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Say<span style="color: black;">&#40;</span>Event<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Speak event
     args: what to say
    &quot;&quot;&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> DogBot<span style="color: black;">&#40;</span>Stdin<span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> read<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
        command = args<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> command:
            <span style="color: #ff7700;font-weight:bold;">return</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> command<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> == <span style="color: #483d8b;">'sit'</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">push</span><span style="color: black;">&#40;</span>Sit<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'sit'</span>, <span style="color: #008000;">self</span>.<span style="color: black;">channel</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> command<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> == <span style="color: #483d8b;">'say'</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">push</span><span style="color: black;">&#40;</span>Say<span style="color: black;">&#40;</span><span style="color: #483d8b;">' '</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>command<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>:<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'say'</span>, <span style="color: #008000;">self</span>.<span style="color: black;">channel</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> sit<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'i am now sitting'</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> say<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, words<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'&lt;dog&gt;%s&lt;/dog&gt;'</span> <span style="color: #66cc66;">%</span> words</pre></td></tr></table></div>

<p>Rudimentary — but you get the idea. For networking, you’d need to bind the socket and then read off/generate the events — this is largely covered by the sockets.py module in lib, as well as irc, webserver and smtp listeners.</p>
<p>All in all — it’s pretty simple to construct components, it could be made a bit easier with less metaprogramming and more, well, methods but a great deal more documentation could help too. I’m not too fond of too much metaprogramming — I tend to think it makes code rather unapproachable in general.</p>
<p>The (event/channel)/subscription model used here is nice as well — you can easily create your own little asynchronous network daemon or something as simple as what I did above very quickly (once you know what’s going on). It is obviously still evolving — James is putting a lot of work into it. If you’re looking for a compact little library, this would be good to check out.</p>
<p class="wp-flattr-button"></p>]]></content:encoded>
			<wfw:commentRss>http://jessenoller.com/2009/01/31/circuits-event-driven-components/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>A gentle overview of Kamaelia or “it’s axon, stupid”</title>
		<link>http://jessenoller.com/2009/01/29/a-gentle-overview-of-kamaelia-or-its-axon-stupid/</link>
		<comments>http://jessenoller.com/2009/01/29/a-gentle-overview-of-kamaelia-or-its-axon-stupid/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 14:29:34 +0000</pubDate>
		<dc:creator>jesse</dc:creator>
				<category><![CDATA[concurrency]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[pycon 2009]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://jessenoller.com/?p=401</guid>
		<description><![CDATA[Note:This is the first post in what I hope will be a series leading up to my concurrency/distributed systems talk at PyCon. I'm steadily working through experimenting with and learning the various frameworks/libraries in the python ecosystem.

I reserve the right (and probably will) to revise these entries based on feedback from people (mainly the ...]]></description>
			<content:encoded><![CDATA[<p><b>Note:</b>This is the first post in what I hope will be a series leading up to my concurrency/distributed systems talk at PyCon. I’m steadily working through experimenting with and learning the various frameworks/libraries in the python ecosystem.</p>
<p>I reserve the right (and probably will) to revise these entries based on feedback from people (mainly the author(s) of said tool(s)). I will also add additional bits and pieces as I learn and explore more. Code and examples will be checked into my pycon 2009 bitbucket site <a href="http://bitbucket.org/jnoller/pycon_2009/src/" target="_blank">here</a><b>/Note</b></p>
<p>For awhile now, I’ve been meaning to dig into <a href="http://www.kamaelia.org" target="_blank">Kamaelia</a> but was largely put off by what I tend to call the “twisted effect”. What this means is that when I go looking for libraries and small components, I go looking for a library — not a “solution”. I also worry about the “once you go in, you must follow this paradigm” effect. I’m not going to say that these feeling continue to be founded, or are completely rational — after all, I am digging into it, yes? It’s the thought that once you adopt the “one true way of doing things” you’re trapped in that solution/framework “forever” — ironically, I love Django for it’s “conceptual integrity” and full-stack approach. No, I don’t understand me either.</p>
<p><span id="more-401"></span></p>
<p>Also, as time has progressed, I have found that part of me yearns for a clean and simple to use “framework” (note the small “f”) that would help build out a large system without introducing a lot of complexity. Ideally, that framework would allow me to swap components in and out — think of web frameworks like django and turbogears — in this case, instead of using stock localized IPC, I might want to swap in a simple messaging protocol (Pyro, XMPP, etc).</p>
<p>It’s also a matter of marketing and approachability — things have improved on both websites mind you. Looking at Kamaelia’s website though, I don’t find it approachable, as it’s not immediately clear <b>what</b> the core idea is, or what the difference between Axon (the core) and Kamaelia (the project) is. For example, if I had one critique, I would say that Axon should become it’s own “project”/library in and of itself, and almost have it’s own website. It would be like ripping Twisted’s reactor out and making it a completely separate library.</p>
<p>Kamaelia, like <a href="http://twistedmatrix.com/trac/" target="_blank">Twisted</a>, is based on a “simple” core — in this case, it’s the Axon library which has some very simple goals and paradigms it seeks to fulfill. To quote the <a href="http://www.kamaelia.org/Docs/Axon/Axon.html" target="_blank">Axon</a> page:</p>
<blockquote><p>
Axon is a component concurrency framework. With it you can create software “components” that can run concurrently with each other. Components have “inboxes” and “outboxes” through with they communicate with other components.</p>
<p>A component may send a message to one of its outboxes. If a linkage has been created from that outbox to another component’s inbox; then that message will arrive in the inbox of the other component. In this way, components can send and receive data — allowing you to create systems by linking many components together.</p>
<p>Each component is a microprocess — rather like a thread of execution. A scheduler takes care of making sure all microprocesses (and therefore all components) get regularly executed. It also looks after putting microprocesses to sleep (when they ask to be) and waking them up (for example, when something arrives in one of their inboxes).
</p></blockquote>
<p>This by itself is the shining gem of the Kamaelia ecosystem — everything else is applications or additional utilities built on this simple core. This is where the website confusion comes in — where does “solutions built with axon (e.g. kamaelia)” end and Axon begin? The core design (of Axon) is very simple though: <i>build a component which communicates via message passing</i>.</p>
<p>Message passing is a relatively simple concept. Component A generates some work, and then sends it to Component (Not A). Messages are handled by the receiver and results can be passed (via a message) to someone else.</p>
<p>Very, very simple. You can add on little factoids about the fact that messages sent and received are handled in asynchronous fashion, messages can be sent locally — or across a wide network, etc — but largely those are component implementation details.</p>
<p>Which gets us back to Axon.</p>
<p>Since I’m interested in the core — and not video transcoders — I hit up the MiniAxon tutorial <a href="http://www.kamaelia.org/MiniAxon" target="_blank">here</a> and worked through it — even then, I don’t really think it did Axon complete justice. I then jumped into the “<a href="http://edit.kamaelia.org/cgi-bin/blog/blog.cgi?rm=viewpost&#038;nodeid=1113495151" target="_blank">How to write new components</a>” article by Michael.</p>
<p>The second tutorial, in my humble opinion, should be the first article users are directed to, while it has some polishing issues, I found it to really explain what the fruit was going on — and what Axon is. </p>
<p>Reading through both of these, you begin to realize that Axon is built on the core concept of Python generators and yielding control to a scheduler. For example:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p401code32'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40132"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p401code32"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> sender<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
   sock = <span style="color: #dc143c;">socket</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">socket</span>.<span style="color: black;">AF_INET</span>, <span style="color: #dc143c;">socket</span>.<span style="color: black;">SOCK_DGRAM</span>, <span style="color: #dc143c;">socket</span>.<span style="color: black;">IPPROTO_UDP</span><span style="color: black;">&#41;</span>
   sock.<span style="color: black;">bind</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>ANY,SENDERPORT<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
   sock.<span style="color: black;">setsockopt</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">socket</span>.<span style="color: black;">IPPROTO_IP</span>, <span style="color: #dc143c;">socket</span>.<span style="color: black;">IP_MULTICAST_TTL</span>, <span style="color: #ff4500;">255</span><span style="color: black;">&#41;</span>
   <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff4500;">1</span>:
      <span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0.5</span><span style="color: black;">&#41;</span>
      sock.<span style="color: black;">sendto</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Hello World&quot;</span>, <span style="color: black;">&#40;</span>MCAST_ADDR,MCAST_PORT<span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
      <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">1</span></pre></td></tr></table></div>

<p>If you’re familiar with python generators, you know that what this function does is send a message to a socket, and then hand control back to the main program. It will do so forever until the controller exits. </p>
<p>This paradigm is key to Axon: components send and receive messages via mailboxes (by far, one of the best descriptions/abstractions I’ve seen for this) — the components do the work sent/generated and then put it in the right outbox, and then yield control, courtesy of Enhanced Generators (see <a href="http://www.python.org/dev/peps/pep-0342/" target="_blank">PEP 342</a>)</p>
<p>Yes, coroutines/greenlets/tasklets — stop bothering me.</p>
<p>In the tutorial I linked above, Michael takes the very simple network script and ports it to Axon. Here’s my simple experiment that drops the networking code and cuts to the mailbox system. In this case, all I want to do is send and receive the lyrics to the meow mix commercial, forever:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p401code33'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40133"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
</pre></td><td class="code" id="p401code33"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> Axon
&nbsp;
LYRICS=<span style="color: #483d8b;">&quot;I want chicken I want liver Meow Mix Meow Mix Please Deliver.&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Producer<span style="color: black;">&#40;</span>Axon.<span style="color: black;">Component</span>.<span style="color: black;">component</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff4500;">1</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">send</span><span style="color: black;">&#40;</span>LYRICS, <span style="color: #483d8b;">&quot;outbox&quot;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">1</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Sender<span style="color: black;">&#40;</span>Axon.<span style="color: black;">Component</span>.<span style="color: black;">component</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.__super.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff4500;">1</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">dataReady</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;inbox&quot;</span><span style="color: black;">&#41;</span>:
                message = <span style="color: #008000;">self</span>.<span style="color: black;">recv</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: #008000;">self</span>.<span style="color: black;">send</span><span style="color: black;">&#40;</span>message, <span style="color: #483d8b;">&quot;outbox&quot;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">1</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Receiver<span style="color: black;">&#40;</span>Axon.<span style="color: black;">Component</span>.<span style="color: black;">component</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.__super.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff4500;">1</span>:
            message = <span style="color: #008000;">self</span>.<span style="color: black;">recv</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">print</span> message
            <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">1</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> tests<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>: 
    <span style="color: #ff7700;font-weight:bold;">from</span> Axon.<span style="color: black;">Scheduler</span> <span style="color: #ff7700;font-weight:bold;">import</span> scheduler 
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">class</span> testComponent<span style="color: black;">&#40;</span>Axon.<span style="color: black;">Component</span>.<span style="color: black;">component</span><span style="color: black;">&#41;</span>: 
        <span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>: 
            producer= Producer<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            sender = Sender<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            receiver = Receiver<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> 
&nbsp;
            <span style="color: #008000;">self</span>.<span style="color: black;">link</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>producer, <span style="color: #483d8b;">&quot;outbox&quot;</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span>sender, <span style="color: #483d8b;">&quot;inbox&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">link</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>sender, <span style="color: #483d8b;">&quot;outbox&quot;</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span>receiver, <span style="color: #483d8b;">&quot;inbox&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">addChildren</span><span style="color: black;">&#40;</span>producer, sender, receiver<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">yield</span> Axon.<span style="color: black;">Ipc</span>.<span style="color: black;">newComponent</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">children</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> 
            <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff4500;">1</span>: 
                <span style="color: #008000;">self</span>.<span style="color: black;">pause</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> 
                <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">1</span>
&nbsp;
    harness = testComponent<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> 
    harness.<span style="color: black;">activate</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> 
    scheduler.<span style="color: black;">run</span>.<span style="color: black;">runThreads</span><span style="color: black;">&#40;</span>slowmo=<span style="color: #ff4500;">0.1</span><span style="color: black;">&#41;</span> 
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__==<span style="color: #483d8b;">&quot;__main__&quot;</span>: 
    tests<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Now, this uses knowledge from both tutorials, and the <a href="http://www.kamaelia.org/Docs/Axon/Axon.Component.html" target="_blank">Axon.Component</a> documentation. The component documentation can be hard to find, and not so easy to navigate too.</p>
<p>If we break one of the classes/components down and look at the “magic” provided by the component subclass, it gets clearer — in this case, I’ve “added” back in the methods from the component superclass, minus the doc strings:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p401code34'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40134"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
</pre></td><td class="code" id="p401code34"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Sender<span style="color: black;">&#40;</span>Axon.<span style="color: black;">Component</span>.<span style="color: black;">component</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># First, subclass the Axon Component class, this provides us with the</span>
    <span style="color: #808080; font-style: italic;"># basic inbox/outbox static members that look like this:</span>
    Inboxes = <span style="color: black;">&#123;</span> <span style="color: #483d8b;">&quot;inbox&quot;</span>   : <span style="color: #483d8b;">&quot;Send the FOO objects to here&quot;</span>,
                <span style="color: #483d8b;">&quot;control&quot;</span> : <span style="color: #483d8b;">&quot;NOT USED&quot;</span>,
              <span style="color: black;">&#125;</span>
    Outboxes = <span style="color: black;">&#123;</span> <span style="color: #483d8b;">&quot;outbox&quot;</span> : <span style="color: #483d8b;">&quot;Emits BAA objects from here&quot;</span>,
                 <span style="color: #483d8b;">&quot;signal&quot;</span> : <span style="color: #483d8b;">&quot;NOT USED&quot;</span>,
               <span style="color: black;">&#125;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.__super.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
   <span style="color: #ff7700;font-weight:bold;">def</span> recv<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, boxname=<span style="color: #483d8b;">&quot;inbox&quot;</span><span style="color: black;">&#41;</span>:
      <span style="color: #808080; font-style: italic;"># returns the first piece of data in the requested inbox.</span>
&nbsp;
      <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">inboxes</span><span style="color: black;">&#91;</span>boxname<span style="color: black;">&#93;</span>.<span style="color: black;">pop</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
&nbsp;
   <span style="color: #ff7700;font-weight:bold;">def</span> send<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, message, boxname=<span style="color: #483d8b;">&quot;outbox&quot;</span><span style="color: black;">&#41;</span>:
      <span style="color: #808080; font-style: italic;"># appends message to the requested outbox.</span>
&nbsp;
      <span style="color: #008000;">self</span>.<span style="color: black;">outboxes</span><span style="color: black;">&#91;</span>boxname<span style="color: black;">&#93;</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>message<span style="color: black;">&#41;</span>
&nbsp;
   <span style="color: #ff7700;font-weight:bold;">def</span> dataReady<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>,boxname=<span style="color: #483d8b;">&quot;inbox&quot;</span><span style="color: black;">&#41;</span>:
      <span style="color: #808080; font-style: italic;"># Returns true if data is available in the requested inbox.</span>
&nbsp;
      <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">inboxes</span><span style="color: black;">&#91;</span>boxname<span style="color: black;">&#93;</span>.<span style="color: black;">local_len</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff4500;">1</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">dataReady</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;inbox&quot;</span><span style="color: black;">&#41;</span>:
                message = <span style="color: #008000;">self</span>.<span style="color: black;">recv</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: #008000;">self</span>.<span style="color: black;">send</span><span style="color: black;">&#40;</span>message, <span style="color: #483d8b;">&quot;outbox&quot;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">1</span></pre></td></tr></table></div>

<p>I think this makes it abundantly clear what’s happening with the method calls on this class. Now, there’s the additional magic of the new tests method — in which we defined a new component, which was actually a component containing and linking the pipelines (connections between mailboxes) between the other components.</p>
<p>Now, the <a href="http://www.kamaelia.org/Docs/Axon/Axon.Ipc.html" target="_blank">Axon.Ipc.*</a> docs aren’t the most helpful — in our case, we called:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p401code35'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40135"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p401code35"><pre class="python" style="font-family:monospace;">    <span style="color: #008000;">self</span>.<span style="color: black;">link</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>producer, <span style="color: #483d8b;">&quot;outbox&quot;</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span>sender, <span style="color: #483d8b;">&quot;inbox&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">link</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>sender, <span style="color: #483d8b;">&quot;outbox&quot;</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span>receiver, <span style="color: #483d8b;">&quot;inbox&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">addChildren</span><span style="color: black;">&#40;</span>producer, sender, receiver<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">yield</span> Axon.<span style="color: black;">Ipc</span>.<span style="color: black;">newComponent</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">children</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Within the main method of a component. We need to look at the link method on the superclass:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p401code36'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40136"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code" id="p401code36"><pre class="python" style="font-family:monospace;">   <span style="color: #ff7700;font-weight:bold;">def</span> link<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, source,sink,<span style="color: #66cc66;">*</span>optionalargs, <span style="color: #66cc66;">**</span>kwoptionalargs<span style="color: black;">&#41;</span>:
      <span style="color: #483d8b;">&quot;&quot;&quot;<span style="color: #000099; font-weight: bold;">\</span>
      Creates a linkage from one inbox/outbox to another.
&nbsp;
      -- source  - a tuple (component, boxname) of where the link should start  
                   from
      -- sink    - a tuple (component, boxname) of where the link should go to
&nbsp;
      Other optional arguments:
&nbsp;
      - passthrough=0  - (the default) link goes from an outbox to an inbox
      - passthrough=1  - the link goes from an inbox to another inbox
      - passthrough=2  - the link goes from an outbox to another outbox
&nbsp;
      See Axon.Postoffice.postoffice.link() for more information.
      &quot;&quot;&quot;</span>
      <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">postoffice</span>.<span style="color: black;">link</span><span style="color: black;">&#40;</span>source, sink, <span style="color: #66cc66;">*</span>optionalargs, \
                                  <span style="color: #66cc66;">**</span>kwoptionalargs<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>This leads us to the <a href="http://www.kamaelia.org/Docs/Axon/Axon.Postoffice.html" target="_blank">Postoffice</a> class which actually constructs and tracks the links between the components. Here there be dragons.</p>
<p>So, addChildren just registers all of the passed in component instances as children of the newly constructed components (components, all the way down), and then we yield ourself — if you added a ‘print harness’ you’d see:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p401code37'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40137"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p401code37"><pre class="python" style="font-family:monospace;">Component <span style="color: #dc143c;">__main__</span>.<span style="color: black;">testComponent_5</span> <span style="color: black;">&#91;</span> inboxes : <span style="color: black;">&#123;</span><span style="color: #483d8b;">'control'</span>: <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>, <span style="color: #483d8b;">'inbox'</span>: <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span>
outboxes : <span style="color: black;">&#123;</span><span style="color: #483d8b;">'outbox'</span>: <span style="color: #66cc66;">&lt;&gt;</span>, <span style="color: #483d8b;">'signal'</span>: <span style="color: #66cc66;">&lt;&gt;</span><span style="color: black;">&#125;</span></pre></td></tr></table></div>

<p>This means we’re getting a component back, and then calling .activate on it — .activate is actually a method on the Axon.Microprocess.microprocess class. In our case, it (it being activate) is simply registering our test component (which contains all of the children) with the default scheduler.</p>
<p>At which point, we call scheduler.run.runThreads <b>jazz hands</b>.</p>
<p>I dived into some of the internals here, I ended up having to supplement the documentation with pouring through the code — but I personally think it helps clear things up to remove some of the magic and show what is actually occurring. Most of the time, it seems you simply <b>won’t care</b> — and instead you’d just make and register your happy component and be on your way.</p>
<p>To somewhat summarize what we’re lookin at — a component that subclasses the default Axon.Component uses generators to yield control back and forth, passing messages/work to and from each other via the very clever mailbox/postoffice metaphor.</p>
<p>Now, the interesting thing, once you start digging through things is that your component isn’t a really a Thread — if you wanted to make sure each component was in its own thread, you might instead subclass <a href="http://www.kamaelia.org/Docs/Axon/Axon.ThreadedComponent.html" target="_blank">Axon.ThreadedComponent</a>.</p>
<p>Subclassing this new class looks mighty close to what we did before but instead Uses threads and queues for the message passing. Instead of yield, you just run, and the recv/send methods are backed by queues. Ahh, delicious non judgmental queues.</p>
<p>In any case, Kamaelia — via Axon, is a very nice abstraction on top of a very simple concept — message passing for concurrency. The fact that you can quickly build up a series of components which pass work back and forth via some sort of communications system and not have to worry about the underlying nuances/organization is quite nice.</p>
<p>One of the things Michael Sparks and I have talked about is adding some level of multiprocessing support for Kamaelia — this would actually be insanely easy if I used Axon.ThreadedComponent as the template, but instead used multiprocessing.Queue and multiprocessing.Process as the back end.</p>
<p>Kamaelia itself, is really a series of example components/applications which build on a core (Axon), but you do not need Kamaelia to use Axon effectively. In fact, just on a whim, I decided to whip up a dirty http load tool in Kamaelia. You can see it <a href="http://bitbucket.org/jnoller/pycon_2009/src/tip/kamaelia/http_pain.py" target="_blank">here</a>.</p>
<p>It’s really a hack job — all I did was build off the meowmix demo, swapped in the threaded component and hacked it around a bit. One thing I’d like to know is how to pass in a dynamic number of clients so that I could create the outboxes dynamically in the producer — there wasn’t anything clear in the docs to allow me to do this. Also, it doesn’t shut down.</p>
<p>I’m going to keep hacking around with Axon, it’s pretty neat. Interesting things I’d like to poke around in:</p>
<ul>
<li> Replace the underlying IPC mechanism with multiprocessing.Pipe/Pyro/<a href="http://semanchuk.com/philip/posix_ipc/" target="_blank">posix_ipc</a>
<li> hack on the mp version of the component backend
<li> get a multi-system script running and communicating workloads across the LAN
</ul>
<p class="wp-flattr-button"></p>]]></content:encoded>
			<wfw:commentRss>http://jessenoller.com/2009/01/29/a-gentle-overview-of-kamaelia-or-its-axon-stupid/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Object Caching 2089/2231 objects using disk: basic

Served from: jessenoller.com @ 2012-02-07 03:00:51 -->
