Не съм и вярвал, че точно аз (и то след толкова време) ще пусна поезия на блога, обаче това много ми хареса, и си заслужава да бъде запазено тук и споделено с всички които вярват в себе си.


Дамян Дамянов

Когато си на дъното на пъкъла
Когато си най тъжен и злочест
От парещите въглени на мъката
Си направи сам стълба и излез
Светът когато мръкне пред очите ти
И притъмнява в тези две очи
Сам слънце си създай и от лъчите
Създай си стълба и по нея се качи
Когато от безпътица премазан си
И си зазидан в четири стени
От всички свои пътища премазани
Нов път си направи и сам тръгни
Трънлив и зъл е на живота ребуса
На кръст разпъва нашите души
Загубил всичко, не загубвай себе си
Единствено така ще го решиш.

Start It Smart | SIStory – Христо Попов

Записи от събитието SIStory (Successful Inspirational Story), което се състоя на 25 септември 2012, като гост-лектор бе Христо Попов. Събитието се организира от клуба по предприемачество Start It Smart

IGN’s Top 100 Super Heroes

Сверете си часовника, като проверите класацията на IGN за стоте най-популярни комикс герои: герои, не злодеи – въпреки, че Рик Граймс от „The Walking Dead“ и Йорик Браун от „Y: The Last Man“ са си съвсем обикновенни хора ;)

Funky caching in WordPress + nginx/php-fpm without any plugins

If you ask me if I am against  doing everything yourself  or using the available solutions, my answer usually is going to be that it is best to use what’s available and save yourself the time and efforts to do (and maintain) a solution of your own. „Usually“. Here’s a cautionary tale of how tried to go by that rule and did the opposite.

A foreword.

I have this pet project which is 10 WordPress sites on a 512MB VPS. Each of those sites has several thousand posts and few thousand tags/categories. It used to be no problem for WordPress to handle such sites, but with each new version WordPress is getting slower and slower. Last configuration was on a 512MB slice from Slicehost, which at the time (late 2008) seemed like the best solution.

Using APC.

To make it run as fast as possible I deployed APC, although any other opcode cache would do fine. The „project“ is a set of 10 WordPress sites. Unfortunately this made it run slower than originally. Why ? Imagine having 2 sites,  abc.com and xyz.net, both running the  latest WordPress,  so almost everything inside them is the same – everything but their own unique themes and their own set of plugins. Now, when those run on the same machine APC will have to store the files for both of them, e.g. /var/www/abc.com/html/wp-login.php and /var/www/xyz.net/html/wp-login.php – and this is the same for every other file from the WordPress distribution. At first it is obvious that this is just waste of space since those are identical. At second look however you see the worse downside:  these identical files are going to take twice as much space.  This will cause the APC memory to deplete really fast and because of this decreasing the performance boost we are expecting to get from having a opcode cache. Now instead of having just 2 sites imagine having 10 sites: the cached copies inside APC were cleaned up before even being hit, because the space in the bytecode cache was not enough.

Using APC with symlinked WordPress.

The solution for the problem above was to symlink everything for each site except the configuration from wp-config.php – in this way APC will not have to deal with duplicate copies of the same files. The plugins and themes are also placed with one another. Here’s what a ls -la looks like:

lrwxrwxrwx 1 www-data root   27 Feb 18 16:36 crossdomain.xml -> /var/www/wp/crossdomain.xml
-rw-r--r-- 1 www-data 1000  246 Dec  4  2007 favicon.ico
lrwxrwxrwx 1 www-data root   21 Feb 18 16:36 index.php -> /var/www/wp/index.php
lrwxrwxrwx 1 www-data root   23 Feb 18 16:36 license.txt -> /var/www/wp/license.txt
lrwxrwxrwx 1 www-data root   23 Feb 18 16:36 readme.html -> /var/www/wp/readme.html
lrwxrwxrwx 1 www-data root   22 Feb 18 16:36 robots.txt -> /var/www/wp/robots.txt
lrwxrwxrwx 1 www-data root   27 Feb 18 16:36 wp-activate.php -> /var/www/wp/wp-activate.php
lrwxrwxrwx 1 www-data root   20 Feb 18 16:36 wp-admin -> /var/www/wp/wp-admin
lrwxrwxrwx 1 www-data root   22 Feb 18 16:36 wp-app.php -> /var/www/wp/wp-app.php
lrwxrwxrwx 1 www-data root   23 Feb 18 16:36 wp-atom.php -> /var/www/wp/wp-atom.php
lrwxrwxrwx 1 www-data root   30 Feb 18 16:36 wp-blog-header.php -> /var/www/wp/wp-blog-header.php
lrwxrwxrwx 1 www-data root   32 Feb 18 16:36 wp-comments-post.php -> /var/www/wp/wp-comments-post.php
lrwxrwxrwx 1 www-data root   31 Feb 18 16:36 wp-commentsrss2.php -> /var/www/wp/wp-commentsrss2.php
-rw-r--r-- 1 www-data 1000 1048 Feb 23 20:08 wp-config.php
lrwxrwxrwx 1 www-data root   22 Feb 18 16:36 wp-content -> /var/www/wp/wp-content
lrwxrwxrwx 1 www-data root   23 Feb 18 16:36 wp-cron.php -> /var/www/wp/wp-cron.php

How is that going to help? Very simple: there are no more duplicates and APC only works with one set of files. A little tweaking was required to make wp-super-cache plugin work, but for a while everything was OK.

The new setup.

Recently I moved the project from Slicehost to Linode:  it is a lot more affordable – 32bit setup for almost half the money (for 512MB). For the new setup I decided to ditch Apache and try something new – nginx + phpfpm. That was not enough and decided to ditch wp-super-cache and try w3-total-cache with all the different layers of performance boost that it offers. Linode makes very easy to deploy a LEMP setup, and with some help from a friend of mine I was ready to go.  Then I installed w3-total-cache and the problems started:

  • you got to do your own rewrite rules for nginx
  • the „page cache“ was not using the domain name for the site, so the wrong cached pages popped up at the wrong places, e.g. abc.com/2008/10/ opened the page from xyz.net/2008/10/
  • the performance was degraded, not improved

I spend the best of the last 2 days to try and find a way around this issue.  It seems that W3TC prepends the domain name only when the WordPress is a WPMU/Multisite installation. I do not wanted to dive into that, so after 30 mins ot thinking I decided to ditch W3TC and do a „page cache“ (funky caching really) on my own. After several hours I was ready, and it works like a charm.  It pretty much works like wp-super-cache, but without all the settings and admin pages – I know how my projects behaves so I didn’t need all the stuff for purging cache on adding comments, changing statuses, writing new posts or whatever. I customized part of W3TC for cleaning up the static files on disk, but instead of relying on WordPress’ pseudo-cron I decided to use the VPS crontab instead: and it is really easy – you just have to call the script ;)

The script and how to set it up yourself ?

http://pastie.org/1633881 (download)

First you got to enable WP_CACHE in your wp-config.php file, because this is the requirement to make WordPress include our script. The script is called advanced-cache.php (WordPress named it like that) and it has to be placed inside your wp-content/ folder. You can find the rewrite rules for nginx inside the script as a comment (if you are wondering what HB stands for, that’s an abbreviation for the pet project).

So, fuck you W3TC ;)

PS. It turns out somebody else has that symlink solution figured out long time before myself, and it is actually documented on WordPress’ Codex:

This system is based on Allan Mertner’s original symbolic link hack.


Краят на блога както го познаваме, или търсене на ново начало

Последната година ми показа ясно, че скоро време за блога няма да имам. Не знам имали и смисъл, след като вече местата за коментиране и обмен на информация са Twitter и Facebooк, а и май съм на някаква интелектуална диета и май нямам какво да добавя за новите неща които се случват напоследък. Поне в тази форма не виждам този блог да има бъдеще. Ако по някакво щастливо стечение на обстоятелствата намеря време през идващата 2011 година ще потърся начин как да променя сайта и блога, като останат нещата, които може би са най-важни: информация как да ме откриете, и проектите над които работя. До тук са 755 поста и 1702 коментара, като имам и 99 драфта, които така и не съм довършил. Все още не съм намерил това, в което исках да направя от моя блог през времето през което имах да пиша: място на което да се обсъждат новините от българския ИКТ живот. Напоследък не е като да няма: няколко сливания, като се забелязва тенденцията към консолидация и окрупняване, нови проявления на „цифровия живот“ като чуруликащия гняв, няколко конференции, издънки на билинг системи на мобилни оператори, академична реформа, Ранделов смени Киряков, Свежо се раздели с Нетинфо (и със Станислав, но може би не в този ред), БГ Сайт 2010, OpenFest 2010 и т.н. и т.н. За момента ще продължаваме да си ги подхвърляме в Twitter и във Facebook ;)

Докладване под карантина или „Quarantine Logging“

Отдавна не съм писал в блога, да не повтарям баналното „Няма Време!“, но нямам как –живота си тече от баналност до баналност докато се чудим как да сме оригинални ;) Както и да е, днес реших да опитам нещо ново и публикувах първият си пост на английски в опит да съчетая полезното с приятното: надявам се написаното за Quarantine Logging да ви е интересно ;) Критики приемам всякакви.

Понеже ни съм пускал снимка за септември, ще взема една „назаем“ от Facebook ;)

 Бобето срещу ябълката
Бобето срещу ябълката

Quarantine Logging

Certainly these days everyone knows that your PHP project should be developed with error reporting set to report everything with E_ALL|E_STRICT (I guess the sloppy freelance days are over). When the project is deployed on a live server you can set the error reporting to log only the severe errors (fatal errors and exceptions), or you can leave it with the detailed error reporting. While I was not a fan of the latter, I did appreciate how useful it is when tracking bugs, since there is certainly a notice or a warning to hint you in the right direction. It is twice that important if your project is a SaaS solution, and you are responsible not only for the development of the application, but for hosting it and making it available to your customers. In that situation detailed logging is as priceless as doing backups: probably in 95% of the time you will not need it, but when the „fuck-up fairy“ comes knocking it is better to be prepared.

Speaking of backups, detailed logging probably shares one more feature with them – the huge space that it occupies. For an application that works without hick-ups for several months the volume of the logs is several times bigger the rest of the application data. The volume of the detailed logging data gets even bigger when 3rd party apps, plug-ins or add-ons are used, since they not always comply with the E_ALL|E_STRICT policy, and some of them might produce tons and tons of repetitive warnings and notices. Depending on the media on which the detailed logging is stored, it might cause performance degradation in the application when its volume gets out of proportions.

That’s the problem I’ve been faced with recently. I want application to run as fast as possible, not burdened by the detailed logging, yet I want to be able to have all the data I need for when tracking bugs and issues. The solution I came up with is called „Quarantine Logging“.

In general, I want to keep all the data that is required for tracking and fixing issues. So, when are these „issues“ tend to surface ? I am sure that you share the same observations as myself: issues happen when the application is deployed: when installed, or when updated. When it starts running you fix the issues that pop up, and the longer it runs, there is less chance for something to go south. Anyway, that’s not always – that’s just for most of the time: usually bugs show their ugly head when you least expect them ;) So, if we can expect problems with a certain probability for some period of time (e.g. after deployment), then let’s turn on the detailed logging only for that time. Hence, the „quarantine“ ;)

The quarantine is the time after the application has been updated, or in other words the time after the supposed problems have been introduced. Until the application is under quarantine, it will use detailed logging to report everything that’s happening. Once the quarantine is over, we can reduce the logging to only the severe emergencies: errors and uncaught exceptions. It is a fair trade-off: you get all the detailed logs for N days (a week) while under quarantine, and then only the most ugly stuff ;)

To make this work after each deployment, install or update, you have to put the application under quarantine, where you choose what period will fit your needs – in mine it is (as suggested above) 7 days. That’s not all: while not being under quarantine, an error or an uncaught exception can happen. The severe-only logging will report it, but in addition to that it will put the application in a state of „self-quarantine“ for M days (2 for example): during that time we expect the error/exception to happen again, so we are again doing the detailed logging while under quarantine.

So, that’s it for Quarantine Logging. I will not bother you with a concrete implementation, I am sure you can manage to do it yourself for your own error reporting. I myself just implemented this feature and will see how it behaves in the next few months.