2011-09-11

Ett år av träning

Jag har aldrig tidigare varit särskilt intresserad av träning och när kompisar har frågat mig om jag inte ska hänga med till gymmet eller liknande så har svaret alltid automatiskt varit "nej". Men för exakt ett år sedan så hände någonting.


Motivation
Jag har 2 stycken söner som är 4 och 8 år gamla och jag älskar att leka med dem, men jag märkte mer och mer att min energi inte riktigt räckte när man kom hem efter en heldag på jobbet. Efter att man hade lagat mat, städat upp och fixat i ordning så fanns det helt enkelt ingen energi kvar den lilla stunden som fanns kvar innan det var läggdags för barnen. Ofta fanns det inte ens energi till att städa upp heller, utan man däckade i soffan istället.
De senaste åren har jag dessutom stadigt gått upp i vikt. Kanske inte så mycket, men kroppsformen har förändrats med åren och jag har känt mig mer och mer "osexig" (inte för att jag någonsin har ansett mig vara sexig :) ).

Förändringen
Min hustru har i några år tränat från och till och har vid ett flertal tillfälle påpekat för mig att jag kanske borde träna lite eftersom man faktiskt får energi av träning. För ett år sedan bestämde hon sig dessutom för att gå på en extravagansa-diet (diet där man bara äter pulver) och dessutom börja träna lite mer och bad mig att hjälpa henne att hålla sig borta från onyttig mat och godis. "Självklart" sa jag , men började sen fundera lite mer på detta. Jag tänkte att det bästa sättet att hjälpa henne måste ju vara att jag också ger mig på någon typ av diet och att jag dessutom började träna.
Det var ett första steg att börja tänka på detta, men jag behövde några veckor att bearbeta tankarna lite. Det var ett stort steg att faktiskt göra det.
Det första jag beslutade mig för var att köra på en GI-diet. Jag har en del kompisar som har kört GI eller LCHF-dieter som i princip går ut på att man äter så lite kolhydrater som möjligt, men i gengäld kan lägga på lite mer fett på kosten. Detta låter lite tokigt, men ju mer man tänker och läser om det så är det inte helt fel. Jag såg helt klart fördelarna med att kunna grilla en stor köttbit med en god fet bernaisesås och en god sallad till och istället skippa potatisen, pastan eller riset. Sagt och gjort, första veckan var inte lätt innan sötsuget försvann och i värsta fall fick man ta till en bit mörk choklad till kaffet. På tal om kaffet, så slutade jag även helt med socker i kaffet samtidigt.
Att börja träna tog några veckor till. Vi har sedan studietiden varit goda vänner med Anna och Roger Tell och de senaste 6 åren har även jag och Roger jobbat på samma arbetsplats. Jag har alltid trivts väldigt bra tillsammans med dem, vi ha grymma fester tillsammans och de har dessutom barn som fungerar bra ihop med våra egna barn. Både Anna och Roger jobbar även som instruktörer på Lerums Sportcentrum (LSC) som ligger i lilla Stenkullen där vi bor. De gånger vi har diskuterat träning så har de alltid rekommenderat mig att jag ska prova på BodyCombat och jag måste erkänna att jag tyckte det lät lite "coolt" att prova på (fåfängan vinner alltid).

Så exakt för ett år sedan så gick jag på mitt första BodyCombat-pass och blev väldigt positivt förvånad.
De kommande dagarna var jag inte så positiv med den enorma träningsvärken som jag fick och var väldigt ovan vid. Som tur var så härdade jag ut och fortsatte att gå, och efter några veckor med BodyCombat 2 ggr i veckan så försvann träningsvärken nästan helt.
På något sätt lyckades jag fortsätta att träna regelbundet. Troligtvis på grund av ett antal faktorer:

  • Roligt: BodyCombat var riktigt roligt. Lite skrämmande i början för att man tycker att man gör allting fel och att alla tittar på en. Att göra fel är dock inte hela världen, och efter ett tag inser man att ingen tittar på en eftersom alla är så fokuserade på vad de själva gör. 
  • Trevligt: Min hustru och jag gick på många pass tillsammans och gjorde det till "vår grej tillsammans".
  • Peppande: Instruktörerna på LSC är grymt duktiga och peppar en till att göra sitt bästa oavsett vilken nivå du är på. Hade det dessutom inte varit för min hustru, så hade jag nog fallit tillbaka på latheten.
  • Lägligt: LSC ligger 500 meter från pendelstationen och 200 meter från skolan och dagis. LSC har dessutom barnpassning (KidzInn) där båda barnen trivs och ofta träffar olika kompisar. Oscar frågar ofta om vi inte kan åka till "gymmet" när man hämtar dem på dagis/skolan.
  • Lämpliga tider: Det verkar som om LSC har tänkt till när de har plannerat träningspassen. I varje fall så passar tiderna mig väldigt bra. Tex går en hel del pass vid 17:30 på vardagar. Det passar perfekt att hämta barnen lite före 17 och hinna med ett snabbt mellanmål innan det är träningsdags. På vardagar blir det dock ofta att den ena hämtar barnen när den andre ska träna så att barnen får komma hem så snart som möjligt.
    Min äldste son går dessutom på judo på lördagar och onsdagar, så det passar väldigt bra att köra några varv på "milon" (cirkelträning med både styrka och kondition).

Kontinuitet
Nästa stora utmaning var att fortsätta med träningen. Även om det finns många motivationsfaktorer så är det väldigt lätt att falla tillbaka på latheten. En god vän frågade för några veckor sedan "Hur lång tid tog det tills träningen blev ett beroende?". Dvs hur länge ska du ha tränat tills du kommer till en punkt då det börjar krypa i kroppen om man inte tränar?
Detta är en väldigt bra och befogad fråga, och för mig tog detta rätt så lång tid. Ca 6 månader med träning ca 2 ggr/veckan. Men lyckas man hålla ut så länge så följer träningen automatiskt efteråt. Man VILL gå och träna. I slutet av våren så började jag till och med att börja köra dubbelpass på söndagar med BodyPump och BodyCombat direkt efter varandra. Dock hade jag ett uppehåll i somras i 4:a veckor eftersom jag skadade ett revben när jag var på soptippen och hade problem att röra mig.

Resultatet
Lägger man ihop alla dessa faktorer så finns det inte längre någon anledning till att inte träna. I gengäld blir belöningen:
  • Pigg: Redan efter några veckor så märkte jag att tröttheten minskade och man orkade väldigt mycket mer. Tidigare när jag läste godnattsaga för barenen så hade jag en tendens att somna.
  • Tålamod: Som ett resultat av att tröttheten försvinner så blir också tålamodet mycket bättre. 
  • Ork.Man får ork att ta tag i saker.
  • Vikt: Under första månaderna som jag började träna och dessutom körde GI, så gick jag ner 10kg. Jag har dock gått upp lite efter att jag slutade med strikt GI, men kroppens proportioner är helt annorlunda nu :) 
  • Mindre osexig: Underskatta inte fåfängan :)

Fördomar
Före jag började träna så hade jag en hel del fördomar gällande "gym" (dock har jag kanske spätt på dem lite här): 
  • Alla "gymmare" är mellan 20 och 25 år och bara där för att visa upp hur snygga de är.
  • 25% av alla på ett "gym" dopar sig på något sätt.
  • Går man på gym och är lite lönnfet så kommer man att bli utskrattad/utfryst.
Detta är ju helt löjligt och totalt totalt felaktigt, iallafall på LSC där jag tränar.
  • Alla "modeller" är representerade. På LSC ser man allt från tonåringar till pensionärer i alla storlekar och alla verkar ha lika trevligt. Det verkar finnas ett pensionärsgäng som ofta är där och mer använder gymmet som ett sätt att träffas. Helt underbart, och jag kan bara hoppas att jag kommer att göra samma sak en dag.
  • Doping har jag aldrig sett om man nu inte ska kalla endorfiner eller proteindrinkar för doping (ung. samma sak som att dricka en bit kött). 
  • Inställningen på LSC är alltid att alla ska trivas, och detta smittar av sig på alla som är där. Även om man inte känner personalen så hejar de alltid på en när man kommer dig och önskar en välkommen.

Tack till min hustru, LSC och Tellarna som har hjälpt mig att genomföra detta! 


2011-05-09

Optimized websites

This article is about how to setup and develop a website in PHP.
At our company we develop a Learning Management System (LMS), and a couple of years ago we decided to rewrite the whole LMS from scratch and at the same time take all our experience and make the best of it.
We took into consideration everything from choice of web-server, scripting language, database backend, clients proxy caching (that we have had some problems with before), etc etc.
This is a guide on our experiences from nothing to version 2.0 of our LMS.

Web-server:
Our servers are running Linux, so the choice of web-server some years ago was always Apache. But since about 75% of all the content that our servers send is static files we decided to give nginx a try. Nginx is a asynchronous web-server that only runs in one process and serves files with very little footprint or load on the system. Nginx can not serve php-files like Apache can using mod_php, but instead you use fastcgi to execute php-files. The downside with Apache is that every request has it's own process, and every process will load mod_php even if only serving a static file, so every request will use up alot of memory with no advantage. Nginx will (when configured right) instead only proxy the fastcgi when it needs to execute php code.

PHP:
So the choice of nginx required us to execute php through fastcgi, and fortunately php now includes php-fpm that is a fastcgi process manager for php.
Setting up php-fpm is basically like setting up how Apache works. You need to set the number of startup/maximum/minimum processes.
At first I was a bit worried that executing php through nginx/fastcgi/php-fpm would affect the performance, but after setting it up and benchmarking some php scripts, we noticed that the performance was about the same compared to Apache/mod_php.
We also made the choice to use xcache that is set up and optimized for 4 cores that we have on the webserver. Optimizing xcache for several cores using the xcache.count parameter affects the locking of shared memory quite a bit.

Problems with web-server/PHP:
When we started to benchmark our LMS we ran into some problems that are important.

  1. The first problem was that PHP leaks memory, so after running the web-server for a couple of hours we noticed that the php-fpm processes was getting bigger and bigger, so after a while the server started swapping memory that affected the whole system.
    The solution was easy: Just set php-fpm parameter "pm.max_requests" to something like 20 that means that the process will only serve 20 requests and then shut down. Php-fpm will handle this nicely and start a new process if the processes are too few.
  2. When benchmarking under high load, we started to get alot of php errors that turned out to be problems with the database. PHP could not connect to the database anymore giving us some undocumented error code in return.
    We use PHPs PDO to connect to a MySQL-server running on a different server and the error we got turned out to be a error that there where no available ports anymore.
    The solution again was very easy: Just turn on persistent connections to the database. If you do not use persistent connections, the PHP script will connect to the database and make it's requests and then close the connection. But a normal system will still make that TCP port unavailable for another 60 seconds, and since there are only some thousand ports dedicated to this you will eventually run out of ports.
    When we turn on persistent connection, the connection will not close to the database unless the process is killed and that will only happen every 20 request with our configuration. 


Static files:
When we developed the new version of our LMS we made some very good decisions based on previous experience.
We see our static files in different ways:

  1. Shared files: This is files used everywhere and is basically javascript (like jquery, json, uploadify, etc), stylesheets and images.
  2. Uploaded files: In a LMS the administrators upload all the content like documents and SCORM-packages.

Ground rule: NEVER UPDATE STATIC FILES!!
This means that if we make a update on any of the shared files, we make a new revision in a new path. For instance we go from http://example.com/shared/r100/jquery.js to http://example.com/shared/r101/jquery.js if we upgrade jquery.
If the administrators upload any new content, we always update the path to the content like: http://example.com/data/documents/1/mydoc.pdf to http://example.com/data/documents/2/mydoc.pdf
If we follow this rule, we can setup nginx with the setting "expires max" on all our static files. This basically means that if a browser have downloaded the file once, it will not even check to see if the file is updated again and if we update a file, the path change and the browser will see this as a new file to download.
This will also take care of any miss-configured proxy server that doesn't check for updated files as it should. Proxy servers are very good with this aproach, since they can take the load off serving static files.

Rule: Compress appropriate static files.
For our shared file, we have made a script that will go through all the javascript and stylesheets and run minimize on them and then gzip them. So in the "shared" folder there is always both a myscript.js and a myscript.js.gz. Now we can turn on the nginx "gzip_static on" that will check if the browser can handle compressed files. Nginx will then serve the gzipped file instead.

With all this setup I compared the output before and after. Out front page was initially about 850Kb big and included alot of images, stylesheets and javascript. After all this settings the front page went down to 120Kb, and since the static files weren't served again with the "expires max", clicking on a link is very fast since it's only the page itself that needs to be served.
We also have turned on nginxs "gzip on" on out php files.

Bottlenecks:
Our web application is very fast. We have a very well normalized and indexed database running on one backend server and our webapp is developed using Zend Framework. When we make a load test on the LMS the bottleneck actually isn't the database as you normally predict, but instead it's PHP that is the main bottleneck. On maximum load on the web-server (4 cores) the database (1 core) server only has a load of about 1/4 compared to the web-server. We are looking at different approaches to optimize this like trying to optimize the autoloader or maybe even use PHP hip-hop compiler. The problem is not memory on the web-server; there is plenty of memory left and the maximum number of php-fpm processes is never reached under maximum load.

Conclusion:
After optimizing our application, we score 91/100 on the "page speed" firebug plugin. And we have no problems with high load on our servers at all. But it's always fun to optimize webapplications further since I'm a bit allergic to slow webapps :)
Any suggestions on how to optimize this further is appreciated.

2011-02-08

Howto design a webapp C++ MVC API part 2

Doing a MVC implementation that is intuitive in C++ isn't very easy. I'm thinking about how to implement the controllers. Should the controller-class be inherited by the implementations or should it provide some kind of callback/signal-system. For some reason I seem to be against inheriting from the controller, but compared to a signal/slot or similar callbacksystem, this is probably the best and most intuitive option.

So I'm thinking something like this:
-----
// Create a webapp
forumApp myforum;
http_server.add_webapp("forum",myforum); // add the forumApp to the "/forum/"-path
-----
// Looking at the forumApp-class, it inherits the webapp_controller
class forumApp : public webapp_controller{


    // Set up the "sub" controllers in a static method
    static void add_controllers(dispatcher::ptr dispatcher){
        // Add the controller "forumAdministration" to the subpath "/forum/admin/"
        dispatcher->add_controller<forumAdministration>("admin"); 
        // Add the controller "forumThread" to the subpath "/forum/thread/"
        dispatcher->add_controller<forumThread>("thread");
        // Also add actions related to this controller 
        dispatcher->add_action(&forumApp::about,"about");
     }

     void about(connection &con){
         con.send_response("this is the best forumapp ever");
     }
}
-------
So, this is just initial thoughts. Writing about this helps me figure out how code would look like, and who knows, maybe I can catch someones attention.

Next up is how views should work and what type if template-system to use or not to use.