Google loves Ruby

Can you see any reference to Ruby here?

They even have an ObjectiveC library, probably cause of the huge amount of Objective C web frameworks, but no official Ruby library.

Do they hate Ruby? Please, do not hate Ruby! I’m a poor little interpreted language used by everyone who is making real money, please love me! pleaseeeee, I’ll make you rich!

Yeah, ok, I’m sarcastic and there obviously are some unofficial Ruby libraries around there for GData.

CentOS and apache

A great part of VPS users run a CentOS, also a lot of real servers run CentOS nowadays. Usually this happens as CentOS users hope that it should be more stable, tested and secure then other distributions as being derived from an enterprise commercial one.

This might be true for most cases, but while developing PyHP we found a lot of “unknown mysterious bugs” that happened only on CentOS. After some investigation we found that apr_stat on CentOS always returns 0 as file size (this made quite interesting to allocate buffers or use mmap to read files) and also that bucket brigades had a strange behaviour, and as strange I mean that in some conditions they never considered terminated the request and caged the user in a wonderful infinite loop (as in “while(true)” not as teleporting the user to apple head quarters).

As a big percentage of PyHP users rely on CentOS we had to rewrite some parts to use lstat instead of apr_stat and also move away from bucket brigades to ap_should_client_block. If you are using CentOS and find any problem with PyHP try to upgrade to the latest svn trunk, also if you are using the svn trunk please upgrade to the latest one as there was a bug caused by the process of migrating from bucket brigades to apr_should_client_block that might prevent your users from being able to upload big files.

PyHP Database Session backend available

PyHP got the ability to save sessions on a database, the new PyHPSessionBackend config variable can be set to “db” or “file”, and PyHPDBSessionUser, PyHPDBSessionPass and PyHPDBSessionUri can be specified to set which database to use to store sessions and which user to access the database.

This works only on mysql as mysql is currently the only database supported by the pyhp database backend. Sessions will be saved in the pyhp_sessions table which will be created by pyhp itself, so remember to give to the user you choose the ability to create tables inside the selected database.

Flash and Mac OS X bug while interrupting connections

Some days ago, testing an upload feature in a web application we’re working on, someone pointed out that something seemed to go wrong trying to interrupt an upload using Firefox on Mac OS X 10.5. That sounded quite strange, since that feature worked well on Windows and Linux on Firefox, Safari and Internet Explorer too.

To manage multimedia content uploads, we use a Flash-based plugin called SWFUpload: the main reason is to allow multiple files selection and management, since although there is a standard way to select more than one file to be sent through multipart-data forms, no browsers actually support it (or to be more correct, only latest versions of Firefox do that). After some more tests, we noticed that it wasn’t a Mozilla issue, since the problem happened on Safari too and the responsibility of the reported crash had to be assigned to the Flash Player plugin… but why that happens on Mac OS X only?

Taking a look on Google, we found out that WordPress’ uploader suffers the same problem, since it uses a Flash component as multiple file selector too… So, we weren’t the only ones in trouble!

In these cases, GDB could give quite interesting information: running this debugger attached to a Firefox process, we found that:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x15b0a000
0xffff08a0 in _memcpy () at /System/Library/Frameworks/System.framework/PrivateHeaders/i386/cpu_capabilities.h:246
246 /System/Library/Frameworks/System.framework/PrivateHeaders/i386/cpu_capabilities.h: No such file or directory.
in /System/Library/Frameworks/System.framework/PrivateHeaders/i386/cpu_capabilities.h
(gdb) bt
#0 0xffff08a0 in _
memcpy () at /System/Library/Frameworks/System.framework/PrivateHeaders/i386/cpu_capabilities.h:246
#1 0x952966a3 in dataRead ()
#2 0x952e512d in CFReadStreamRead ()
#3 0x92269532 in HTTPNetConnection::transmitRequest ()
#4 0x92269860 in HTTPNetConnection::requestStreamCallback ()
#5 0x922673c1 in NetConnection::connectionRequest ()
#6 0x952e25a9 in _CFStreamSignalEventSynch ()
#7 0x952e4147 in CFWriteStreamSignalEvent ()
#8 0x9226fe91 in HTTPWriteFilter::streamFilterCallback ()
#9 0x92270503 in HTTPWriteFilter::_httpWrFilterStreamCallBack ()
#10 0x952e25a9 in _CFStreamSignalEventSynch ()
#11 0x952e4147 in CFWriteStreamSignalEvent ()
#12 0x92277bef in SocketStream::socketCallback ()
#13 0x92277cd1 in SocketStream::_SocketCallBack_stream ()
#14 0x952d97b1 in __CFSocketDoCallback ()
#15 0x952daf65 in __CFSocketPerformV0 ()
#16 0x952d063f in CFRunLoopRunSpecific ()
#17 0x952d0cd8 in CFRunLoopRunInMode ()
#18 0x946da2c0 in RunCurrentEventLoopInMode ()
#19 0x946da012 in ReceiveNextEventCommon ()
#20 0x946d9f4d in BlockUntilNextEventMatchingListInMode ()
#21 0x90af7d7d in _DPSNextEvent ()
#22 0x90af7630 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#23 0x90af066b in -[NSApplication run] ()
#24 0x0141ff89 in JSD_GetValueForObject ()
#25 0x012e5b21 in XRE_GetFileFromPath ()
#26 0x00cafaed in XRE_main ()
#27 0x00001d25 in start ()
Current language: auto; currently asm

WOW! Something’s triggering a failure in a part of Mac OS X’s CoreFoundation on i386 systems! And this actually fired trying to close the page while the Flash component was still uploading a file…

How to manage and correct this? On our side, the best thing we can do is trying to force the closure of pending connections using SWFUpload’s Javascript exposed methods, which effectively saves the browser from an unrelenting crash if our user clicks on the “cancel” button, but still doesn’t save from the eventuality of a less polite closure of the page.

Anyway, this highlights two facts: last version 10 of Adobe’s Flash Player still causes some problems and Apple’s transition to x86 platform has still something to be fixed.

Alternatives 2.0

You may know that ruby and rails hype is fading and there are lots of interesting platform that have the same good points of rails like the rapid development even if they are almost unknown. Some, like the perl catalyst, are faster, other like the new python turbogears provide everything rails gives you and overall in a cleaner, more rational shape.

Obviously you hardly heard about them or how good they are since there isn’t enough people blogging and gloating about how good they are or how many kool points your achieve by using them.

Well I’ll start some small post about it with some obviously biased comparisons, just to raise curiosity and foster discussion, let’s start with the template engines.

Catalyst suggests the use of TT by default. It is fast, quite lightweight and simplifies the perl constructs a bit.

Rails has erb as template engine with some faster implementations than the stock ones like erubis (that usually saves your day once you notice how pitiful rails is about performances).

Turbogears let you pick whatever you like, but right now suggests/bundles genshi since it’s quite fast, uses an xml compliant markup so you may edit it with your favourite xml/xhtml editor, the parser will error out if what you wrote isn’t compliant to your dtd/schema giving you a nice output pointing where it is broken like tidy does for you static content, since it is xml you may generate rich xhtml pages embedding svg and mathml with relative ease.

That’s all I hope someone will debate if is better have your template engine use a more compact markup even if then you cannot use it common tools to edit your views structure or the possibility to fully harness xml good points out weights the relative verbosity.

I will discuss ORM and models in the next post.

PyHP Sessions support improvements

Good news for PyHP. Latest SVN version got a few bug fixes and a big session management improvement. Now session collision is handled in a more coherent way, it’s a major improvement and I suggest to everyone using it to upgrade to svn revision. Also a few fixes have been implemented to catch programming errors by the developer that caused PyHP to crash making it more stable.

PyHP now supports multiple headers

SVN revision 24 of PyHP now supports multiple headers!

This broke code that iterates over the old headers_in dictionary because now every value inside headers_in is a list instead of a string. On the other side code writing inside headers_out should continue to work because it is possible to insert both a string or a list inside headers_out dictionary to set only one header or multiple headers.

You can try it from here:

PyHP improvements

New features in PyHP this week on the SVN version

  • it is now possible to set sessions timeout with PyHPSessionTimeout config variable
  • The Result object from the Database Layer is now iterable and will work as performing multiple .fetch() calls
  • pyhp.status is now exposed to return a status code different from HTTP_OK (200)
  • pyhp.content_type is now exposed to permit serving images and files different from text/html

Also some performance tests has been performed on mod_pyhp in production mode and the results are here available:

Time taken for tests:   1.419409 seconds
Complete requests:      500
Failed requests:        0
Write errors:           0
Non-2xx responses:      500 (hello_world.pyhp returns 500 on last pyhp)
Total transferred:      1558000 bytes
HTML transferred:       1344000 bytes
Requests per second:    352.26 [#/sec] (mean)
Time per request:       2.839 [ms] (mean)
Time per request:       2.839 [ms] (mean, across all concurrent requests)
Transfer rate:          1071.57 [Kbytes/sec] received

The results reveal to be quite good compared to other popular web development tools like WEBrick, mod_python and mod_php. Still they have a bunch of space for improvement to reach the “standard” ~600req/sec that more mature solutions obtain. Probably .pyhp files caching might be implemented to increase a lot performances.

I will provide a complete comparations to the other major web tools as soon as I have some time to set up a concrete test suite.