Crosstips.org

My fun Crossword solver project. Crosstips.org & Krysstips.se

Kung Fu

Fujian White Crane Kung Fu

Fry-IT

Fry-IT is the company I work for

Photos

Photoalbum, both old and new.

Zope

What I have and am doing with Zope

Receptsamlingen

In Swedish only. About my "Collection of Recipes" website.

Contact me

My contact details and how to contact me.

 

KungFuPeople.com
Do you train Kung Fu?
Or know someone who does?
Then check out KungFuPeople.com


Mobile version of this page Mobile version of this page

RSS

Hot topics

by : Some consider the module system of nginx to be a strength. Dynamic loading...

fcgi vs. gunicorn vs. uWSGI

by Oz DiGennaro: I believe we need a new world-wide movement. The only possible use of caps...

Disable Caps Lock in Linux

by aditya: Thanks a lot, after a lot of had banging i laded on this page ......

Upgrading to Ubuntu Lucid Lynx and downgrading to

by Jess: Just what I was looking for. Thanks so much....

Read in passwords with bash

by Peter Bengtsson: I agree. They have a lot on their plate and they do have to worry about pro...

Upgrading to Ubuntu Lucid Lynx and downgrading to

by ethnopunk: Thanks for the post, this is a major fail as far as Ubuntu is concerned. It...

Upgrading to Ubuntu Lucid Lynx and downgrading to

by Namke von Federlein: Same problem. I agree. What a fake-out. Testing my own apps was the very la...

Upgrading to Ubuntu Lucid Lynx and downgrading to

by Peter Bengtsson: I think the one I'm using is a hybrid of DB and memcached. Haven't looked i...

fcgi vs. gunicorn vs. uWSGI

by njharman: "Real world" apps don't use DB for sessions they use the cache backend -> m...

fcgi vs. gunicorn vs. uWSGI

by Peter Bengtsson: With gunicorn, yes, 5 workers = 5 processes but internally I'm not sure wha...

fcgi vs. gunicorn vs. uWSGI

Old entries


April, 2010
Word Whomp solvers love Crosstips
UPPER vs. ILIKE
Who was logged in during a Django exception
fcgi vs. gunicorn vs. uWSGI
Cycling across England on Orange Snapshot

March, 2010
The awesomest way possible to serve your static stuff in Django with Nginx
Beautiful photos from the Katrina hurricane
Speed test between django_mongokit and postgresql_psycopg2
How and why to use django-mongokit (aka. Django to MongoDB)
Ubuntu Cola or Ubuntu Linux
Importance of public URLs and how enterprisecarsales.com gets it wrong

February, 2010
January, 2010
2009
2008
2007
2006
2005
2004
2003

 

You're viewing blogs from Linux only.

View all different categories

17th of May

Making output stay on stdout

This is fairly obvious stuff I guess but it has troubled me for a long time. Some programs on Linux don't spit out their results to stdout. Instead they start a little program similar to less. So what is a console nerd to do?

Pipe it cat! I don't know why I've never thought of this before:

 $ psql -l | cat

11th of May

Upgrading to Ubuntu Lucid Lynx and downgrading to Python2.4 and Python2.5

So I upgraded to the latest Ubuntu Lucid Lynx 10.04 the other day and to my horror it removed Python 2.4 and Python 2.5. I rely more on those programs than I do on some silly Facebook connecting social widget crap. On my laptop I have lots of Zopes requiring Python 2.4 and I have about 10 active Django projects that rely on Python2.5. This fuckup by Ubuntu caused me to write this complaint.

So my estimeed colleague and Linux wiz Jan Kokoska helped me set things straight by showing me how to downgrade these packages to Karmic version and how to pin them in the apt preferences. First of all, make your /etc/apt/source.list look like this:

 deb http://gb.archive.ubuntu.com/ubuntu/ karmic main restricted universe multiverse
 deb-src http://gb.archive.ubuntu.com/ubuntu/ karmic main restricted universe multiverse

 deb http://gb.archive.ubuntu.com/ubuntu/ karmic-updates main restricted universe multiverse
 deb-src http://gb.archive.ubuntu.com/ubuntu/ karmic-updates main restricted universe multiverse

 deb http://gb.archive.ubuntu.com/ubuntu/ karmic-backports main restricted universe multiverse
 deb-src http://gb.archive.ubuntu.com/ubuntu/ karmic-backports main restricted universe multiverse

 deb http://security.ubuntu.com/ubuntu karmic-security main restricted universe multiverse
 deb-src http://security.ubuntu.com/ubuntu karmic-security main restricted universe multiverse

 deb http://gb.archive.ubuntu.com/ubuntu/ lucid main restricted universe multiverse
 deb-src http://gb.archive.ubuntu.com/ubuntu/ lucid main restricted universe multiverse

 deb http://gb.archive.ubuntu.com/ubuntu/ lucid-updates main restricted universe multiverse
 deb-src http://gb.archive.ubuntu.com/ubuntu/ lucid-updates main restricted universe multiverse

 deb http://gb.archive.ubuntu.com/ubuntu/ lucid-backports main restricted universe multiverse
 deb-src http://gb.archive.ubuntu.com/ubuntu/ lucid-backports main restricted universe multiverse

 deb http://security.ubuntu.com/ubuntu lucid-security main restricted universe multiverse
 deb-src http://security.ubuntu.com/ubuntu lucid-security main restricted universe multiverse

If you know what you're doing you might have other additional sources in there then keep those as is. Next thing to do is to update and upgrade:

 # apt-get update
 # apt-get dist-upgrade

You should now see that it's intending to upgrade a bunch of juicy packages like python2.4-dev for example. To check that python2.4 is now getting in from Karmic run this:

 $ apt-cache madison python2.4

Now for the trick that really makes the difference:

 # apt-get install python2.4=2.4.6-1ubuntu3.2.9.10.1 python2.4-dbg=2.4.6-1ubuntu3.2.9.10.1 \
 python2.4-dev=2.4.6-1ubuntu3.2.9.10.1 python2.4-doc=2.4.6-1ubuntu3.2.9.10.1 \
 python2.4-minimal=2.4.6-1ubuntu3.2.9.10.1

The command is quite self-explanatory. You use the equal sign to basically say what version you want to install. If you now for example want to install something like python-profiler for your Python 2.4 since this isn't available as a PyPi package. First, find out what version you have to install:

 $ apt-cache madison python-profiler | grep karmic

From that list you'll get a bunch of versions. Chose the one from karmic-updates or karmic-security. Then install it:

 # apt-get install python-profiler=2.6.4-0ubuntu1

Now, to avoid this causing a conflict and thus be removed the next time you do an upgrade you need to pin it. Create a file called /etc/apt/preferences and put the following into it:

 Package: python-profiler
 Pin: version 2.6.4-0ubuntu1
 Pin-Priority: 999

And that concludes it. A word of warning from Jan:

"he slight problem is that with this setup, suppose a big security flaw was found in python-imaging and got patched in karmic that is still supported... you wouldn't get the package update. That is because it's pinned and while asterisks can be used in the version number, we don't know in advance what the version will match and what the Lucid version that we don't want will match"

"so you basically lose security upgrades for affected packages"

"minor annoyance when you have one or two packages on a laptop, but a big deal if you have a dozen packages on 100 VMs on server"

Having written about this helps me remember it myself for the next time I need it. Also, hopefully it will help other people who get bitten by this. Hopefully this will shame the Canonical guys into action so that the next time they don't haste their deprecation process and actually think about who's using their products. I bet a majority of Ubuntu's users care more about programming or something like that than they do about the ability to buy music on Ubuntu One or whatever it's called.

8th of April

fcgi vs. gunicorn vs. uWSGI

uwsgi is the latest and greatest WSGI server and promising to be the fastest possible way to run Nginx + Django. Proof here But! Is it that simple? Especially if you're involving Django herself.

So I set out to benchmark good old threaded fcgi and gunicorn and then with a source compiled nginx with the uwsgi module baked in I also benchmarked uwsgi. The first mistake I did was testing a Django view that was using sessions and other crap. I profiled the view to make sure it wouldn't be the bottleneck as it appeared to take only 0.02 seconds each. However, with fcgi, gunicorn and uwsgi I kept being stuck on about 50 requests per second. Why? 1/0.02 = 50.0!!! Clearly the slowness of the Django view was thee bottleneck (for the curious, what took all of 0.02 was the need to create new session keys and putting them into the database).

So I wrote a really dumb Django view with no sessions middleware enabled. Now we're getting some interesting numbers:

 fcgi (threaded)              640 r/s
 fcgi (prefork 4 processors)  240 r/s (*)
 gunicorn (2 workers)         1100 r/s
 gunicorn (5 workers)         1300 r/s
 gunicorn (10 workers)        1200 r/s (?!?)
 uwsgi (2 workers)            1800 r/s
 uwsgi (5 workers)            2100 r/s
 uwsgi (10 workers)           2300 r/s

 (* this made my computer exceptionally sluggish as CPU when through the roof)


>Read the whole text (471 more words)

6th of March

Ubuntu Cola or Ubuntu Linux

Ubuntu Cola or Ubuntu Linux

Which came first?

Does it matter?

23rd of January

Guake, not Yakuake or Yeahconsole

I've been a big fan of Yakuake for a long time. It's a terminal you have open all the time in Linux that is shown and hidden, over any other windows, by a simply hit on the F12 button.

But as of more recent versions of Yakuake it has become really slow. It sometimes take 2-3 seconds from F12 press till you can type on the terminal. So I uninstalled it and tried Yeahconsole but I uninstalled it equally fast as I understood it was broken and didn't work at all despite being in the Xubuntu apt repositories.

Last but not least I ended up using Guake which not only works but also works really really fast. Screenshots here

22nd of October

Make makes my website slow? DNS

Pagetest web page performance test is a great tool for doing what Firebug does but not in your browser. Pagetest can do repeated tests to iron out any outliers. An alternative is Pingdom tools which has some nifty sorting functions but is generally the same thing.

So I ran the homepage of my website on it and concluded that: Wow! Half the time is spent on DNS lookup!

FirstSecondThird

The server it sits on is located here in London, UK and the Pagetest test was made from a server also here in the UK. Needless to say, I was disappointed. Is there anything I can do about that? I've spent so much time configuring Squid, Varnish and Nginx and yet the biggest chunk is DNS lookup.

In a pseudo-optimistic fashion I'm hoping it's because I've made the site so fast that this is what's left when you've done all you can do. I'm hoping to learn some more about this "dilemma" without having to read any lengthy manuals. Pointers welcomed.

31st of August

To sub-select or not sub-select in PostgreSQL

I have a query that looks like this (simplified for the sake of brevity):

 SELECT
   gl.id,
   miles_between_lat_long(46.519582, 6.632121,
                          gl.latitude::numeric, gl.longitude::numeric
                         ) AS distance
 FROM 
  kungfuperson gl
  miles_between_lat_long(46.519582, 6.632121,
                         gl.latitude::numeric, gl.longitude::numeric
                         ) < 5000

 ORDER BY distance ASC;

It basically finds other entries in a table (which has columns for latitude and longitude) but only returns those that are within a certain distance (from a known latitude/longitude point). Running this query on my small table takes about 7 milliseconds. (I used EXPLAIN ANALYZE)

So I thought, how about if I wrap it in a sub-select so that the function miles_between_lat_long() is only used once per row. Surely that would make it a lot faster. I accept that it wouldn't be twice as fast because wrapping it in a sub-select would also add some extra computation. Here's the "improved" version:

 SELECT * FROM (
 SELECT
   gl.id,
   miles_between_lat_long(46.519582, 6.632121,
                          gl.latitude::numeric, gl.longitude::numeric
                         ) AS distance
 FROM 
  kungfuperson gl
 ) AS ss
 WHERE ss.distance < 5000
 ORDER BY ss.distance ASC;

To test it I wrote a little script that randomly runs these two versions many many times (about 50 times) each and then compare the averages.


>Read the whole text (81 more words)

11th of August

gg - wrapping git-grep

I've grown quite addicted to this and finding that it's saving me tonnes of milliseconds every day. First of all, I've made this little script and put it in my bin directory called '~/bin/gg':

 #!/usr/bin/python
 import sys, os
 args = sys.argv[1:]
 i = False
 if '-i' in args:
     i = True
     args.remove('-i')
 pattern = args[-1]
 extra_args = ''
 if len(args) > 1:
     extra_args = ' '.join(args[:-1])
 if i:
     param = "-in"
 else:
     param = "-n"
 cmd = "git grep %s %s '%s'" % (param, extra_args, pattern)
 os.system(cmd)

Basically, it's just a lazy short hand for git grep ("Look for specified patterns in the working tree files"). Now I can do this:

 peterbe@trillian:~/MoneyVillage2 $ gg getDIYPackURL
 Homesite.py:526:    def getDIYPackURL(self):
 zpt/homepage/index_html.zpt:78:       tal:attributes="href here/getDIYPackURL">Get your free trial here</
 zpt/moneyconcerns/index_html.zpt:36:       tal:attributes="href here/getDIYPackURL">Get your free trial h
 zpt/moneyconcerns/index_html.zpt:50:          <p><a tal:attributes="href here/getDIYPackURL" class="makea
 (END) 

It's not much faster than normal grep but it automatically filters out junk. Obviously doesn't help you when searching in files you haven't added yet.

12th of May

Sequences in PostgreSQL and rolling back transactions

This behavior bit me today and caused me some pain so hopefully by sharing it it can help someone else not ending up in the same pitfall.

Basically, I use Zope to manage a PostgreSQL database and since Zope is 100% transactional it rolls back queries when exception occur. That's great but what I didn't know is that when it rolls back it doesn't roll back the sequences. Makes sense in retrospect I guess. Here's a proof of that:

 test_db=create table "foo" (id serial primary key, name varchar(10));
 CREATE TABLE
 test_db=insert into foo(name) values('Peter');
 INSERT 0 1
 test_db=select * from foo;
  id | name  
 ----+-------
   1 | Peter
 (1 row)

 test_db=#  select nextval('foo_id_seq');
  nextval 
 ---------
        2
 (1 row)

 test_db=begin;
 BEGIN
 test_db=insert into foo(id, name) values(2, 'Sonic');
 INSERT 0 1
 test_db=rollback;
 ROLLBACK
 test_db=#  select nextval('foo_id_seq');
  nextval 
 ---------
        3
 (1 row)

In my application I often use the sequences to predict what the auto generate new ID is going to be for things that the application can use such as redirecting or updating some other tables. As I wasn't expecting this it caused a bug in my web app.

22nd of April

Git + Twitter = Friedcode

Git + Twitter = Friedcode I've now written my first Git hook. For the people who don't know what Git is you have either lived under a rock for the past few years or your not into computer programming at all.

The hook is a post-commit hook and what it does is that it sends the last commit message up to a twitter account I called "friedcode". I guess it's not entirely useful but for you who want to be loud about your work and the progress you make I guess it can make sense. Or if you're a team and you want to get a brief overview of what your team mates are up to. For me, it was mostly an experiment to try Git hooks and pytwitter. Here's how I did it:


>Read the whole text (252 more words)

16th of March

Nginx vs. Squid

We all know that Nginx is fast and very lightweight. We also know that Squid is very fast too. But which one is fastest?

In an insanely unscientific way I added some rewrite rules to my current Nginx -> Squid -> Zope stack so that for certain static content, Nginx could go straight to the filesystem (where the Zope product holds the static stuff) to bypass the proxy pass. Then I did a quick and simple benchmark with ab comparing how to get a 700 bytes GIF image:

 squid: 2275.62 [#/sec] (mean)
 nginx: 7059.45 [#/sec] (mean)


>Read the whole text (143 more words)

10th of December

Wing IDE versus Jed

For the impatient: Jed and Wing IDE are programming editors I use for my Python, Javascript, HTML, CSS editing. One is ultra-light, fast and simple. The other one is very feature full, commercial and slow (in comparison to Jed).

I've been using Jed now for several years on Linux. It's an "Emacs clone" 1 in that almost the same key bindings you have in Emacs work in Jed. A few weeks ago I started using Wing IDE 3.1 instead to see if I could learn to love it. I got a professional license as a gift for participating in the PyCon 2008 sprint by Wingware (the company behind Wing IDE). As of yesterday I've gone back to Jed but I haven't uninstalled Wing yet. Here are what I've learned from using both quite a bit. Note, I'm not comparing things that they both do equally well such as macros, community support and block indentation.


>Read the whole text (739 more words)

22nd of November

Finally got rid of the system beep

I have a Thinkpad T60p which is working really well for me. On it I've run various flavors of Ubuntu and as of a couple of weeks ago I put on Ubuntu 8.10 which has been working very well too except that I didn't get any options in the Preferences menu to switch off the damn loud system beep. The beep comes through the speakers and at a much much louder volume than any other sound or music.

I tried changing thins in BIOS and I tried installing various packages hoping one of them will give me the options. Finally I've found out how to disable it:

 $ sudo modprobe -r pcspkr

This tip page showed me how to put it into /etc so it's applied all the time. Thanks Andy!

9th of October

Why bother with MySQL...

...over PostgreSQL? I've just read through this document:MySQL vs PostgreSQL and it's obvious paragraph after paragraph that PostgreSQL is the better database. Performance, features and community are all in PostgreSQL's favor. There is almost nothing in MySQL's favor apart from obscure things like faster count(*) (without conditionals) and built in replication support. In the last two weeks I've also had the great fortune of playing with full textindexing in both MySQL and PostgreSQL and again, MySQL sucks ass and PostgreSQL (8.3) is really impressive and fast. (I've used both databases quite extensively over the past 8 years as a web developer)

I once heard that Google uses MySQL for its user database with a custom built transaction machine. And I read that Google engineers had donated some great code to the MySQL project. But why do they bother? What do they know that other engineers don't? And why is MySQL so popular with cheap stack-em-high LAMP hosting sites?

I do understand that PostgreSQL came off a bad start 5 years ago(ish) when it didn't support Windows which meant that newbies had to use MySQL and that stigma is still lingering but that was a very long time ago.

I guess it takes a lot of convincing to switch from one technology to another once you've set your mind on something. That's why we're human. A proof of this is shown if you scroll down to the bottom of this page there's a little simple survey and despite being on a long article with objective convincing arguments that PostgreSQL is better MySQL is doing quite well. Why?

4th of July

A great thing about Squid: Calamaris

A great thing about Squid: Calamaris I'm talking about Squid the web proxy cache server and Calamaris the Squid log file analyzer not food. Calamaris was a breeze to set up and now it emails me once a month a report summary of what Squid has done for my site each month. It's brilliant because it includes a piece of information that both really easy to understand and really useful no matter how technical you are:

 Proxy statistics                                                                
 -------------------------------------------------------------------- 
 Average speed increase:                                     %  44.57 

Nota bena: I've had to work on this. It used to be a lot lower before but I've worked on setting no-refresh on selected few resources and I've tweaked the Cache-Control headers here and there.

What people sometimes forget about Squid is that it can actually slow down your site too. On an individual object that you test with ab you can go from 50 requests/sec to 2000 requests/sec but for large sites with many many objects Squid has to do a lot of thinking to work out what to cache, not to cache, put in RAM, etc. Just installing Squid is not necessarily good enough. You have to massage and caress it till it starts to work for you. And to get to that Calamaris really helps.

2nd of June

Damn lies and benchmark comparing Apache and Nginx

Today I moved a bunch of sites over from Apache to Nginx but still keeping Squid in between as a http accelerator (I hope to replace Squid with Varnish soon). I did a quick benchmark of a HTML page that is cached by Squid, 4 times via Apache and 4 times via Nginx. The results:

 Apache2
 ********
 Requests per second:    1601.34 [#/sec] (mean)
 Time per request:       6.268 [ms] (mean)
 Time per request:       0.627 [ms] (mean, across all concurrent requests)
 Transfer rate:          13020.50 [Kbytes/sec] received

 Nginx
 ********
 Requests per second:    1810.02 [#/sec] (mean)
 Time per request:       5.6435 [ms] (mean)
 Time per request:       0.5645 [ms] (mean, across all concurrent requests)
 Transfer rate:          14591.35 [Kbytes/sec] received

That's "only" 13% faster and I had hoped for a bigger difference but the test is very simple and depends on how Squid feels. The other important test would be to see how much less CPU and memory Nginx uses during the stresstest period but that's for another day.

One note: This is Nginx 0.4.3 on Debian Etch. The current stable release is Nginx 0.6.13. I'll need to talk to my sys admins to remedy this. Perhaps it makes a difference on the benchmark, I don't know.

7th of April

pwdf - a mix of ls and pwd

I often need to know the path to a file so that I can put that in an email for example. The only way I know is to copy and paste the output of pwd followed by a slash / followed by the name of the file. This is too much work so I wrote a quick bash script to combine this into one. Now I can do this:

 $ cd bin
 $ pwdf todo.sh 
 /home/peterbe/bin/todo.sh

I call it pwdf since it's pwd + file. Here's the code for the curious:

 #!/bin/bash
 echo -n `pwd`
 echo -n '/'
 echo $1

Is there no easier way built in into Linux already?

31st of March

One thing I hate about Linux: cron

First of all, I understand that the problem cron solves is a hard one but come on, it's been many years now without much progress. At least not in the usability field of cron jobs. Secondly, I don't know of an operating system that does this better. Perhaps there is one. All I'm saying here is that this aspect of Linux sucks. The issues I have with cron are:

Beef number 1 Is it root, user1 or user2 running a crontab job? I'll have to su into each suspected user and run crontab -l. Granted, some jobs require root access and others don't but it nevertheless makes it hard to find the configured jobs when maintaining someones server.

Beef number 2 Even though they do such a similar thing, it feels like /etc/cron.* is a different battlefield from crontab. Why can't this all be in one coherent place?

Beef number 3 The crontab syntax. How difficult would it be to allow an interface to accept user input as "every 10 minutes" or "01.30 every day"?

Beef number 4 With there being 12 different ways (sarcasm) to write cron job scripts there's no coherent place to collect all log and errors that happen from cron. Couldn't it be default to always write to /var/log/cron/access.log and all executions that cause a write to stderr could append to /var/log/cron/error.log

I don't think Anacron would make me any happier since the problem Anacron solves was not one of the problems I listed above. And lastly, I wouldn't be surprised if there's a semi-abandoned Open Source project on SourceForge that is user friendly but what I'm after is something to get into stock Linux. Kind of like apt/aptitude/dselect is for dpkg maybe?

28th of March

How to uninstall nginx with apt

My colleague Jan showed me how to do this so I'm going to blog about it to not forget and perhaps by being here other people might be able to search and find the solution too. I installed nginx because I wanted to play with it as an alternative to apache on my laptop. Now I've played enough and I'm going to want to remove it. My first attempt didn't work:

 peterbe@trillian:~ $ sudo apt-get --purge remove nginx
 Reading package lists... Done
 Building dependency tree
 Reading state information... Done
 The following packages will be REMOVED:
  nginx*
 0 upgraded, 0 newly installed, 1 to remove and 116 not upgraded.
 1 not fully installed or removed.
 Need to get 0B of archives.
 After unpacking 528kB disk space will be freed.
 Do you want to continue [Y/n]?
 (Reading database ... 242827 files and directories currently installed.)
 Removing nginx ...
 Stopping nginx: invoke-rc.d: initscript nginx, action "stop" failed.
 dpkg: error processing nginx (--purge):
  subprocess pre-removal script returned error exit status 1
 Starting nginx: invoke-rc.d: initscript nginx, action "start" failed.
 dpkg: error while cleaning up:
  subprocess post-installation script returned error exit status 1
 Errors were encountered while processing:
  nginx
 E: Sub-process /usr/bin/dpkg returned an error code (1)

I tried this both before and after having stopped and started nginx. Nothing worked. The trick is to fiddle with the init script /etc/init.d/nginx and insert a exit 0 at the top so that it now starts like this:

 #!/bin/sh
 exit 0

Once saved and you try apt-get --purge remove nginx it will work. It might warn you that /var/log/nginx aren't removed because they're not empty but you can safely remove them manually unless you want to keep them.

6th of March

File check before delete

Because I always forget, here's how to check if a file exists before attempting to delete it in bash:

 [ -f foobar.html ] && rm foobar.html

If you don't do it this way and the file doesn't exist you get this:

 rm: cannot remove `foobar.html': No such file or directory

 

Older entriesOrder entries