<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3233128</id><updated>2012-05-08T14:58:11.211-07:00</updated><category term='Mac OS X'/><category term='impulsecurrents'/><category term='peer-to-peer'/><category term='magnifyingtransmitter'/><category term='MacPython'/><category term='wardenclyffe'/><category term='Nevow'/><category term='single-page-apps'/><category term='tesla'/><category term='onewire'/><title type='text'>pyx</title><subtitle type='html'>|piks| n. a box at the Royal Mint in which specimen gold and silver coins are deposited to be tested annually at the trial of the pyx.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default?start-index=26&amp;max-results=25'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>87</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3233128.post-7085885375785606081</id><published>2012-03-05T18:55:00.001-08:00</published><updated>2012-03-05T18:55:22.899-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='peer-to-peer'/><category scheme='http://www.blogger.com/atom/ns#' term='single-page-apps'/><title type='text'>Where are the Peer-to-Peer web apps?</title><content type='html'>&lt;p&gt;Perhaps the reason we have not seen single-page html applications that connect directly to peers without an intermediate server is that browsers cannot easily listen on a local port. They can open outgoing connections all day long, but WebRTC may be the first web standard that allows the browser to listen on a port. If there are others, please let me know.&lt;/p&gt;
&lt;p&gt;Of course, the WebRTC spec looks overly complicated for the incredibly simple thing I want to do. I just want the browser to be able to listen on a port like any other process on the machine can. Sure, there are security implications, but these exist for everything the browser exposes to web applications, and there's an entire class of Peer-to-Peer web apps that simply cannot easily be written using current web technologies.&lt;/p&gt;
&lt;p&gt;There are many examples of a Peer-to-Peer experience being delivered to users using a client-server architecture. ChatRoulette, Omegle, and even more recently, products like Google Hangouts. These applications must be implemented by using servers in the middle to connect the peers, making scaling them much harder than it would be if browsers could just listen.&lt;/p&gt;
&lt;p&gt;There is an opportunity to explore a generic Client-Agent-Peer architecture, where Clients (Browsers) talk to an Agent server using HTTP to configure the state of the Agent, which would then be contacted by the Peer on behalf of the Client when the Browser is not online. When the Browser is online, the Agent can refer the Peer directly to the Client. When the Browser is offline, the Agent can handle the request itself using a cached copy of the material the Browser was sharing, or it can just decline to fulfill the request.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://wiki.secondlife.com/wiki/Reverse_HTTP" title="Reverse HTTP"&gt;Reverse HTTP&lt;/a&gt; was my attempt to push out the simplest thing that could possibly work to get browsers to talk to each other. It didn't really go anywhere in terms of being implemented in actual browsers. Coincidentally, someone else had the same idea around the same time, and implemented Reverse HTTP in terms of actual &lt;a href="http://reversehttp.net/"&gt;HTTP Requests encoded in Responses&lt;/a&gt;, and vice versa. This makes it possible to write a pure javascript client rather than needing the browser to support the Upgrade protocol itself.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Really, though, it would be very nice if all of the hacks and tricks and workarounds weren't necessary, and I could just listen on a port with javascript. I'll keep dreaming.&lt;/p&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-7085885375785606081?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/7085885375785606081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=7085885375785606081' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/7085885375785606081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/7085885375785606081'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2012/03/where-are-peer-to-peer-web-apps.html' title='Where are the Peer-to-Peer web apps?'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-2161797760599783418</id><published>2011-08-11T14:30:00.000-07:00</published><updated>2011-08-11T14:30:01.024-07:00</updated><title type='text'></title><content type='html'>&lt;b&gt;Coverage and Profile Information Gathered from -D&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The disassembly information provided by SpiderMonkey's -D switch is much richer than the plain coverage data I gathered with my trace hook. However, the disassembly is printed straight to stdout which makes it more difficult to separate from test output and harder to parse. So, I wrote a small patch which makes -D take the filename to write the disassembly to instead of stdout.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://pastebin.mozilla.org/1296772"&gt;http://pastebin.mozilla.org/1296772&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I need to get my situation with the mozilla-central repository figured out so I can create a branch and commit. In the meantime, there's the small patch.&lt;br /&gt;
&lt;br /&gt;
Then, I rewrote my coverage_parser.py script in dom.js to parse the -D output and was able to generate nice coverage files, including displaying the number of total bytecodes executed on each line, and nice profile files, sorted from the lines which executed the most bytecodes down to those that executed the least.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.flickr.com/photos/fzzzy/6030567525/" title="Screen Shot 2011-08-10 at 6.47.44 PM by fzZzy, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6189/6030567525_2d2a1e146f.jpg" width="500" height="313" alt="Screen Shot 2011-08-10 at 6.47.44 PM"&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.flickr.com/photos/fzzzy/6031475964/" title="Screen Shot 2011-08-10 at 9.30.22 PM by fzZzy, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6133/6031475964_e8a293b2ed.jpg" width="500" height="313" alt="Screen Shot 2011-08-10 at 9.30.22 PM"&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
With the test suites we scraped together from various places, we have almost 50% coverage of dom.js right off the bat.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-2161797760599783418?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/2161797760599783418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=2161797760599783418' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/2161797760599783418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/2161797760599783418'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2011/08/coverage-and-profile-information.html' title=''/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm7.static.flickr.com/6189/6030567525_2d2a1e146f_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-8952286275698631296</id><published>2011-08-08T14:12:00.000-07:00</published><updated>2011-08-08T14:12:52.540-07:00</updated><title type='text'></title><content type='html'>&lt;b&gt;Dumping Bytecode with SpiderMonkey&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
While trying to implement my code coverage tool, SpiderMonkey's -D flag was brought to my attention.&lt;br /&gt;
&lt;br /&gt;
You need to have a debug build of SpiderMonkey. You can find instructions on how to get the source and build &lt;a href="https://developer.mozilla.org/En/SpiderMonkey/Build_Documentation"&gt;here.&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
For the given input file foo.js:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;var a = 1 + 1;&lt;br /&gt;
var b = 2 + 2;&lt;br /&gt;
var c = a + b;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Running with the command-line switch -D gives:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;$ js -D foo.js&lt;br /&gt;
--- PC COUNTS foo.js:1 ---&lt;br /&gt;
loc   counts           x line  op&lt;br /&gt;
----- ----------------   ----  --&lt;br /&gt;
main:&lt;br /&gt;
00000:1/0/0            x    1  bindgname "a"&lt;br /&gt;
00003:1/0/0            x    1  int8 2&lt;br /&gt;
00005:1/0/0            x    1  setgname "a"&lt;br /&gt;
00008:0/0/0            x    1  pop&lt;br /&gt;
00009:1/0/0            x    2  bindgname "b"&lt;br /&gt;
00012:1/0/0            x    2  int8 4&lt;br /&gt;
00014:1/0/0            x    2  setgname "b"&lt;br /&gt;
00017:0/0/0            x    2  pop&lt;br /&gt;
00018:1/0/0            x    3  bindgname "c"&lt;br /&gt;
00021:1/0/0            x    3  getglobal "a"&lt;br /&gt;
00024:1/0/0            x    3  getglobal "b"&lt;br /&gt;
00027:1/0/0            x    3  add&lt;br /&gt;
00028:1/0/0            x    3  setgname "c"&lt;br /&gt;
00031:0/0/0            x    3  pop&lt;br /&gt;
00032:1/0/0            x    3  stop&lt;br /&gt;
&lt;br /&gt;
--- END PC COUNTS foo.js:1 ---&lt;/blockquote&gt;&lt;br /&gt;
Useful and interesting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-8952286275698631296?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/8952286275698631296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=8952286275698631296' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/8952286275698631296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/8952286275698631296'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2011/08/dumping-bytecode-with-spidermonkey.html' title=''/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-4374886246991445247</id><published>2011-08-04T19:24:00.000-07:00</published><updated>2011-08-04T19:27:17.549-07:00</updated><title type='text'></title><content type='html'>Code Coverage Reporting in JavaScript&lt;br /&gt;
&lt;br /&gt;
Now that I am working on dom.js, I need to learn an entirely new environment and all the tools that go with it. JavaScript is also fundamentally different from other scripting languages because usually the environment it is executing in is the browser rather than the command line. However, dom.js is designed to be used in environments where a native DOM does not already exist, such as in Node.js or in SpiderMonkey. Since it's such a unique project many of the existing tools don't really apply.&lt;br /&gt;
&lt;br /&gt;
I went looking for code coverage tools that we could use to determine how much of the dom.js code was being exercised by the test suites we have in place right now. Several coverage tools exist for JavaScript, as discussed on StackOverflow here: &lt;a href="http://stackoverflow.com/questions/53249/are-there-any-good-javascript-code-coverage-tools"&gt;http://stackoverflow.com/questions/53249/are-there-any-good-javascript-code-coverage-tools&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
For example, the ffhrtimer project (&lt;a href="http://hrtimer.mozdev.org/"&gt;http://hrtimer.mozdev.org/&lt;/a&gt;) is a nice firefox extension that provides high resolution timers and UI to display JavaScript code coverage, but it can't easily be integrated into the SpiderMonkey command line js and only runs on FireFox 3.0.&lt;br /&gt;
&lt;br /&gt;
JSCoverage is interesting (&lt;a href="http://siliconforks.com/jscoverage/"&gt;http://siliconforks.com/jscoverage/&lt;/a&gt;) but it requires source-level translations on the javascript in order to record coverage information. It makes this easy by providing a web server that automatically translates javascript that it serves as well as a proxy that translates any javascript that passes through it, but this does not really fit into our model where we are testing from the command line.&lt;br /&gt;
&lt;br /&gt;
js-test-driver (&lt;a href="http://code.google.com/p/js-test-driver/wiki/CodeCoverage"&gt;http://code.google.com/p/js-test-driver/wiki/CodeCoverage&lt;/a&gt;) looks good but it also is designed to work in a browser environment.&lt;br /&gt;
&lt;br /&gt;
Finally, JSChiliCat (&lt;a href="http://jschilicat.sourceforge.net/"&gt;http://jschilicat.sourceforge.net/&lt;/a&gt;) is getting closer because it allows running of tests without a browser being involved, but it also requires Rhino for running the tests. dom.js needs the HEAD version of SpiderMonkey since it uses extensions to JavaScript which are not widely implemented, Proxies and WeakMaps.&lt;br /&gt;
&lt;br /&gt;
So, I looked at the way ffhrtimer gathers coverage data and modified SpiderMonkey to have a --coverage switch which installs a simple hook that prints out the current javascript filename and line number for every line of execution.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;JSTrapStatus&lt;br /&gt;
CoverageHook(JSContext *cx, JSScript *script,&lt;br /&gt;
jsbytecode *pc, jsval *rval, void *closure)&lt;br /&gt;
{&lt;br /&gt;
const char* filename = JS_GetScriptFilename(cx, script);&lt;br /&gt;
uintN lineno = JS_PCToLineNumber(cx, script, pc);&lt;br /&gt;
&lt;br /&gt;
printf("CoverageHook %s %d\n", filename, lineno);&lt;br /&gt;
&lt;br /&gt;
return JSTRAP_CONTINUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Here's how this hook is installed as a callback:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;JS_SetInterrupt(cx-&gt;runtime, &amp;CoverageHook, NULL);&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Now, the question is how best to store the data for use by an analysis tool. ffhrtimer used an in-memory data structure to keep track of which lines in which files had been visited, but for simplicity I think I am going to use the code above, writing the files and line numbers to a file 'coverage.out' for post-processing with a python script.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-4374886246991445247?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/4374886246991445247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=4374886246991445247' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/4374886246991445247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/4374886246991445247'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2011/08/code-coverage-reporting-in-javascript.html' title=''/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-661191195520472261</id><published>2011-08-02T12:09:00.000-07:00</published><updated>2011-08-02T12:09:24.135-07:00</updated><title type='text'></title><content type='html'>I started work at Mozilla yesterday. It has been quite a whirlwind. I'm sitting next to Brendan Eich and working with David Flanagan. David's &lt;a target="_blank"  href="http://www.amazon.com/JavaScript-Definitive-Guide-Activate-Guides/dp/0596805527?ie=UTF8&amp;tag=widgetsamazon-20&amp;link_code=btl&amp;camp=213689&amp;creative=392969"&gt;JavaScript: The Definitive Guide&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=widgetsamazon-20&amp;l=btl&amp;camp=213689&amp;creative=392969&amp;o=1&amp;a=0596805527" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important; padding: 0px !important" /&gt; was the reference I turned to when I seriously started with web programming in 2000, and when Brendan Eich wrote JavaScript I was working on server-side scripts hosted in LambdaMOO and had no idea what I wanted to do with my career. Life is strange. If I could go back in time and tell my 1995 self where I am now I don't think I would believe myself.&lt;br /&gt;
&lt;br /&gt;
I'm having a lot of fun learning more about the history of JavaScript and the projects we are working on. After being so deeply embedded in the Python world for so long, it feels refreshing to venture into completely alien terrain. Some things are familiar and some things are incredibly strange. It feels very natural overall; I think if something like WebSockets had existed in 2000 I never would have discovered Python and would have stuck with JavaScript and the LambdaMOO programming language. Python was class oriented; JavaScript was prototype oriented like LambdaMOO. I needed some intermediate glue language to handle JavaScript's inability to use plain old socket objects though, and thus my love affair with Python was born.&lt;br /&gt;
&lt;br /&gt;
The first project I am helping with is &lt;a href="https://github.com/andreasgal/dom.js"&gt;dom.js&lt;/a&gt;, a project whose aim is to implement the common browser DOM APIs in pure JavaScript. This project will be useful for a server-side implementation of the DOM for use in node.js and will also be useful as a DOM implementation for &lt;a href="https://github.com/mozilla/narcissus/"&gt;Narcissus&lt;/a&gt; which is just straight up JavaScript written in JavaScript.&lt;br /&gt;
&lt;br /&gt;
Woah, man. Meta. I love it.&lt;br /&gt;
&lt;br /&gt;
Finally there is &lt;a href="http://mozillalabs.com/zaphod/"&gt;Zaphod&lt;/a&gt;, which is a FireFox extension which installs Narcissus as the default JavaScript interpreter, useful for rapid prototyping of changes to JavaScript itself.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-661191195520472261?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/661191195520472261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=661191195520472261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/661191195520472261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/661191195520472261'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2011/08/i-started-work-at-mozilla-yesterday.html' title=''/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-9029381460824781109</id><published>2010-11-16T09:08:00.000-08:00</published><updated>2010-11-16T09:08:32.426-08:00</updated><title type='text'></title><content type='html'>&lt;h1&gt;Simplified one-wire transmission system&lt;/h1&gt;&lt;br /&gt;
&lt;img src="http://img696.imageshack.us/img696/4492/magnifyingtransmitteron.png"&gt;&lt;br /&gt;
&lt;br /&gt;
If the secondary does not have distributed capacitance which cancels the coil's self induction, then an appropriately sized capacitor should be added between the coil and ground.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-9029381460824781109?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/9029381460824781109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=9029381460824781109' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/9029381460824781109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/9029381460824781109'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2010/11/simplified-one-wire-transmission-system.html' title=''/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-4524184128688216280</id><published>2010-11-16T08:24:00.000-08:00</published><updated>2010-11-16T08:35:18.898-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tesla'/><category scheme='http://www.blogger.com/atom/ns#' term='impulsecurrents'/><category scheme='http://www.blogger.com/atom/ns#' term='magnifyingtransmitter'/><category scheme='http://www.blogger.com/atom/ns#' term='onewire'/><category scheme='http://www.blogger.com/atom/ns#' term='wardenclyffe'/><title type='text'></title><content type='html'>&lt;h1&gt;Magnifying transmitter replication&lt;/h1&gt;&lt;br /&gt;
&lt;b&gt;Key tuning factors&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Coil length must match one quarter the wavelength of the impulse frequency.&lt;br /&gt;
&lt;br /&gt;
Coil capacitance, including a capacitor added to coil, must cancel self-induction of the coil.&lt;br /&gt;
&lt;br /&gt;
Impulse rise and fall slopes must be as sharp as possible, possibly in the nanosecond range.&lt;br /&gt;
&lt;br /&gt;
Impulse duration must be as short as possible. The duty cycle of the wave should be as close to 0 as possible.&lt;br /&gt;
&lt;br /&gt;
The center tap on a bifilar pancake coil will be the point at which the output voltage is highest. The terminal goes here. (? -- is this true? Take measurements)&lt;br /&gt;
&lt;br /&gt;
How to calculate the capacity of the terminal? Terminal construction? Terminal should possibly be glass, although could also be metal&lt;br /&gt;
&lt;br /&gt;
How is the size and positioning of the extra coil calculated?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;One wire electrical transmission driving loads&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Step-down coils, wound in the opposite direction but otherwise exactly the same as the transmitter, can be attached to the one-wire transmission system to drive loads.&lt;br /&gt;
&lt;br /&gt;
The AV plug and a smoothing capacitor is added to power a load.&lt;br /&gt;
&lt;br /&gt;
As many receivers as desired may be added to drive loads.&lt;br /&gt;
&lt;br /&gt;
The wardenclyffe tower magnifying transmitter used the earth as the one wire.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-4524184128688216280?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/4524184128688216280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=4524184128688216280' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/4524184128688216280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/4524184128688216280'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2010/11/p.html' title=''/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-499434338938682044</id><published>2009-01-15T06:11:00.000-08:00</published><updated>2009-10-22T03:58:45.312-07:00</updated><title type='text'>Spawning 0.8.8 released</title><content type='html'>&lt;p&gt;Another minor Spawning release cleans up some log messages, the way PYTHONPATH and the location of python are determined, and adds some convenient command-line options for controlling the operation of the server. Here are the release notes:&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;&lt;li&gt;Added --access-log-file command line option to allow writing access logs to someplace other than stdout. Useful for redirecting to /dev/null for speed&lt;/li&gt;&lt;br/&gt;&lt;li&gt;Correctly extract the child's exit code and clean up the logging of child exit events.&lt;/li&gt;&lt;br/&gt;&lt;li&gt;Add coverage gathering using figleaf if the --coverage command line option is given. When gathering coverage, the figleaf report can be downloaded from the /_coverage url.&lt;/li&gt;&lt;br/&gt;&lt;li&gt;Add a --max-memory option to limit the total amount of memory spawning will use. If this is exceeded a SIGHUP will be sent to the controller causing the children to restart.&lt;/li&gt;&lt;br/&gt;&lt;li&gt;Add a --max-age option to limit the total amount of time a spawning child is allowed to run. After the time limit is exceeded a SIGHUP will be sent to the controller to cause the children to restart.&lt;/li&gt;&lt;br/&gt;&lt;li&gt;Instead of just passing the PYTHONPATH environment variable through to the children, construct the PYTHONPATH from the contents of sys.path.&lt;/li&gt;&lt;br/&gt;&lt;li&gt;Instead of just trying to run 'spawn' with /usr/bin/env when restarting, just run sys.executable -m spawning.spawning_controller, making it more likely that the controller will run correctly when restarting.&lt;/li&gt;&lt;br/&gt;&lt;li&gt;Add a --verbose option and change the default startup procedure to not log the detailed dictionary of configuration information.&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-499434338938682044?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/499434338938682044/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=499434338938682044' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/499434338938682044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/499434338938682044'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2009/01/spawning-088-released.html' title='Spawning 0.8.8 released'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-4267158538416115923</id><published>2009-01-14T06:57:00.000-08:00</published><updated>2009-10-22T03:58:45.332-07:00</updated><title type='text'>Python binding for Mongrel's http11 parser</title><content type='html'>&lt;p&gt;Last weekend I wrote a Python binding for Mongrel's http11 parser. I will probably integrate this into eventlet.wsgi and Spawning at some point, but it's not really that much faster than eventlet.wsgi's existing pure python http parser, so I'm not in a hurry.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;I decided to release &lt;a href="http://github.com/fzzzy/pyhttp11/tree/master"&gt;the code&lt;/a&gt; on github in case anybody else is interested in playing around with it in the meantime. This is the first time I've used git to commit and push. So far my impression of git compared to darcs and hg is very good. git seems easy enough to use and is very fast. There's not a compelling reason to use it over hg except for the fact that pretty much everybody else in the world seems to be leaning towards git.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-4267158538416115923?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/4267158538416115923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=4267158538416115923' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/4267158538416115923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/4267158538416115923'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2009/01/python-binding-for-mongrel-http11.html' title='Python binding for Mongrel&amp;#39;s http11 parser'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-843980900389629645</id><published>2008-12-19T13:40:00.000-08:00</published><updated>2009-10-22T03:58:45.343-07:00</updated><title type='text'>Evolution of Codependency in Antagonistic Relationships</title><content type='html'>&lt;p&gt;I'm reading &lt;a href="http://www.amazon.com/gp/product/0201483408?ie=UTF8&amp;tag=pyx-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0201483408"&gt;Out of Control: The New Biology of Machines, Social Systems, &amp; the Economic World&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=pyx-20&amp;l=as2&amp;o=1&amp;a=0201483408" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;, a most excellent book about complexity. This quote caught my eye:&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;blockquote&gt;In defending itself so thoroughly against the monarch, the milkweed became inseparable from the butterfly. And vice versa. Any long-term antagonistic relationship seemed to harbor this kind of codependency. (p 74)&lt;/blockquote&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;This made me realize something about the nature of governments and war: Governments evolved to protect resources and people from the threat of outside invasion. An organizing structure was required to create and maintain a fighting force capable of resisting invasion from neighbors. However, it's now obvious that governments are in a codependent relationship with war: If there were no more war, then there would be no need for a government's ability to organize a fighting force. Therefore it's in a government's best interest to ensure that &lt;em&gt;war never ceases.&lt;/em&gt;&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;However, just like any other codependent relationship, a lot of denial takes place. I doubt most politicians would come out and say that a prime function of government is to create war. Actions speak louder than words, though, and it's clear that in the thousands of years of human civilization there have been plenty of wars.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-843980900389629645?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/843980900389629645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=843980900389629645' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/843980900389629645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/843980900389629645'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2008/12/evolution-of-codependency-in.html' title='Evolution of Codependency in Antagonistic Relationships'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-4449161875536716234</id><published>2008-12-19T13:14:00.000-08:00</published><updated>2009-10-22T03:58:45.352-07:00</updated><title type='text'>lxml + eventlet mashup</title><content type='html'>&lt;p&gt;Since Ian was kind enough to &lt;a href="http://blog.ianbicking.org/2008/12/10/lxml-an-underappreciated-web-scraping-library/"&gt;give me instructions&lt;/a&gt; that gave me a working lxml (I had never been able to compile it before), I thought I'd write a quick scraper by mashing lxml together with eventlet.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;The result is a thing of beauty:&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;from os import path&lt;br/&gt;import sys&lt;br/&gt;&lt;br/&gt;from eventlet import coros&lt;br/&gt;from eventlet import httpc&lt;br/&gt;from eventlet import util&lt;br/&gt;&lt;br/&gt;from lxml import html&lt;br/&gt;&lt;br/&gt;## Make httpc work -- I'll make it work without this soon&lt;br/&gt;util.wrap_socket_with_coroutine_socket()&lt;br/&gt;&lt;br/&gt;def get(linknum, url):&lt;br/&gt;print "[%s] downloading %s" % (linknum, url)&lt;br/&gt;file(path.basename(url), 'wb').write(httpc.get(url))&lt;br/&gt;&lt;br/&gt;def scrape(url):&lt;br/&gt;root = html.parse(url).getroot()&lt;br/&gt;pool = coros.CoroutinePool(max_size=8)&lt;br/&gt;linknum = 0&lt;br/&gt;for link in root.cssselect('a'):&lt;br/&gt;url = link.get('href', '')&lt;br/&gt;if url.endswith('.mp3'):&lt;br/&gt;linknum += 1&lt;br/&gt;pool.execute(get, linknum, url)&lt;br/&gt;pool.wait_all()&lt;br/&gt;&lt;br/&gt;if __name__ == '__main__':&lt;br/&gt;if len(sys.argv) == 2:&lt;br/&gt;scrape(sys.argv[1])&lt;br/&gt;else:&lt;br/&gt;print "usage: %s url" % (sys.argv[0], )&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;This script manages to max out my bandwidth -- 800KB/sec at home and 2.5MB/sec at work -- without breaking a sweat. It oscillates between about 10% and 20% CPU on my MacBook Pro. Nice!&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-4449161875536716234?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/4449161875536716234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=4449161875536716234' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/4449161875536716234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/4449161875536716234'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2008/12/lxml-eventlet-mashup.html' title='lxml + eventlet mashup'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-4655464072204561758</id><published>2008-12-06T19:09:00.000-08:00</published><updated>2009-10-22T03:58:45.362-07:00</updated><title type='text'>ptth (Reverse HTTP) implementation in a browser using Long Poll COMET</title><content type='html'>&lt;p&gt;ptth is an idea I have planning on implementing for a few years now. The basic idea is that you take normal HTTP semantics and reverse them, meaning that the client (from the TCP perspective) acts like a server (from the application perspective), and the server (from the TCP perspective) acts like a client (from the application perspective) and makes requests on the client whenever it feels like it. This is distinguished from most normal COMET semantics in that ptth retains all of http's characteristics even though the underlying transport is radically different looking at the TCP level.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;When I was at Linden Lab, I advocated using this technique in the Second Life Viewer as a refinement of the Plain Old COMET implementation currently in use (which I also helped implement). I wrote a &lt;a href="http://wiki.secondlife.com/wiki/Reverse_HTTP"&gt;wiki page&lt;/a&gt; describing how the http Upgrade: header can be used to initiate a ptth connection, effectively turning a socket that the client opened to the server around, allowing the server to make requests on the client as if the server had opened a connection to the client (even though it didn't). I even did an &lt;a href="http://soundfarmer.com/paste/B4B75B7A-2E16-4CB1-B0BC-98ADAD2B9214.py"&gt;implementation in Python&lt;/a&gt; showing how once the Upgrade: has been performed the semantics are exactly the same as normal http. This means with a little hackery it's possible (and in the Python case, almost trivial) to reuse existing http client and server libraries. All you have to mess around with is the setup of the socket; once both sides have an open socket and have agreed to Upgrade:, you just grab the underlying socket and pass it to the client or server library and away you go.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Even though I didn't get the chance to implement and deploy this technique in the Second Life Viewer and Server before I left Linden for Mochi, I still hope this gets implemented someday, as I think it is a very elegant and efficient technique. While implementing the real ptth Upgrade: in C++ will be more challenging than doing a quick Python prototype, once the dirty business of extracting sockets and injecting them into the client and server libraries used is complete, it should be a very reliable technique since at that point everything is exactly the same as normal http.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;However, it won't be possible to do these type of Upgrade: shenanigans when we are in the browser's Javascript environment and don't have access to low level details like socket APIs. Therefore, I also specced out what ptth would look like running over a Plain Old COMET Long Poll style transport. The &lt;a href="http://wiki.secondlife.com/wiki/Reverse_HTTP#COMET_Fallback"&gt;wiki page&lt;/a&gt; describes encoding the reverse request and response as JSON for ease of parsing and generating in Javascript, but other content-types could be used (application/x-http-request and application/x-http-response perhaps, or maybe the message/http mime type could simply be used or modified to be message/http+request and message/http+response?)&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;On Saturday the 6th we had a Mochi Hack Day at our office, and I was hacking on my perpetual hacking project, Pavel. If you don't know me personally and haven't heard me talk about Pavel, someday I'll flesh out the ideas behind it more fully in a series of web pages, but for now you can read &lt;a href="http://ulaluma.com/pyx/archives/2005/05/multiuser_progr.html"&gt;this old blog post&lt;/a&gt; to get a rough idea of what it is. The post uses the term "graphical multiuser networked programming environment" to describe the basic idea. From the very beginning I conceived ptth as a vehicle for driving updates of the user interface to Pavel, so I decided to get down to it and actually implement it. Since I have implemented so many COMET servers at this point that I have lost count, it turned out to be almost trivially easy, and I had something working in a few hours.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;And now the part everyone has been waiting for: the demo. The demo takes place in firebug, where you can see the Javascript side of the Long Poll operating, and in the eventlet backdoor running inside of a terminal. The eventlet backdoor gives me a Python interactive REPL into the process which is serving the server side of the Long Poll, and allows me to manually inject ptth messages into the system which then get delivered to the browser, which then responds to the request. The first thing you see me doing is building a simple ptth request by hand, encoded in JSON. I then inject this message into the ptth system, copying and pasting the uuid of the user who is connected via the Firefox browser in the background. You can see the debug printing in Firebug showing that the request was delivered to the browser, and the result in the backdoor's REPL is the response that was generated in Javascript and sent back to the server.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;embed src="http://soundfarmer.com/content/movies/ptth-to-browser.mov" height="495" width="640" autoplay="false"&gt;&lt;/embed&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;This means that I now need to implement some sort of web framework in Javascript. I know Dojo has already done this and I'm sure other people will start to experiment with this idea as well, but for my purposes I'll probably come up with something super simple. The idea that immediately came to my mind is to have URIs represent XPath into the html document, and PUT replacing the selected node with the content fragment from the request body of the PUT.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-4655464072204561758?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/4655464072204561758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=4655464072204561758' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/4655464072204561758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/4655464072204561758'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2008/12/ptth-reverse-http-implementation-in.html' title='ptth (Reverse HTTP) implementation in a browser using Long Poll COMET'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-5598808152442083818</id><published>2008-07-29T09:33:00.000-07:00</published><updated>2009-10-22T03:58:45.373-07:00</updated><title type='text'>Eventlet 0.7 and Spawning 0.7 Released</title><content type='html'>&lt;h1&gt;Eventlet 0.7&lt;/h1&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Eventlet 0.7 fixes some very long-standing bugs. First of all, there was a CPU leak in the select hub which would cause an http keep-alive connection to consume 100% CPU while it was open. The problem was that every file descriptor was being passed in to select, even if the callback for the readiness mode was None. This bug has been in since the very beginning of eventlet, and it's great to have it fixed!&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Second, another old bug. It's now possible to use Eventlet's SSL client to talk to Eventlet's SSL server. There was a subtle bug in the way SSL sockets would raise an error in some conditions instead of returning '' to indicate the connection was closed.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Finally, some memory leaks in the libevent and libev hubs (fairly new code) were fixed, so if you're using Eventlet with libevent or libev try it out and see how it performs for you.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Also, this release pulls in a bunch of API additions from the Linden SVN repository. Ryan Williams is now maintaining an HG repository which is synched with the SVN repository, so integrating patches between branches will now be much easier.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;b&gt;Update July 30, 2008&lt;/b&gt;This release of eventlet also supports stackless-pypy again. I had to check for the absence of the socket.ssl object, and re-enable the poll hub. To try this out, check out and translate pypy-c following the instructions &lt;a href="http://codespeak.net/pypy/dist/pypy/doc/getting-started.html"&gt;on the pypy site&lt;/a&gt;, and then run one of the eventlet examples (for example, "./pypy-c /Users/donovan/src/eventlet/examples/wsgi.py")&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Download Eventlet 0.7 from PyPI: &lt;a href="http://pypi.python.org/pypi/eventlet/0.7"&gt;http://pypi.python.org/pypi/eventlet/0.7&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;h1&gt;Spawning 0.7&lt;/h1&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Spawning has improved a lot since I last wrote about it. It now has a command line script, "spawn", which makes it easy to quickly serve any wsgi application. The concurrency strategy is also now extremely flexible and can be configured for a plethora of use cases.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;The default is to use one non-blocking i/o process with a threadpool, which makes it easy to use with any existing wsgi applications out there that assume shared memory and the ability to block.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;However, it's possible to independently configure the number of i/o processes, the number of threads, and even configure it to be single-process, single-thread, with fully non-blocking i/o (thanks to eventlet's monkey patching abilities).&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;b&gt;Update July 30, 2008&lt;/b&gt;This release of spawning also has an experimental Django factory. To run a Django app under Spawning, run "spawn --factory=spawning.django_factory.config_factory mysite.settings".&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Take a look at the Spawning PyPI entry for more information: &lt;a href="http://pypi.python.org/pypi/Spawning/0.7"&gt;http://pypi.python.org/pypi/Spawning/0.7&lt;/a&gt;&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-5598808152442083818?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/5598808152442083818/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=5598808152442083818' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/5598808152442083818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/5598808152442083818'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2008/07/eventlet-07-and-spawning-07-released.html' title='Eventlet 0.7 and Spawning 0.7 Released'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-48342388085534585</id><published>2008-06-16T12:10:00.000-07:00</published><updated>2009-10-22T03:58:45.382-07:00</updated><title type='text'>Spawning 0.1 Released</title><content type='html'>&lt;p&gt;Spawning is an experimental mashup between Paste and eventlet. It provides a server_factory for Paste Deploy that uses eventlet.wsgi. It also has some other nice features, such as the ability to run multiple processes to take advantage of multicore processors and multiprocessor machines, and graceful code reloading when modules change or the svn revision of a directory changes. Graceful reloading means new processes are immediately started which start serving new incoming requests, but old processes hang around processing the old requests until those requests are complete.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;This is very early still. The code is currently hard-coded to run one process, but once I figure out how to use Paste Deploy's configuration files a bit better I will make it configurable. I mostly wanted to get it out quickly because Ian Bicking asked for it in the comments of my &lt;a href="http://ulaluma.com/pyx/archives/2008/06/eventlet_05_rel.html#comments"&gt;last blog post&lt;/a&gt;, and to get feedback. I'd like more of this code to be shared between Spawning and mulib's 'mud' server. I also need a better name than Spawning.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;You can download a tarball &lt;a href="http://soundfarmer.com/eventlet/Spawning-0.1.tar.gz"&gt;here&lt;/a&gt; or you can clone the Mercurial repository &lt;a href="http://donovanpreston.com:8888/spawning"&gt;here.&lt;/a&gt;&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-48342388085534585?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/48342388085534585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=48342388085534585' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/48342388085534585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/48342388085534585'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2008/06/spawning-01-released.html' title='Spawning 0.1 Released'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-6928909523617150323</id><published>2008-06-12T04:49:00.000-07:00</published><updated>2009-10-22T03:58:45.391-07:00</updated><title type='text'>Eventlet 0.5 Released</title><content type='html'>&lt;p&gt;The last release of eventlet was 0.2, which we did when we re-open-sourced the fork of eventlet I worked on while I was at Linden Lab. 0.2 was released quite a while ago, and eventlet has seen significant improvement in the meantime.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;The main change in this release is the ability to use libevent as the multiplexing api instead of raw select or poll. If libevent and the Python wrapping are not installed, eventlet will still fall back, first checking for the presence of poll and falling back to select if it is not available.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Another major change in this release is a much improved eventlet.wsgi server. The wsgi server now supports Transfer-Coding: chunked as well as Expect: 100 Continue, and is quite fast. I tested it against an eventlet based wsgi server I wrote which uses wsgiref (from the Python 2.5 standard library) and my informal tests showed eventlet.wsgi being several hundred requests a second faster at serving a "Hello, World!" wsgi application.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;This release also features significant refactoring, cleaner code, support for cooperative operations on pipes (and unix domain sockets) as well as sockets, more tests, and docstrings for pretty much everything. The documentation, which was non-existant before, is now pretty comprehensive.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;To install, just "easy_install eventlet" and start hacking!&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;&lt;li&gt;PyPI page: &lt;a href="http://pypi.python.org/pypi/eventlet/0.5"&gt;http://pypi.python.org/pypi/eventlet/0.5&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;&lt;li&gt;Overview: &lt;a href="http://wiki.secondlife.com/wiki/Eventlet"&gt;http://wiki.secondlife.com/wiki/Eventlet&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;&lt;li&gt;Documentation: &lt;a href="http://wiki.secondlife.com/wiki/Eventlet/Documentation"&gt;http://wiki.secondlife.com/wiki/Eventlet/Documentation&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;&lt;li&gt;Mercurial Repository: &lt;a href="http://donovanpreston.com:8888/eventlet"&gt;http://donovanpreston.com:8888/eventlet&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt;&lt;br/&gt;&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-6928909523617150323?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/6928909523617150323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=6928909523617150323' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/6928909523617150323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/6928909523617150323'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2008/06/eventlet-05-released.html' title='Eventlet 0.5 Released'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-1092759670747590509</id><published>2008-06-02T03:42:00.000-07:00</published><updated>2009-10-22T03:58:45.401-07:00</updated><title type='text'>REST + Actors</title><content type='html'>&lt;p&gt;I had a really good idea over the weekend for using eventlet and mulib to combine the concepts of REST and Actors. Eventlet has had an Actor class for a while now, but I haven't really used it for anything. After otakup0pe twittered a link to the Reia language (everyone knows how much of a language geek I am) I started thinking about Actors again and how I could have applied them to various work problems I solved in the last few years. The last time I really tried to do anything serious with Actors was when I wrote the latest version of Pavel on top of the just-written (at the time) eventlet. I also tried to mix a prototype object system in there and the actor coroutines were implicit in the semantics of usage (an Actor which called a method on another Actor would be implicitly causing a switch into the other Actor's coroutine), which in retrospect was perhaps a bit too ambitious.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Ryan Williams wrote the current eventlet Actor (eventlet.coros.Actor) and it's much simpler and more straightforward: You override the received method to handle messages, and other actors call the cast method to send messages. This is different from my previous implementation (and also what my ideal would be) in that you get called back for every message, meaning the main coroutine is generic and there's no need to keep track of where the Actor's coroutine is to serialize an actor. This means it would be possible to request a representation of an Actor at any time between messages. The state would include all the Python instance variables along with all the unhandled messages currently in the Actor's mailbox.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;So, with that realization, it suddenly becomes trivial to write a mulib handler for the Actor class. GET and PUT with the appropriate content types (application/json for example) would get or set the current state of the Actor. DELETE would delete it. POST enqueues a message in the actor's mailbox (it just calls cast with the body of the request). Simple and straightforward. I'm totally going to do this soon -- it probably would have been faster to just do the implementation rather than blog about it :-)&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Oh, one more thing -- to enhance the experience of actually using these semantics, the cast method should become a generic method that dispatches based on pattern matching (using mulib.shaped). I haven't figured out what an efficient implementation of this would look like yet, but I'm going to try a brute-force implementation just for fun.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-1092759670747590509?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/1092759670747590509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=1092759670747590509' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/1092759670747590509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/1092759670747590509'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2008/06/rest-actors.html' title='REST + Actors'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-8404367475316967881</id><published>2008-05-14T05:55:00.000-07:00</published><updated>2009-10-22T03:58:45.411-07:00</updated><title type='text'>Template on PUT</title><content type='html'>I just had a cool idea. Usually, people run HTML templating engines on GET. They fetch some data, load an HTML template, and then mash the two together. My idea is to instead run the templating engine on PUT. The body of the PUT would have the data to be templated. The URL that was PUT to would determine which template to use. The response from the PUT would contain the fully templated output, equivalent to what the client would get by doing a GET to that url at any point afterwards.&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-8404367475316967881?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/8404367475316967881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=8404367475316967881' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/8404367475316967881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/8404367475316967881'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2008/05/template-on-put.html' title='Template on PUT'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-1806645163654417688</id><published>2007-09-29T17:08:00.000-07:00</published><updated>2009-10-22T03:58:45.421-07:00</updated><title type='text'>REST to LSL via Python and Comet</title><content type='html'>&lt;p&gt;For those that may not know, I got a job at Linden Lab, the creators of Second Life. I really enjoy what I do, and I find this reduces the urge to work on recreational programming on the kinds of things that I enjoy. (It has also seemed to reduce my blog output to almost nil.)&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;I've had a project on the back burner for a while that involves pushing data into LSL (the Linden Scripting Language runtime that Second Life uses) over &lt;a href="http://en.wikipedia.org/wiki/Comet_(programming)"&gt;Comet&lt;/a&gt;.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;And it works amazingly well! Of course, I just had to toss &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt; in there as well.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;I'll release this code as open source next week. Meanwhile, here's a movie to show you what the hell I am talking about. I also like how this movie shows off the surreal aspect of collaborative programming!&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;embed src="http://soundfarmer.com/content/movies/rest-lsl-comet-bridge.mov" height="600" width="798" autoplay="false"&gt;&lt;/embed&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-1806645163654417688?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/1806645163654417688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=1806645163654417688' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/1806645163654417688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/1806645163654417688'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2007/09/rest-to-lsl-via-python-and-comet.html' title='REST to LSL via Python and Comet'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-8243318201623399764</id><published>2007-06-08T10:17:00.000-07:00</published><updated>2009-10-22T03:58:45.436-07:00</updated><title type='text'>My blog is growing weeds...</title><content type='html'>It's been over a year now since I posted to this blog. What happened? I got a job at Linden Lab just over a year ago. Somehow, my blogging just stopped during that time. I have been busy though, and have been using twitter recently. I'll probably start posting here again with more frequency, as I have lots of things to talk about, but until then check out my twitter:&lt;br/&gt;&lt;br/&gt;&lt;a href="http://twitter.com/donovanpreston"&gt;http://twitter.com/donovanpreston&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-8243318201623399764?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/8243318201623399764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=8243318201623399764' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/8243318201623399764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/8243318201623399764'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2007/06/my-blog-is-growing-weeds.html' title='My blog is growing weeds...'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-2175669486546481767</id><published>2006-05-01T15:18:00.000-07:00</published><updated>2009-10-22T03:58:45.445-07:00</updated><title type='text'>Awesome</title><content type='html'>&lt;a href="http://item.slide.com/i/uid=xMSTXOmcSLEA6VtJkKLBU8gpjvGBg-a6VjoCtm9EqOxePF8Rs-o29Um-fpzIp5TVajSMFiFH9vk"&gt;&lt;img src="http://item.slide.com/i/uid=xMSTXOmcSLEA6VtJkKLBU8gpjvGBg-a6VjoCtm9EqOxePF8Rs-o29Um-fpzIp5TVajSMFiFH9vk" width="600" /&gt;&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Picked this up at Kid Robot in the Haight this weekend. It is so freaking awesome. I want more, but &lt;a href="http://dot-s.net/"&gt;can't read japanese :-)&lt;/a&gt;&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;a href="http://item.slide.com/i/uid=dYs0FyrwTPK9GYdMJTY-a-tzeHHtHE8bTHqb3V-8AdxjoJGx_E0GmcyhYWEYtJMTjdqN9xOp3tA"&gt;&lt;img src="http://item.slide.com/i/uid=dYs0FyrwTPK9GYdMJTY-a-tzeHHtHE8bTHqb3V-8AdxjoJGx_E0GmcyhYWEYtJMTjdqN9xOp3tA" width="600" /&gt;&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-2175669486546481767?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/2175669486546481767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=2175669486546481767' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/2175669486546481767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/2175669486546481767'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2006/05/awesome.html' title='Awesome'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-6482123342220343719</id><published>2006-04-25T09:59:00.000-07:00</published><updated>2009-10-22T03:58:45.455-07:00</updated><title type='text'>Running Ubuntu on Mac OS X</title><content type='html'>&lt;p&gt;One of the first things I did when I got my MacBook is install Parallels, CPU virtualization software that lets me run Windows XP in a window on Mac OS X, so I can easily test our site with Internet Explorer. It's very fast, and very, very friendly.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Recently I was tasked with discovering whether it is possible to do non-blocking file reads and writes to a filesystem that is mounted over NFS. I tried on OS X, and I was unable to get a read to return EWOULDBLOCK. So, I decided to install Ubuntu on Parallels. I downloaded the iso, burned it to a CD, created a new virtual machine, and installed it.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Everything worked flawlessly. Ubuntu has always been incredibly high quality, and it has only gotten nicer in the year since I used it last. It's polished, beautiful, and just works. It is definitely something that I could install on my machine for my Mom with a web browser and mail reader.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Here's a screenshot:&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;a href="http://www.soundfarmer.com/pictures/screenshots/ubuntu-parallels.png"&gt;&lt;br/&gt;&lt;img width="600" height="800" src="http://www.soundfarmer.com/pictures/screenshots/ubuntu-parallels.png" /&gt;&lt;br/&gt;&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-6482123342220343719?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/6482123342220343719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=6482123342220343719' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/6482123342220343719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/6482123342220343719'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2006/04/running-ubuntu-on-mac-os-x.html' title='Running Ubuntu on Mac OS X'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-2115080078523497501</id><published>2006-04-03T12:10:00.000-07:00</published><updated>2009-10-22T03:58:45.466-07:00</updated><title type='text'>Writing your Python REPL history to a file</title><content type='html'>&lt;p&gt;Something I have often wished for is the ability to save the history of a Python interactive session to a file. I often screw around in the interpreter to figure out how I am going to implement something, and it is tedious to go through and copy/paste all the lines out of the terminal into an editor and clean it up. Luckily, I discovered there is an easier way in the readline module:&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;import readline&lt;br/&gt;readline.write_history_file('my_history.py')&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;I'm sure this is going to come in handy many times.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-2115080078523497501?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/2115080078523497501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=2115080078523497501' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/2115080078523497501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/2115080078523497501'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2006/04/writing-your-python-repl-history-to.html' title='Writing your Python REPL history to a file'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-9167925986465950691</id><published>2006-03-24T14:59:00.000-08:00</published><updated>2009-10-22T03:58:45.477-07:00</updated><title type='text'>New Slide Transitions</title><content type='html'>&lt;p&gt;One of the new transitions we have been working on at Slide:&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;embed src="http://widget.slide.com/cticker/648940/ticker.swf" quality="high" scale="noscale" salign="l" flashvars="site=widget.slide.com&amp;channel=648940" wmode="transparent" width="500" height="375" name="flashticker" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"/&gt;&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Very busy at work lately. Getting a lot accomplished, and it is challenging, fun work. We're starting to ramp up pretty fast and I have been doing scalability work on the backend, which is surprisingly enjoyable after doing web front end work for so long.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-9167925986465950691?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/9167925986465950691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=9167925986465950691' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/9167925986465950691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/9167925986465950691'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2006/03/new-slide-transitions.html' title='New Slide Transitions'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-2497756197500119764</id><published>2006-01-28T20:37:00.000-08:00</published><updated>2009-10-22T03:58:45.487-07:00</updated><title type='text'>Introducing NevowPavel</title><content type='html'>&lt;img height="600" src="http://soundfarmer.com/pictures/screenshots/NevowPavel.png" /&gt;&lt;br/&gt;&lt;p&gt;I'm at SuperHappyDevHouse VII tonight. I went to II, and had a good time, but haven't been able to get back until now for various reasons. It was supposed to be last weekend, which falls on my weekend I am scheduled to work in the city, but for some reason it got bumped to this weekend. My goal for tonight is to release some code which was written almost a year ago: &lt;a href="http://www.soundfarmer.com/darcs/NevowPavel"&gt;NevowPavel&lt;/a&gt;. If you have a short attention span, watch the &lt;a href="http://soundfarmer.com/content/movies/PavelScreencast.mov"&gt;screencast&lt;/a&gt;, wherein I explain the basic idea behind the project and give a demonstration of the currently implemented features.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;This is the secret LivePage project I wrote about the last time I went to SHDH. It is a multiuser real-time updating wiki similar to and inspired by (the precursor to) &lt;a href="http://jotlive.com/"&gt;Jot Live&lt;/a&gt;, the "live" version of Jot that broadcasts real-time updates to everyone that is participating. The difference with the NevowPavel implementation is that it is "spatial". Instead of editing a contiguous page of text, each piece of text is contained in a sticky note which can be moved and resized at will to organize the information as one wishes.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Links are also handled in an interesting way. Links are inserted by dragging out a link instead of a sticky and typing a new page name. Following the link takes you to the new page, where you can create and organize new pieces of information. Each page has a user list, so you can see who is there editing with you. To organize information cross-page, you drag stickies onto links. People who are on other pages see the information appear magically.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;The ultimate goal of these template objects which you can spatially place in the page is for them to be pluggable. New types of objects should be able to be created which can provide code which renders content and handles input events for instances placed in the page. Eventually, the code should be through-the-web programmable. Obviously this involves lots of different things, like run-time code modification, restricted code execution, perhaps distributed code (to move code across multiple Pavel servers), and some sort of persistence. I'm also working on a Prototype-based object system with very simple persistence which is coming along well, but isn't integrated with the old project at all yet. This is a multi-year project, so check back again next year :-)&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-2497756197500119764?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/2497756197500119764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=2497756197500119764' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/2497756197500119764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/2497756197500119764'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2006/01/introducing-nevowpavel.html' title='Introducing NevowPavel'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3233128.post-1654053849864906589</id><published>2005-12-17T09:40:00.000-08:00</published><updated>2009-10-22T03:58:45.499-07:00</updated><title type='text'>Slide Show of Photos from Paradise</title><content type='html'>&lt;p&gt;I have been working at &lt;a href="http://slide.com/"&gt;Slide&lt;/a&gt; for a few months now. We are working on making photo sharing and real-time media communication easy to use. We've made a lot of progress on the web site recently, and one of the things we are working on is making embedding a Slide Show in an external web page easier. Here is one of my Slide Shows, pictures of my trip to Michigan this summer immediately before I began working at Slide.&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;br/&gt;&lt;embed allowScriptAccess="never" src="http://www.slide.com/images/flashticker.swf" quality="high" scale="noscale" salign="l" flashvars="site=www.slide.com&amp;channel=3059" wmode="transparent" width="600" height="97" name="flashticker" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;&lt;br/&gt;&lt;br&gt;&lt;font size="1"&gt;Get the &lt;a href="http://www.macromedia.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash&amp;promoid=BIOW"&gt;latest version of Flash&lt;/a&gt; to view Slide Show, above.  &lt;a href="http://www.slide.com"&gt;Visit Slide.com&lt;/a&gt; to create your own Slide Show&lt;/font&gt;&lt;br/&gt;&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3233128-1654053849864906589?l=donovanpreston.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://donovanpreston.blogspot.com/feeds/1654053849864906589/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3233128&amp;postID=1654053849864906589' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/1654053849864906589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3233128/posts/default/1654053849864906589'/><link rel='alternate' type='text/html' href='http://donovanpreston.blogspot.com/2005/12/slide-show-of-photos-from-paradise.html' title='Slide Show of Photos from Paradise'/><author><name>Donovan Preston</name><uri>http://www.blogger.com/profile/07076057843365973055</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
