<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wikidot="http://www.wikidot.com/rss-namespace">

	<channel>
		<title>Piotr Gabryjeluk dev blog</title>
		<link>http://piotr.gabryjeluk.pl</link>
		<description>Blog, photos and developer notes of Piotr Gabryjeluk, one of Wikidot.com developers.</description>
				<copyright></copyright>
		<lastBuildDate></lastBuildDate>
		
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:changes-not-really</guid>
				<title>Changes? Not Really</title>
				<link>http://piotr.gabryjeluk.pl/dev:changes-not-really</link>
				<description>

&lt;p&gt;As announced on &lt;a href=&quot;http://blog.wikidot.com/blog:good-morning-wikidot&quot;&gt;Wikidot blog&lt;/a&gt;, CEO of Wikidot.com is changing. The position of CEO of Wikidot has been hold by Pieter Hintjens, now changed by Michał Frąckowiak, the founder of Wikidot service.&lt;/p&gt;
&lt;p&gt;Pieter was the Wikidot front-man for its community and organized good workflow for many community and internal projects. We learned how to talk to the community, how to solve problems and how to concentrate on important things. And we&#039;re going to keep being good at it.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Sun, 28 Feb 2010 17:36:28 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>As announced on <a href="http://blog.wikidot.com/blog:good-morning-wikidot">Wikidot blog</a>, CEO of Wikidot.com is changing. The position of CEO of Wikidot has been hold by Pieter Hintjens, now changed by Michał Frąckowiak, the founder of Wikidot service.</p> <p>Pieter was the Wikidot front-man for its community and organized good workflow for many community and internal projects. We learned how to talk to the community, how to solve problems and how to concentrate on important things. And we're going to keep being good at it.</p> <div class="content-separator" style="display: none:"></div> <p>With the addition of data forms Wikidot becomes one of the most interesting wiki platfarms (platform + farm) on the Earth. Using ListPages, _templates and forms we allow (almost) regular folks to create applications like CMS for their co-workers, clients or friends. Things usually done by programmers are now available for smart guys without need to find proper hosting, web framework or writing a line of computer code.</p> <p>What I find most interesting in building applications on Wikidot is that the platform itself is quite bullet-proof. I mean when you forget to put semicolon at the end of some line, you don't get your application crashing because of syntax error. Moreover when making application you get storage with history and e-mail notifications about changes for free, which makes your data quite safe. In case someone destroys your site (which you are informed by e-mail), you can just revert the right version).</p> <p>But Wikidot applications is not the most important thing Wikidot is used for. Many sites on Wikidot are just plain wiki sites with links to store and share knowledge of certain groups. They don't use advanced features like modules, includes, templates. They usually edit and save :-) from time to time uploading some file or image. What we want to do is to review all common operations people do most often and (really really) simplify them. Sophisticated applications are worth nothing if basic usage of service is not easy.</p> <p>We want to introduce features people will appreciate, like [[html]] blocks for embedding completely custom HTML, like this:</p> <div class="code"> <pre> <code>[[html]] &lt;h1&gt;Custom HTML&lt;/h1&gt; &lt;p&gt;Something else&lt;/p&gt; &lt;img src="anything.png" alt="hello ;-)"/&gt; [[/html]]</code> </pre></div> <p>This code will just inject the HTML (including JavaScript) into the page in that place. Seems easy to do, but in fact, to make it safe for your site, we needed to implement this as a frame, that autoresizes to keep the content fit inside.</p> <p>We also want to introduce [[block]] syntax for sandboxing wiki texts, for example:</p> <div class="code"> <pre> <code>[[block]] What put inside is parsed and rendered independently, so even if you put some random [[/div]]s or other nasty things, the page outside will be rendered nicely. [[/block]]</code> </pre></div> <p>This will be useful for site designers to use in template pages, like this:</p> <div class="code"> <pre> <code>[[table]] [[row]] [[cell]] [[block]] %%content%% [[/block]] [[/cell]] [[cell]] some other things. [[/cell]] [[/row]] [[/table]]</code> </pre></div> <p>Putting %%content%% in block tags you make sure user won't break the original layout (the table). Without block, user could put [[/cell]] inside of his text and thus break the layout.</p> <p>To let our users know what happens on their sites, we want to make live feeds of activity available for most common start-places on the web — iGoogle, NetVibes, Facebook and Twitter. Most important news from YOUR sites will be next to other things you start your day from.</p> <p>We have a bunch of other fresh ideas, which we'll be sharing on <a href="http://blog.wikidot.com/">blog.wikidot.com</a>.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:using-caps-key-as-second-tab</guid>
				<title>Using Caps Key As Second Tab</title>
				<link>http://piotr.gabryjeluk.pl/dev:using-caps-key-as-second-tab</link>
				<description>

&lt;p&gt;As we all know, Caps Lock key is useless and annoying, so some folks change it to behave as third Control key. I prefer using two Controls I already have, so I mapped the Caps Lock key to Tab (which I use very often).&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 23 Dec 2009 13:49:45 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>As we all know, Caps Lock key is useless and annoying, so some folks change it to behave as third Control key. I prefer using two Controls I already have, so I mapped the Caps Lock key to Tab (which I use very often).</p> <div class="content-separator" style="display: none:"></div> <div class="code"> <pre> <code>$ xmodmap - remove Lock = Caps_Lock keycode 0x42 = Tab &lt;hit Ctrl-D now&gt;</code> </pre></div> <p>This works till you logout. If it does work, you can make this persistent by adding those two lines to your empty or missing ~/.Xmodmap file:</p> <div class="code"> <pre> <code>remove Lock = Caps_Lock keycode 0x42 = Tab</code> </pre></div> <p>If this doesn't work for you, it's possible your window manager doesn't take care of this file, but if you have a way to execute commands at each start of GNOME/KDE/whatever, just add the following command to those run it startup sequence:</p> <div class="code"> <pre> <code>xmodmap ~/.Xmodmap</code> </pre></div> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:nowa-strona-nowy-temat</guid>
				<title>Nowa Strona -- Nowy Temat</title>
				<link>http://piotr.gabryjeluk.pl/dev:nowa-strona-nowy-temat</link>
				<description>

&lt;p&gt;Stworzyłem dziś nowy temat do Wikidota będący modyfikacją Łukaszowego Orange-Black:&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 10 Dec 2009 19:09:18 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Stworzyłem dziś nowy temat do Wikidota będący modyfikacją Łukaszowego Orange-Black:</p> <div class="content-separator" style="display: none:"></div> <p style="text-align: center;"><img src="http://thumbnail.s.wdfiles.com/thumbnail/theme/orange-black/240.jpg" alt="240.jpg" class="image" /></p> <p>Oto wynik:</p> <p style="text-align: center;"><img src="http://thumbnail.s.wdfiles.com/thumbnail/theme/orange-black-improved/240.jpg" alt="240.jpg" class="image" /></p> <p>Poza tym co widać, zmiany dotyczą użytego fonta, wyglądu komentarzy i forum, uproszczenia okienka nowego komentarza, ustalenia pozycji tła (żeby przewijanie przewijało samą treść, a nie tło) i dodanie lekkiego prześwitywania tła, żeby było bardziej sexy.</p> <p>Temat jest hostowany pod adresem: <a href="http://themes.wikidot.com/orange-black-improved">http://themes.wikidot.com/orange-black-improved</a>.</p> <p>A wszystko po to, żeby nadać naszej nowej stronce: <a href="http://parapetowa.wikidot.com/">http://parapetowa.wikidot.com/</a> ładnego wyglądu. A na stronce oprócz informacji co można nam kupić z okazji zbliżającej się parapetówy (jeszcze dokładnie nie wiadomo kiedy) uruchomiliśmy też bloga, gdzie pisać będziemy (a przynajmniej ja) o trudzie przystosowania mieszkania do wymagających lokatorów (czyli nas). Link do bloga:</p> <p style="text-align: center;"><a href="http://parapetowa.wikidot.com/blog">http://parapetowa.wikidot.com/blog</a></p> <p>Serdecznie zapraszamy!</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:sobotni-poranek</guid>
				<title>Sobotni Poranek</title>
				<link>http://piotr.gabryjeluk.pl/dev:sobotni-poranek</link>
				<description>

&lt;h1&gt;&lt;span&gt;Co łączy hazard i cenzurę Internetu?&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Przede wszystkim, z rana czytając o ostatnio modnej ustawie anty-hazardowej, zauważyłem, że nie tylko hazard (a i to nie wiem po jaką cholerę) próbuje ona ukrócić. Komentarze pod wpisem na blogu vagla.pl zdają się sugerować, że propozycja ustawy jest niezgodna z Konstytucją, regulacjami Unii Europejskiej i Kartą Praw Człowieka, a wszystko przez to, że nakazuje dostawcom internetu blokować ustalane odgórnie strony internetowe. Centralnym miejscem będzie specjalny Rejestr, do którego będą dopisywane strony o wymienionym w propozycji ustawy charakterze. Dopisywanie ma się odbywać na żądanie kilku organów państwa, a egzekucja tego żądania ma się odbywać natychmiastowo. Dostawcy internetu będą musieli blokować strony z tego rejestru swoim klientom.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Sat, 21 Nov 2009 12:20:26 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <h1><span>Co łączy hazard i cenzurę Internetu?</span></h1> <p>Przede wszystkim, z rana czytając o ostatnio modnej ustawie anty-hazardowej, zauważyłem, że nie tylko hazard (a i to nie wiem po jaką cholerę) próbuje ona ukrócić. Komentarze pod wpisem na blogu vagla.pl zdają się sugerować, że propozycja ustawy jest niezgodna z Konstytucją, regulacjami Unii Europejskiej i Kartą Praw Człowieka, a wszystko przez to, że nakazuje dostawcom internetu blokować ustalane odgórnie strony internetowe. Centralnym miejscem będzie specjalny Rejestr, do którego będą dopisywane strony o wymienionym w propozycji ustawy charakterze. Dopisywanie ma się odbywać na żądanie kilku organów państwa, a egzekucja tego żądania ma się odbywać natychmiastowo. Dostawcy internetu będą musieli blokować strony z tego rejestru swoim klientom.</p> <div class="content-separator" style="display: none:"></div> <p>Zapraszam do przeczytania komentarzy (zarówno prawników, "techników" jak i nietechnicznych, ale zdrowo myślących ludzi) pod następującym adresem:</p> <p><a href="http://prawo.vagla.pl/node/8752">http://prawo.vagla.pl/node/8752</a></p> <p>Komentarze przedstawiają wątpliwości natury technicznej (techniki blokowania będą albo nieskuteczne albo bardzo drogie) jak i prawnej. Znajdziemy również sugestię, że ten rejestr stanie się pierwszym źródłem informacji wśród szukających w Internecie pornografii dziecięcej.</p> <p>Pomijając jednak te "drobne" aspekty, sprawę należy postawić zupełnie inaczej. Czy uprawnione jest w ogóle myślenie o tym, żeby blokować dostęp do części internetu ludziom przybywającym na terenie Polski? Czy zamiast dodawać mechanizmy mające niby uchronić Polaków przed naciągaczami i pedofilami, nie powinniśmy poprawić tych mechanizmów, które już istnieją? Moim zdaniem zamiast żądać dodania strony do Rejestru, odpowiedni urząd powinien złożyć doniesienie o popełnieniu przestępstwa i zostawić prokuraturze i sądom szybkie załatwienie tej sprawy (włącznie z żądaniem zdjęcia jej z sieci). Prokuratura i sądy działają za wolno? No właśnie to jest problem, który należy rozwiązać zamiast zajmować się jakimiś głupimi pomysłami blokowania Internetu!</p> <p>Inny komentator podaje również jako problem wymuszenie stosowania takiego rejestru. O ile rejestry SPAM-u, malware'u i innych nieporządnych stron internetowych (wliczając w to zawierające "nielegalną" pornografię, np. dziecięcą) istnieją, ich używanie jest zupełnie dobrowolne. Jeśli dbam o swoje bezpieczeństwo w sieci, mogę takiego filtra użyć, będąc świadomym, że może mi to ograniczyć dostęp do niektórych serwisów (do których mogę się dostać "omijając" filtr na własne życzenie). Propozycja ustawy jest bezlitosna, dostawcy internetu mają blokować pod rygorem kary pieniężnej.</p> <h1><span>Chwila rozrywki</span></h1> <p>Korzystając z chwilowego braku cenzury w Internecie chciałbym podzielić się filmikiem zaczerpniętym ze strony failblog.org, która prezentuje wypadek rowerzysty.</p> <p><strong>UWAGA: TREŚĆ DRASTYCZNA</strong> (chociaż wydaje mi się, że uczestnik wypadku nie odniósł dużych obrażeń)</p> <p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/XxGGyVklPHg&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;feature=player_embedded&amp;fs=1" /> <param name="allowFullScreen" value="true" /> <param name="allowScriptAccess" value="always" /> <embed src="http://www.youtube.com/v/XxGGyVklPHg&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="425" height="344" /></object></p> <p>I jeszcze jedno, a co!</p> <p><iframe src="http://www.viddler.com/player/bc706765/" width="437" height="288" border="0" frameborder="0"></iframe></p> <p>I jeszcze powiększanie biustu po chińsku (trzeba przyznać, że bardzo pomysłowe, od razu przypomniał mi się Abracada Bra Mossa z IT Crowd):</p> <p><iframe src="http://www.viddler.com/player/a492be30/" width="437" height="351" border="0" frameborder="0"></iframe></p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:home-directory-snapshots</guid>
				<title>Home Directory Snapshots</title>
				<link>http://piotr.gabryjeluk.pl/dev:home-directory-snapshots</link>
				<description>

&lt;p&gt;Your home directory is where the most important data is stored.&lt;/p&gt;
&lt;p&gt;But from time to time you just simply &lt;tt&gt;rm -Rf ~&lt;/tt&gt; and your all precious data is totally out of luck. Backups you say, don&#039;t you?&lt;/p&gt;
&lt;p&gt;So let&#039;s think how do you do backups. &lt;tt&gt;cp /home/quake /my/distant/location&lt;/tt&gt; ? On my 24&amp;nbsp;GB home directory? It would take hours. &lt;tt&gt;cp /home/quake /home/backups/quake/date&lt;/tt&gt; ? Better, this will take a few minutes, but wait, I have like 120&amp;nbsp;GB of disk space, which means I can have no more than 5 backups.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Sun, 25 Oct 2009 16:12:38 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Your home directory is where the most important data is stored.</p> <p>But from time to time you just simply <tt>rm -Rf ~</tt> and your all precious data is totally out of luck. Backups you say, don't you?</p> <p>So let's think how do you do backups. <tt>cp /home/quake /my/distant/location</tt> ? On my 24&nbsp;GB home directory? It would take hours. <tt>cp /home/quake /home/backups/quake/date</tt> ? Better, this will take a few minutes, but wait, I have like 120&nbsp;GB of disk space, which means I can have no more than 5 backups.</p> <div class="content-separator" style="display: none:"></div> <p>What to do with this? There are two posibilities. Either you minimize data to backup to only backup important data (but figuring out what data is important may take some time and be inappropriate) or move to smarter solution, like incremental backups. Or snapshots.</p> <p>Having brtfs as the filesystem for my home directory, I chose to make a snapshot of it each hour. It takes between 0 and 1 second to complete and uses almost no disk space. Why? Btrfs is copy-on-write filesystems, which means cloning a filesystems is instant as it only makes it available under two locations. And then modifying one of the two makes a real copy of the modified fragment of it and changes that copy.</p> <p>OK. How to do it.</p> <p>First create a btrfs filesystem (you'll need a recent kernel and btrfs-utils):</p> <div class="code"> <pre> <code># mkfs.btrfs /dev/sda7</code> </pre></div> <p>(sda7 is partition for my /home directory)</p> <p>Then mount it somewhere else than /home, let's use /vol as an example:</p> <div class="code"> <pre> <code># mount /dev/sda7 /vol</code> </pre></div> <p>Create some volumes on that filesystem: home, quake, snapshots:</p> <div class="code"> <pre> <code># btrfsctl -S home /vol # btrfsctl -S quake /vol # btrfsctl -S snapshots /vol</code> </pre></div> <p>The volumes are accessible as the subdirectories of /vol:</p> <div class="code"> <pre> <code># ls -la /vol drwx------ 1 root root 36 1970-01-01 01:00 . drwxr-xr-x 24 root root 4096 2009-10-25 15:04 .. drwx------ 1 root root 20 2009-10-25 15:51 home drwx------ 1 root root 11488 2009-10-25 16:17 quake drwx------ 1 root root 76 2009-10-25 15:40 snapshots</code> </pre></div> <p>But you can mount then separately:</p> <div class="code"> <pre> <code># mount /dev/sda7 /home -o subvolume=home # mkdir /home/quake # mount /dev/sda7 /home/quake -o subvolume=quake</code> </pre></div> <p>Fix permissions:</p> <div class="code"> <pre> <code># chown quake:quake /home/quake /vol/quake /vol/snapshots # chmod 0755 /home/ /home/quake</code> </pre></div> <p>Now you're ready to do snapshots. Now populate the /home/quake directory:</p> <div class="code"> <pre> <code>$ mkdir /home/quake/abcd $ mkdir /home/quake/dddd $ mkdir /home/quake/abcd/eeee $ echo testtest &gt; /home/quake/testfile</code> </pre></div> <p>Aaaaaand, make snapshots!</p> <div class="code"> <pre> <code>$ btrfs -s /vol/snapshots/quake-`date +%Y%m%d-%H%M` /vol/quake</code> </pre></div> <p>I figured out, that it's quite important to point to /vol/quake and not /home/quake. At first it seams that it's totally the same, but on /home/quake there can be some other filesystems mounted (like .gvfs for GNOME virtual file systems) and /vol/quake contains "pure data". When doing snapshots of /home/quake with filesystems mounted under it, the filesystems freezes for me (btrfs is still experimental, they say). So as noted above, it's better to snapshot pure data directory.</p> <p>Now, the /vol/snapshots/quake-20091025-1653 (or whatever your date is) and /vol/quake should list the same files and the operation of "cloning" should be just instant no matter how much data you have. But now modifying the contents of /vol/quake should not change anything in /vol/snapshots/quake-20091025-1653 (but of course should in /home/quake).</p> <p>Also the snapshot doesn't really take any disk space as long as you keep the /vol/quake directory unchanged. Once you change some file from /vol/quake, it needs to really keep two copies of it, so this is when additional space is allocated.</p> <p>To sum up let's have a table listing possibilities to have the same contents in two directories:</p> <table class="wiki-content-table"> <tr> <th>method</th> <th>file copy</th> <th>symbolic link</th> <th>hard link</th> <th>bind-mount</th> <th>btrfs' clone</th> </tr> <tr> <th>how</th> <td>cp -a dir1 dir2</td> <td>ln -s dir1 dir2</td> <td>ln dir1 dir2</td> <td>mount -o bind dir1 dir2</td> <td>btrfs-bcp dir1 dir2</td> </tr> <tr> <th>time</th> <td>long</td> <td><strong>instant</strong></td> <td><strong>instant</strong></td> <td><strong>instant</strong></td> <td><strong>instant</strong></td> </tr> <tr> <th>takes disk space</th> <td>yes</td> <td><strong>no</strong></td> <td><strong>no</strong></td> <td><strong>no</strong></td> <td><strong>no</strong> (only the difference)</td> </tr> <tr> <th>points to the same data<br /> (changing file in dir1 changes it in dir2)</th> <td><strong>no</strong></td> <td>yes</td> <td>yes</td> <td>yes</td> <td><strong>no</strong></td> </tr> <tr> <th>notes</th> <td></td> <td></td> <td>not on Linux (Mac only?)</td> <td></td> <td>btrfs-bcp not distributed in Ubuntu's btrfs-tools</td> </tr> </table> <p>More notes on btrfs and snapshotting:</p> <ul> <li>What can be done with btrfs-bcp on directories level can be done with snapshots on volumes level (as described in this post)</li> <li>Snapshots in btrfs are not removable yet. You can clear them and reclaim the space taken by saved difference from the starting point. Still a few bytes is taken by having the directory that is not removable. Deleting snapshots is to be implemented in stable version of btrfs.</li> </ul> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:0x600df00d</guid>
				<title>0x600DF00D</title>
				<link>http://piotr.gabryjeluk.pl/dev:0x600df00d</link>
				<description>

&lt;p&gt;Ta notka powstaje z dwóch powodów.&lt;/p&gt;
&lt;p&gt;Po pierwsze obiecałem, że napiszę coś na blogasku, jeśli będzie mi się dzisiaj podobać.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 07 Oct 2009 19:44:35 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Ta notka powstaje z dwóch powodów.</p> <p>Po pierwsze obiecałem, że napiszę coś na blogasku, jeśli będzie mi się dzisiaj podobać.</p> <div class="content-separator" style="display: none:"></div> <p>Po drugie, muszę oddać hołd mojemu dziewczęciu — Marcie.</p> <p>Marto, jesteś bardzo dobrze przewidującą osobą. Przewidziałaś dwa wydarzenia w Californication (na dwa strzały — 100% skuteczności).</p> <p>Poza tym, lepiej znasz kolekcję moich płyt niż ja. Tak, mam w niej płytę Rapid Eye Movement naszego kochanego Riverside'u.</p> <p>Cieszę się, że jesteśmy razem.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:ssd-fses-benchmark-results</guid>
				<title>SSD FS-es Benchmark Results</title>
				<link>http://piotr.gabryjeluk.pl/dev:ssd-fses-benchmark-results</link>
				<description>

&lt;p&gt;As I &lt;a href=&quot;http://piotr.gabryjeluk.pl/dev:file-systems-on-solid-state-drives-benchmark&quot;&gt;promised&lt;/a&gt; I benchmarked some of the Linux filesystems on my solid state disk.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Fri, 02 Oct 2009 17:39:53 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>As I <a href="http://piotr.gabryjeluk.pl/dev:file-systems-on-solid-state-drives-benchmark">promised</a> I benchmarked some of the Linux filesystems on my solid state disk.</p> <div class="content-separator" style="display: none:"></div> <h1><span>Introduction</span></h1> <p>I wanted to benchmark the following filesystems:</p> <ul> <li>ext2, ext3</li> <li>ext4</li> <li>xfs</li> <li>reiserfs, reiser4</li> <li>nilfs</li> <li>btrfs</li> <li>zfs (via fuse)</li> </ul> <p>NILFS2 haven't managed to even finish the Bonnie++ test. This means this filesystem is not yet ready to use (but promises very nice features). Other filesystem that has not been benchmarked is reiser4, because the Ubuntu kernel doesn't have support for it. I would need to patch it and I wasn't happy about it.</p> <p>Images shown here show results of the standard Bonnie++ tests. Command to do them was:</p> <div class="code"> <pre> <code>bonnie -d /dir/on/ssd/partition -n 200:200</code> </pre></div> <p>The -n parameter was tuned so that for each test some values were returned. With default setting I got many values "++++" indicating test was performed so fast, that Bonnie++ was not able to calculate the performance.</p> <p>Explanation of test names can be found in <a href="http://www.coker.com.au/bonnie++/readme.html">bonnie++ documentation</a>.</p> <p>Before each test, filesystem was created on the prepared partition (25&nbsp;GB) and some (the same for each test) data was copied to it (about 10&nbsp;GB) to simulate "used" filesystem.</p> <p>As it appeared I was not able to <em>disable</em> write-caching with running hdparm -W0 /dev/sda. Instead it stated</p> <div class="code"> <pre> <code>/dev/sda: setting drive write-caching to 0 (off) write-caching = 1 (on)</code> </pre></div> <p>Possible write-caching is good thing though (and by default enabled), so I have no problem with that.</p> <p>All tests were run twice, but the results was nearly the same, so I just removed the second results for each filesystem.</p> <p><strong>For each test, bigger is better with value being thousands operations per second.</strong></p> <h1><span>The best filesystem</span></h1> <p>As some suggest, the preferred I/O-scheduler for SSD disk is "noop", which means there's no IO scheduling in kernel, so we rely on scheduling logic in the hardware (which for various reasons is believed to be good in SSD disks) and profit from no software overhead of queuing.</p> <p>Let's then compare how well filesystems perform with this scheduler chosen:</p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/noop-tests1.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/noop-tests1.png/small.jpg" alt="noop-tests1.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/noop-tests2.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/noop-tests2.png/medium.jpg" alt="noop-tests2.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/noop-tests3.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/noop-tests3.png/medium.jpg" alt="noop-tests3.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/noop-tests4.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/noop-tests4.png/medium.jpg" alt="noop-tests4.png" class="image" /></a></p> <p>This benchmark was performed for all filesystems but NILFS2 and reiser4.</p> <h2><span>Random seeks</span></h2> <p>When it comes to random seeks (very important for low-latency systems), the best is ext4 with reiserfs and xfs having almost the same result. Btrfs is next (10% slower), then ext3, ext2 and zfs at the end being 6 time worse than the best.</p> <h2><span>Creation and deletion of files</span></h2> <p>Ext4 is the fastest in creating files (both sequentially and randomly) while btrfs is the fastest in deleting files, which small exception of ext2 being 7 times faster than everything in sequentially deleting files. On the other hand it's ability to delete files in random fashion is pretty bad. Comparing only btrfs and ext4, both are fast, the difference is about 10% to the one or the other side. Ext3 performs pretty well in this test, reiserfs reaches about half the performance of ext4/btrfs, while xfs and zfs are really slow.</p> <h2><span>Read/write</span></h2> <p>Reading and writing of data is pretty equal through filesystems in terms of benchmark results. The worst results has zfs and ext2 (especially in random read, which is vital in modern use of computers).</p> <p>As per-character reading/writing is not so important, let's concentrate on the rest of tests. As you can see, btrfs is clearly the best, having first place in 3/5 tests being really close to first in the following two. Reiserfs and ext4 perform really well in this area.</p> <h2><span>Semi-summary</span></h2> <p>At this point it's clear that when it comes to performance on SSD disk we have two filesystems to consider the best: btrfs and ext4. Reiserfs is slightly worse, but the most mature from them. Xfs and ext3 are just OK, but don't perform equally good in all tests, while ext2 and zfs (on fuse) being not an option at all.</p> <p>Let's then compare the features of the three:</p> <table class="wiki-content-table"> <tr> <th>Limits</th> <th>reiserfs</th> <th>ext4</th> <th>btrfs</th> </tr> <tr> <td>file name</td> <td>4&nbsp;KB</td> <td>256&nbsp;B</td> <td>255&nbsp;B</td> </tr> <tr> <td>max file size</td> <td>8&nbsp;TB</td> <td>16&nbsp;GB to 16&nbsp;TB<br /> (depends on block size)</td> <td>16 EB</td> </tr> <tr> <td>max volume size</td> <td>16&nbsp;TB</td> <td>1 EB</td> <td>16 EB</td> </tr> <tr> <th>Features</th> <th>reiserfs</th> <th>ext4</th> <th>btrfs</th> </tr> <tr> <td>checksum (error check)</td> <td>no</td> <td>yes</td> <td>yes</td> </tr> <tr> <td>snapshots (like time machine)</td> <td>no</td> <td>no</td> <td>yes</td> </tr> <tr> <td>mirroring/stripping on FS layer</td> <td>no</td> <td>no</td> <td>yes</td> </tr> <tr> <td>compression</td> <td>no</td> <td>no</td> <td>yes</td> </tr> </table> <p>So it seems, btrfs is full of new features compared to (old) reiserfs and (new) ext4 with only small performance penalty in some areas, while even being faster in some.</p> <p>The rest tests presented only cover ext4, reiserfs and btrfs filesystems.</p> <h1><span>What is the best scheduler, then?</span></h1> <p>Having chosen the best filesystems, let's see, which scheduler works best.</p> <h2><span>ext4</span></h2> <p>Comparison of schedulers performance for ext4 filesystem:</p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/ext4-tests1.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/ext4-tests1.png/small.jpg" alt="ext4-tests1.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/ext4-tests2.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/ext4-tests2.png/medium.jpg" alt="ext4-tests2.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/ext4-tests3.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/ext4-tests3.png/medium.jpg" alt="ext4-tests3.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/ext4-tests4.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/ext4-tests4.png/medium.jpg" alt="ext4-tests4.png" class="image" /></a></p> <p>As we see, cfq is the best in 5 tests, significantly worse in two (random creation of files and random seeks) and nearly as good as best in the rest. Deadline and noop perform pretty the same (with noop being better at creating files randomly and deadline being better at creating files sequentially).</p> <h2><span>reiserfs</span></h2> <p>Schedulers performance for reiserfs filesystem:</p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/reiserfs-tests1.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/reiserfs-tests1.png/small.jpg" alt="reiserfs-tests1.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/reiserfs-tests2.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/reiserfs-tests2.png/medium.jpg" alt="reiserfs-tests2.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/reiserfs-tests3.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/reiserfs-tests3.png/medium.jpg" alt="reiserfs-tests3.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/reiserfs-tests4.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/reiserfs-tests4.png/medium.jpg" alt="reiserfs-tests4.png" class="image" /></a></p> <p>For reiserfs, again, cfq does its work really well with only random reads being significantly slower than deadline and noop schedulers.</p> <h2><span>btrfs</span></h2> <p>Let's now see what scheduler will be best for btrfs filesystem:</p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/btrfs-tests1.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/btrfs-tests1.png/small.jpg" alt="btrfs-tests1.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/btrfs-tests2.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/btrfs-tests2.png/medium.jpg" alt="btrfs-tests2.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/btrfs-tests3.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/btrfs-tests3.png/medium.jpg" alt="btrfs-tests3.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/btrfs-tests4.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/btrfs-tests4.png/medium.jpg" alt="btrfs-tests4.png" class="image" /></a></p> <p>This time not cfq, but deadline scheduler is the man! In random seeks, where cfq is generally worse, this time it's worse by about 30% than the best: deadline scheduler. Only in one test deadline is worse than noop, but this is only slight difference. Cfq is only slightly better in 4 tests, but in the rest, deadline is better.</p> <h1><span>Ultimate comparison of btrfs, reiserfs and ext4</span></h1> <p>When we know which scheduler will run best with certain filesystems, let's compare Bonnie++ results for the perfect tandems:</p> <ul> <li>btrfs with deadline scheduler on underlying disk</li> <li>ext4 with cfq</li> <li>reiserfs with cfq</li> </ul> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/best-tests1.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/best-tests1.png/small.jpg" alt="best-tests1.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/best-tests2.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/best-tests2.png/medium.jpg" alt="best-tests2.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/best-tests3.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/best-tests3.png/medium.jpg" alt="best-tests3.png" class="image" /></a></p> <p style="text-align: center;"><a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/best-tests4.png"><img src="http://piotr.gabryjeluk.pl/local--resized-images/dev:ssd-fses-benchmark-results/best-tests4.png/medium.jpg" alt="best-tests4.png" class="image" /></a></p> <h2><span>Random seeks</span></h2> <p>Choosing cfq scheduler on any of the tested filesystems degraded random seek performance. This is why btrfs with deadline scheduler is better than its competitors.</p> <h2><span>Creation and deletion of files</span></h2> <p>This time, without ext2 having so high bar, you can see the differences in creating and deleting files on the three filesystems I tested. Btrfs is much (about 2 times) faster than ext4 in deleting files, while ext4 is a bit faster in creating files randomly, and significantly faster (about 50%) in creating files sequentially. Reiserfs is about 2 times slower than the slower filesystem in each test.</p> <h1><span>Read/write</span></h1> <p>In read/write tests btrfs, ext4 and reiserfs perform almost equally well, with btrfs being slightly better than the latter two filesystems.</p> <h1><span>Summary</span></h1> <p>Ext4 and btrfs filesystems perform really well on SSD disks making the users really happy about the speed they get from normal computer use.</p> <p>With ext4 being the default filesystem for Ubuntu 9.10, having SSD disk, you'll notice that it boots really fast:</p> <ul> <li>from Grub to GDM in 8 seconds</li> <li>from GDM to GNOME in 5 seconds</li> <li>OpenOffice launches the first time in 2-3 seconds (second time is 0 seconds)</li> </ul> <p>With btrfs being equally fast (or even faster) than ext4 it's amazing what features it delivers:</p> <ul> <li>snapshots (you can make a snapshot of filesystem and then roll back to it, or just explore historical version files)</li> <li>compression</li> <li>mirroring/stripping — things usually done on block-device level now incorporated into filesystem</li> <li>nice internal structures and algorithms (copy on write, B-trees, …)</li> <li>integrated volume management</li> </ul> <p>On the second hand, btrfs as of version 0.19 has still experimental disk format, which means it can be non-compatible with future kernels, but usually kernel developers create code that either preserve the old format or converts the filesystem to new one on the first mount (and then it's not possible to mount such a partition from an older kernel). Also if I understand well, the biggest changes from 0.18 to 1.0 were just applied in 0.19, so probably this will be the final format of btrfs partitions.</p> <p>It's clear, that btrfs is the Linux answer to Sun's ZFS, which due to incompatible license can't be incorporated into the kernel (this is why we only have FUSE port available).</p> <p>Having all this said, it's time for me to migrate my /home (and maybe the system partition too) to btrfs!</p> <p>You can download <a href="http://piotr.gabryjeluk.pl/local--files/dev:ssd-fses-benchmark-results/ssd-benchmark.ods">raw benchmark data in ODS format</a>.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:informacja-pks</guid>
				<title>Informacja PKS</title>
				<link>http://piotr.gabryjeluk.pl/dev:informacja-pks</link>
				<description>

&lt;p&gt;Zgłoszone poprzez: &lt;a href=&quot;http://www.pks.bydgoszcz.pl/kontakt.php?pom=3&quot;&gt;http://www.pks.bydgoszcz.pl/kontakt.php?pom=3&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 01 Oct 2009 11:55:43 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Zgłoszone poprzez: <a href="http://www.pks.bydgoszcz.pl/kontakt.php?pom=3">http://www.pks.bydgoszcz.pl/kontakt.php?pom=3</a></p> <div class="content-separator" style="display: none:"></div> <blockquote> <p>Szanowni Państwo,</p> <p>chciałbym zgłosić reklamację dotyczącą pracy informacji telefonicznej PKS Bydgoszcz.</p> <p>Dnia 30 września 2009 pomiędzy godziną 23:40 a 23:55 znajdując się na dworcu autobusowym w Bydgoszczy, wykonaliśmy z telefonu komórkowego połączenie do informacji — nr *720-84-00. Zapytanie dotyczyło najwcześniejszego połączenia z dworca w Bydgoszczy do Torunia. Mężczyzna poinformował nas, że najbliższe takie połączenie będzie dopiero po godzinie szóstej dnia następnego, co było nieprawdą. Nabliższe połączenie z owego dworca było bowiem o godzinie 23:55 (wykonywane przez PKS Mława, ze stanowiska nr 12 na dworcu autobusowym w Bydgoszczy), a następne o godzinie 01:40 (do Łodzi przez Toruń, ze stanowiska nr 11 na dworcu autobusowym w Bydgoszczy).</p> <p>Połączenie telefoniczne kosztowało 5 złotych, o którym to koszcie nie było żadnej informacji na naklejce na szybie na wejściu do budynku dworca. Takiej informacji nie ma różnież na stronie internetowej PKS Bydgoszcz pod adresem: <a href="http://www.pks.bydgoszcz.pl/kontakt.php">http://www.pks.bydgoszcz.pl/kontakt.php</a> .</p> <p>Koszty poniesione w wyniku wprowadzenia w błąd, to 5 złotych (czyli koszt telefonu na informację), zszargane nerwy i stanie na chłodzie przez ponad godzinę. Koszty mogły być znacznie większe, gdybyśmy na podstawie przekazanych informacji zdecydowali się nocować w Bydgoszczy lub wynająć inny środek transportu.</p> <p>Aby sprawę zakończyć polubownie, proponuję zwrot kosztów poniesionych na wykonanie połączenia, oraz wyciągnięcie konsekwencji co do osoby, która wprowadziła nas, czym wpłynęła na znaczne pogorszenie postrzegania przez nas Firmy.</p> <p>W sprawie zwrotu poniesionych kosztów (podamy numer konta), proszę skontaktować się na podany w formularzu kontaktowym adres e-mail.</p> <p>Treść zażalenia będzie dostępna również pod adresem: <a href="http://piotr.gabryjeluk.pl/dev:informacja-pks">http://piotr.gabryjeluk.pl/dev:informacja-pks</a> do czasu uzyskania odpowiedzi, która będzie objawem zajęcia się tą sprawą.</p> <p>Z góry dziękuję za pozytywne rozpatrzenie wniosku.</p> </blockquote> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:cleaning-up</guid>
				<title>Cleaning Up</title>
				<link>http://piotr.gabryjeluk.pl/dev:cleaning-up</link>
				<description>

&lt;p&gt;Some of you, following Wikidot code on &lt;a href=&quot;http://github.com/gabrys/wikidot&quot;&gt;GitHub&lt;/a&gt; may see it&#039;s nicely split into templates, php, web and conf directories. But this is the first impression.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 17 Sep 2009 16:42:53 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Some of you, following Wikidot code on <a href="http://github.com/gabrys/wikidot">GitHub</a> may see it's nicely split into templates, php, web and conf directories. But this is the first impression.</p> <div class="content-separator" style="display: none:"></div> <p>Maintaining Wikidot is a bit more complex, because, files uploaded to sites are located in web, side to side with some static Wikidot php and javascript files. Also for historical reasons, there are web/files--common and web/files--local directories, which maps to /common--* and /local--* URLs and in fact, the files--local is never served directly by the web server (need to check permissions first).</p> <p>Also some time ago, we made static files versioned, so that we can apply more aggressive HTTP caching to them (reducing average page load time) and still be able to fix bugs on them without waiting a few days till the cache expire. In current model, URL to static file contains version hash, this may be for example: <a href="http://static.wikidot.com/v--b44e0ce810ee/common--javascript/WIKIDOT.js">http://static.wikidot.com/v--b44e0ce810ee/common--javascript/WIKIDOT.js</a> (notice the b44e0ce810ee). The whole static.wikidot.com is now hosted on Amazon's CloudFront, which means you get static Wikidot files from a server nearby your location and not always from USA.</p> <p>This all become quite complicated, so we decided to make things really clear and simple in the source code. The primary rule: make the source code (updatable from git) separate from files uploaded by users and generated by Wikidot. Second rule: make files that are automatically generated during installation (not in the runtime) separate from persistent files (like the uploaded by users) and from source code.</p> <p>And at the end there needs to be some place for logs and a place for temporary data (we need this to generate some random cool stuff, but after generating them, files are deleted).</p> <p>So we end up with something like this:</p> <ul> <li>WIKIDOT_ROOT <ul> <li><strong>data/</strong> <ul> <li>avatars/ — user avatars</li> <li>sites/ — site files (both generated thumbnails and uploaded files)</li> </ul> </li> <li><strong>generated/</strong> <ul> <li>static/ — generated static files. This dir can be server directly by a fast non-PHP webserver for static.wikidot.com in case we don't want CloudFront anymore</li> </ul> </li> <li><strong>tmp/</strong> — temporary files including Smarty compiled versions of templates. Content of this dir can be safely removed</li> <li><strong>logs/</strong> — Wikidot logs</li> <li>everything else — comes from git and is unchangeable by application</li> </ul> </li> </ul> <p>Application needs write-access to data, tmp and logs. Generated dir needs write access to one installing or upgrading application.</p> <p>Wikidot persistent data is now ONLY database and data/ directory, so it's easy to backup and restore the application (if you have enough time to make full backup of this).</p> <p>There is still one exception to this nice schema which is php/db/base directory, which is autogenerated during installation from XML database definition files, but the cleaning is not over, I still work on this.</p> <p>Nice thing about this work is that it does not need a lot of code changing, because directory paths are usually stored in one (max two) places in application, so this kind of totally reorganizing directory structure does not break things. As such, it is very very worth doing it. In the end we get clean internal structure of files and it's clear which files you can safely remove, which you can restore from git (and thus you can experiment a little on them — in case of crash, just re-download application), which are "state" of the Wikidot and where to look for logs.</p> <p>This all is also very important, because we aim to make current Wikidot.com source open and as such we want it to be a nice code.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:file-systems-on-solid-state-drives-benchmark</guid>
				<title>File Systems On Solid State Drives Benchmark</title>
				<link>http://piotr.gabryjeluk.pl/dev:file-systems-on-solid-state-drives-benchmark</link>
				<description>

&lt;p&gt;Recently I bought a solid state hard disk for my laptop. All have heard that SSDs are faster and better, and help booting your OS faster. While it&#039;s all true, you need to face a fact, that no mature file system available for Linux is ready (optimized) for SSDs.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Sun, 13 Sep 2009 20:57:40 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Recently I bought a solid state hard disk for my laptop. All have heard that SSDs are faster and better, and help booting your OS faster. While it's all true, you need to face a fact, that no mature file system available for Linux is ready (optimized) for SSDs.</p> <div class="content-separator" style="display: none:"></div> <p>During last 20 years, file system (and kernel-side logic like write schedulers and disk buffers) were made to optimize use of hard disks — magnetic hard disks. The disks are now quite fast when you read or write 1&nbsp;GB file from them, but when you need to read 2000 small files that are located in different physical locations of the disk, their performance degrades.</p> <h1><span>Rotating disks</span></h1> <p>For the years, many developed systems (both software and hardware) to make as little disk seeks as possible. I've heard there are optimizations in kernel like: if you need to read a block that is 20 sectors after current position, don't seek, read the 19 useless sectors, and then read the meaningful one. I don't know if this is true and if yes, is this optimization of Linux kernel or some particular file system.</p> <h1><span>Solid State Drives</span></h1> <p>OK, so the file systems out there perform really well on rotating magnetic disk drives. So what about the solid state non-rotating disks. Are the previously talked optimizations good for them too? No. Solid state drives are not <em>as fast as</em> magnetic disks for sequential reads and writes, but they are much much better in random access to data. The seek time is approximately 0 (actually much less than 0.1&nbsp;ms, when magnetic disks have the seek time about 5&nbsp;ms).</p> <h1><span>SSD + File Systems?</span></h1> <p>On the other hand, there are quite a few new file systems that are meant to be run on SSD disks or at least are SSD-aware. I'm talking about <a href="http://www.nilfs.org">NILFS2</a> and <a href="http://btrfs.wiki.kernel.org">btrfs</a>. Unfortunately neither of them is stable in the sense of on-disk data format. This means that partitions created with current version of NILFS or btrfs may not be readable by future versions of these file systems. Thus it's not too nice to have important data on them.</p> <h1><span>Looking for a benchmark</span></h1> <p>So this is time when I have my expensive SSD in my hand and face serious problem of choosing the right file system to keep my data secure and fast to access. I searched for some benchmarks to compare the results of different file systems, both the old XFS, ReiserFS, ext2/3, the new ext4 and SSD-optimized btrfs and NILFS2. The number of benchmarks of these filesystems on SSD drives I found is 0. So time to make my own benchmark.</p> <h1><span>My benchmark</span></h1> <p>I want to benchmark the following file systems:</p> <ul> <li>ext2, ext3</li> <li>ext4</li> <li>xfs</li> <li>reiserfs, reiser4</li> <li>nilfs</li> <li>btrfs</li> <li>zfs (via fuse)</li> </ul> <p>I will use my new OCZ Agility 120&nbsp;GB SSD disk for this.</p> <p>As this option is used even for magnetic disks, I will append noatime to mount options for every file system I check.</p> <p>Also, I will try the following tweaks as suggested by random sites:</p> <ul> <li>using noop scheduler for disk IO: <tt>echo noop &gt; /sys/block/sdb/queue/scheduler</tt></li> <li>turning on and off write-back caching: <tt>hdparm -W1 /dev/sda</tt>, <tt>hdparm -W0 /dev/sda</tt></li> <li>discourage swapping (so that app data is kept in RAM and is not replaced with disk buffers, reading from SSD is damn fast anyway): <tt>sysctl -w vm.swappiness=1</tt></li> </ul> <p>For each setting, I'll make a test with bonnie++. I'll try to make nice graphs out of the data.</p> <p>If you want me to test more settings or file systems or have some suggestion about the benchmarking tools, feel free to leave a comment.</p> <p><strong>UPDATE:</strong> I will also perform one more test: time of launching Firefox, Claws Mail and Pidgin from encfs-encrypted .mozilla, .purple and .claws-mail directories with different underlying file systems. This is very common task for me (they all start automatically after logging in).</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:problemy-z-netia</guid>
				<title>Problemy z Netią</title>
				<link>http://piotr.gabryjeluk.pl/dev:problemy-z-netia</link>
				<description>

&lt;p&gt;Dzisiaj rano ku mojemu zdziwieniu nie mogłem pobrać poczty z mojego serwera. Pomyślałem, że nie działa internet, ale działa. Druga myśl, serwer padł. O nie! Ale serwer działa (sprawdzone z serwera w firmie). Sprawdziłem jeszcze szybko inny serwer w naszej serwerowni i też nie działał. No to jasna sprawa, szybki tracepath i potencjalnie wadliwy router namierzony.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Fri, 04 Sep 2009 09:27:57 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Dzisiaj rano ku mojemu zdziwieniu nie mogłem pobrać poczty z mojego serwera. Pomyślałem, że nie działa internet, ale działa. Druga myśl, serwer padł. O nie! Ale serwer działa (sprawdzone z serwera w firmie). Sprawdziłem jeszcze szybko inny serwer w naszej serwerowni i też nie działał. No to jasna sprawa, szybki tracepath i potencjalnie wadliwy router namierzony.</p> <div class="content-separator" style="display: none:"></div> <p>Dzwonię czym prędzej do Netii, aby zgłosić mój problem, ale wpierw muszę zaktualizować swoje dane (które nie zmieniły się od początku trwania umowy). Więc podaję swój numer komórkowy i e-mail i już, już prawie szczęśliwy, że mogę opowiedzieć na czym polega problem zaczynam, aby dowiedzieć się, że:</p> <ul> <li>działa panu internet, a jakaś strona nie, to nie nasz problem</li> <li>pewnie ma pan wirusy (a może bakterie?)</li> <li>rozmawiam z osobą, która WIE co to jest PING, TRACEPATH i ROUTER, ale nie potrafi odpowiedzieć na prośbę:</li> </ul> <blockquote> <p>Czy mógłbym prosić, aby powiedziała mi Pani do jakiego adresu IP rozwiązuje się nazwa hetzner.de</p> </blockquote> <p>(Odpowiedzią na to pytanie było: ale Pan nie ma stałego IP i dlatego Pana nie widzę)</p> <p>Poprosiłem, aby kobieta zapingowała adres, który mi nie działa i niby jej działa. No to może faktycznie problem u mnie jakiś. Zrestartuję swój router i zobaczymy.</p> <p>Poprosiłem w międzyczasie Slafsa, który jeden z serwerów w firmie ma podpięty do internetu przez Netię, ażeby zapingował dla mnie hetzner.de i również nie dostał odpowiedzi, a tracepath zatrzymał się na tym samym hopie.</p> <p>Zadzwoniłem zatem drugi raz na infolinię. Tym razem odebrał mężczyzna. O niebo wolę rozmawiać o takich rzeczach z przedstawicielami tej samej płci. Przedstawiłem mu problem przekazując jak najmniej szczegółów. Zapytał jaki komunikat otrzymuję gdy próbuję otworzyć tę stronę. Powiedziałem, że próbuję zapingować ten serwer (co działa z internetu TPSA) i nie dostaję odpowiedzi, a gdy uruchamiam tracepath, to pakiet zatrzymuje się na konkretnym routerze. Dodałem, że problem dotyczy również innych serwerów w tej serwerowni i usłyszałem klarowne i oczekiwane:</p> <blockquote> <p>Rozumiem</p> </blockquote> <p>To było mocne. Kwintesencja męskiej komunikacji w jednym słowie. Po chwili dodał, że sprawdzi i pochwili wrócił do telefonu i powiedział, że jest problem (!), że wystawi zgłoszenie i sprawdzą, czy jest to problem masowy. Hurra!</p> <p>Będę mógł się podłączyć do jabberpl.org, żeby zalogować się do jabbera (jednego z kilku kont). Będę mógł sprawdzić pocztę nie korzystając z proxy SOCKS. Będę mógł zobaczyć stronę hetzner.de!</p> <p>Może to nieuczciwe, ale uważam, że kobiety nie powinny rozmawiać z klientami takimi jak ja. Następnym razem jak odbierze kobieta odkładam słuchawkę i próbuję natrafić na faceta :).</p> <p>Jeszcze naszła mnie refleksja, że dobrze byłoby widzieć aktualne problemy, które są znane pracownikom Netii i nad którymi pracują. Dobrym przykładem jest tutaj strona toruńskiego dostawcy internetu:</p> <p><a href="http://www.man.torun.pl/index.php?mod=tickets">http://www.man.torun.pl/index.php?mod=tickets</a></p> <p>Gdyby takie zestawienie było dostępne na stronach Netii, mógłbym śledzić na bieżąco rozwój wydarzeń. Scenariusz wydarzeń od rana mógłby wyglądać wtedy tak:</p> <ul> <li>nie działa mi poczta</li> <li>patrzę na stronach Netii, czy jest jakiś błąd</li> <li>nie ma błędu, to sobie patrzę, czy to mój problem</li> <li>nie jest to mój problem, więc dzwonię do Netii i zgłaszam</li> <li>w Netii aktualizują tę stronę jeśli uznają, że to faktycznie jest ich problem</li> <li>widzę, że to zrobili, czyli pracują nad tym (przynajmniej tak sobie myślę)</li> <li>za jakiś czas jest aktualizacja, że wymienili router gdzieś tam i, że będzie działać za godzinę</li> <li>za godzinę działa, problem na stronie przechodzi do archiwum</li> </ul> <p>Tutaj pojawia się wniosek taki sam jak z naszego ostatniego zepsucia się Wikidota:</p> <ul> <li>Ludzie nie są bardzo wkurzeni, że coś od czasu do czasu nie działa. Awarie się zdarzają</li> <li>Ludzie są wkurzeni, jak nie wiedzą dlaczego coś nie działa</li> <li>Ludzie są wkurzeni, gdy wiedzą, że jest awaria, a nikt nie chce im tego przyznać</li> </ul> <p>Jak poradziliśmy sobie z tym w przypadku Wikidota? Gdy usługa nie działała, uruchomiliśmy statyczną stronę HTML z opisem awarii (dość szczegółowym) i postępów w jej usuwaniu. Po awarii napisaliśmy co zrobimy, gdy zdarzy się coś podobnego w przyszłości. Ludzie szczęśliwi, bo wiedzą, że potrafimy rozwiązywać poważne problemy, więdzą, że nawet jak będzie awaria, to ich dane są bezpieczne, więdzą, że Wikidot nie zniknie ot tak pewnego dnia. Trochę są smutni, że dzisiaj Wikidot nie działa, ale się cieszą, że będzie działał jutro.</p> <p>I jeszcze mała ciekawostka:</p> <p><a href="http://www.wykop.pl/link/231750/sensacja-ipv6-powstaje-w-polsce-rotfl">IPv6 został opracowany w Bydgoszczy</a></p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:wikidot-crashes</guid>
				<title>Wikidot Crashes</title>
				<link>http://piotr.gabryjeluk.pl/dev:wikidot-crashes</link>
				<description>

&lt;p&gt;Last night we made Wikidot online again after a great crash.&lt;/p&gt;
&lt;p&gt;Wikidot was down for about 12 hours and the time it was down was full of work for us. We got a few things that could be broken starting from recent changes of the Wikidot software, hardware failure, high load-related kernel bugs or limitations to connection number or maximum possible number or file descriptors.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 27 Aug 2009 13:03:23 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Last night we made Wikidot online again after a great crash.</p> <p>Wikidot was down for about 12 hours and the time it was down was full of work for us. We got a few things that could be broken starting from recent changes of the Wikidot software, hardware failure, high load-related kernel bugs or limitations to connection number or maximum possible number or file descriptors.</p> <div class="content-separator" style="display: none:"></div> <p>The problem is Wikidot kind of worked, so some people had their sites loading, some other not and getting "500" errors. We didn't want to stop it, but at some point Wikidot was completely unusable. We switched the database to the other machine, but this was not the solution, then we switched all Wikidot traffic to the machine, still no good, we switched the software to some previous version, but this still seemed bad.</p> <p>Finally we worked out, there was a site, that had so big traffic, that it killed anything else (and itself as well). When we temporarily disabled it, the whole Wikidot started to work nicely again. Then Michał made some improvements for the high traffic site serving and the situation is stable again.</p> <p>In the middle of everything, we had huge problems with our hosting company and their service called Portable IP addresses. It seems that switching DNS is much more reliable that using Portable IPs that took hours to switch (and were supposed to take seconds to switch)! DNS switching time was 15 minutes.</p> <p>We learned a lot from the situation. Hardware upgrade postponed from really long time needs to be done quite quickly. We need more servers, to see which element breaks. For example if database server has high load, we know we need to tune database settings. If we have all on one massive server and one brick on it crashes, it usually causes all the server overloaded and this causes other bricks to crash as well, so it's hard too tell what the real problem is.</p> <p>Another thing is that we see our users want information on what happens. It's bad when Wikidot crashes, but it's even worse, when it crashes and they have no information about this.</p> <p>So, the next time a similar disaster happens we'll update on each technical detail possible, to let you know, that we know it's broken and we work hard to fix it. Other thing is, we plan having more fail-over servers in case something dies.</p> <p>Thank you all for using Wikidot, it's a great pleasure working (and fixing things) for you!</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:dwa-typy</guid>
				<title>Dwa Typy</title>
				<link>http://piotr.gabryjeluk.pl/dev:dwa-typy</link>
				<description>

&lt;p&gt;Wielcy myśliciele potrzebują lat, żeby coś wymyślić. A ja dzisiaj ni z tego, ni z owego, przy zmywaniu naczyń po ostatniej imprezie wymyśliłem aż dwie rzeczy:&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 19 Aug 2009 19:27:35 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Wielcy myśliciele potrzebują lat, żeby coś wymyślić. A ja dzisiaj ni z tego, ni z owego, przy zmywaniu naczyń po ostatniej imprezie wymyśliłem aż dwie rzeczy:</p> <div class="content-separator" style="display: none:"></div> <blockquote> <p>Ludzie są albo niemili, albo nieszczerzy.</p> </blockquote> <p>Oraz:</p> <blockquote> <p>Jedynacy nie czują potrzeby posiadania kont użytkowników na komputerze.</p> </blockquote> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:yaml-and-php</guid>
				<title>YAML and PHP</title>
				<link>http://piotr.gabryjeluk.pl/dev:yaml-and-php</link>
				<description>

&lt;p&gt;There are 3 main YAML implementations for PHP:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Syck (native C library bindings to PHP)&lt;/li&gt;
&lt;li&gt;Symphony YAML (pure PHP)&lt;/li&gt;
&lt;li&gt;Spyc (pure PHP again)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the comparison.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 30 Jul 2009 19:03:36 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>There are 3 main YAML implementations for PHP:</p> <ul> <li>Syck (native C library bindings to PHP)</li> <li>Symphony YAML (pure PHP)</li> <li>Spyc (pure PHP again)</li> </ul> <p>This is the comparison.</p> <div class="content-separator" style="display: none:"></div> <h1><span>What the hell is YAML</span></h1> <p>Have you heard about XML or JSON? YAML is similarly to JSON and XML a way to store (read and write) structured data like arrays (a.k.a. lists), dictionaries (a.k.a. hash maps) and atomic values like strings and numbers. The structures can be nested, to form a definition of near-real-life objects, for example:</p> <div class="code"> <pre> <code>--- Piotr Gabryjeluk: company: Wikidot Inc. university: Nicolaus Copernicus University, Toruń, Poland lives_in: Toruń, Poland hobbies: - basketball - playing the guitar</code> </pre></div> <p>Which translates to PHP:</p> <div class="code"> <div class="hl-main"> <pre> <span class="hl-inlinetags">&lt;?php</span><span class="hl-code"> </span><span class="hl-var">$data</span><span class="hl-code"> = </span><span class="hl-reserved">array</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">Piotr Gabryjeluk</span><span class="hl-quotes">'</span><span class="hl-code"> =&gt; </span><span class="hl-reserved">array</span><span class="hl-brackets">(</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">company</span><span class="hl-quotes">'</span><span class="hl-code"> =&gt; </span><span class="hl-quotes">'</span><span class="hl-string">Wikidot Inc.</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">university</span><span class="hl-quotes">'</span><span class="hl-code"> =&gt; </span><span class="hl-quotes">'</span><span class="hl-string">Nicolaus Copernicus University, Toruń, Poland</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">lives_in</span><span class="hl-quotes">'</span><span class="hl-code"> =&gt; </span><span class="hl-quotes">'</span><span class="hl-string">Toruń, Poland</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">hobbies</span><span class="hl-quotes">'</span><span class="hl-code"> =&gt; </span><span class="hl-reserved">array</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">basketball</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">playing the guitar</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">))</span><span class="hl-code">;</span> </pre></div> </div> <p>So you see YAML is quite nice even when you need to write it yourself.</p> <p>YAML has its specification (see <a href="http://yaml.org">http://yaml.org</a>), so once we have standard YAML parser and standard YAML dumper we can send arrays from one machine to another and the result should be the same array as was sent.</p> <h1><span>PHP</span></h1> <p>So let's see what are the choices if you want to play with YAML in PHP.</p> <h2><span>Syck</span></h2> <p>This is the fastest and the most complete YAML dumper and loader library available. This is binding to C library and this is available in PEAR. It is also available as regular package in Ubuntu repository, so install it by simple:</p> <div class="code"> <pre> <code>aptitude install php5-syck</code> </pre></div> <p>In some shared hosting environment this could be a problem, so you need a pure PHP solution.</p> <h2><span>Spyc</span></h2> <p>This was the first PHP YAML implementation I saw. It is both dumper and loader and it seemed to work fine, but then I found some bugs, that stopped me from using it as the base and only YAML loader and dumper for Wikidot.</p> <p>This one has really nice thing, which is nice when you want your users to enter YAML to define things (like we do for forms). It is quite forgiving when it comes to the syntax and ignores things that don't fit and still parses the rest.</p> <p>Unfortunately as I stated before Spyc dumper so, when you first dump an array and then load it with Spyc you get something different (for example multiple new-lines are treated as one). Not good. Also as a loader it does not fully understand the full YAML specification (which is quite huge BTW).</p> <h2><span>Symphony YAML</span></h2> <p>This one is pure-PHP as well, so you don't need special rights, to use it on a PHP-enabled machine.</p> <p>It's loader does not understand full YAML specification, so for example you can't load documents dumped by Syck. Dumper is good.</p> <h1><span>Summary</span></h1> <table class="wiki-content-table"> <tr> <th></th> <th>Syck</th> <th>Spyc</th> <th>Symphony YAML</th> </tr> <tr> <td>type of library</td> <td>PHP extension</td> <td><strong>pure PHP library</strong></td> <td><strong>pure PHP library</strong></td> </tr> <tr> <td>speed</td> <td><strong>fast</strong></td> <td>slow</td> <td>slow</td> </tr> <tr> <td>loader: YAML support</td> <td><strong>full</strong></td> <td>bad</td> <td>not bad</td> </tr> <tr> <td>loader: if YAML is corrupted</td> <td>exception</td> <td><strong>tries to do its best to load the rest</strong></td> <td>exception</td> </tr> <tr> <td>dumper: YAML human-readable</td> <td>more-or-less</td> <td><strong>yes</strong></td> <td>more-or-less if set properly</td> </tr> <tr> <td>dumper: YAML conforms to spec</td> <td><strong>yes</strong></td> <td>no</td> <td><strong>yes</strong></td> </tr> <tr> <td>loads Syck's dumper output correctly</td> <td><strong>yes</strong></td> <td>no</td> <td>no</td> </tr> <tr> <td>loads Symphony's dumper output correctly</td> <td><strong>yes</strong></td> <td>no</td> <td><strong>yes</strong></td> </tr> </table> <h2><span>Verdict: loader</span></h2> <p>Syck is the winner in loading YAML. If you cannot use Syck, use Symphony YAML. If you need to parse user input (which should be human readable/writable similar to YAML), use Spyc.</p> <p>Actually, this is nice combination for loading:</p> <div class="code"> <div class="hl-main"> <pre> <span class="hl-inlinetags">&lt;?php</span><span class="hl-code"> </span><span class="hl-reserved">try</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code"> </span><span class="hl-comment">// if syck is available use it</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-identifier">extension_loaded</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">syck</span><span class="hl-quotes">'</span><span class="hl-brackets">))</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code"> </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-identifier">syck_load</span><span class="hl-brackets">(</span><span class="hl-var">$string</span><span class="hl-brackets">)</span><span class="hl-code">; </span><span class="hl-brackets">}</span><span class="hl-code"> </span><span class="hl-comment">// if not, use the symfony YAML parser</span><span class="hl-code"> </span><span class="hl-var">$yaml</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">sfYamlParser</span><span class="hl-brackets">()</span><span class="hl-code">; </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-var">$yaml</span><span class="hl-code">-&gt;</span><span class="hl-identifier">parse</span><span class="hl-brackets">(</span><span class="hl-var">$string</span><span class="hl-brackets">)</span><span class="hl-code">; </span><span class="hl-brackets">}</span><span class="hl-code"> </span><span class="hl-reserved">catch</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-identifier">Exception</span><span class="hl-code"> </span><span class="hl-var">$e</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code"> </span><span class="hl-comment">// if YAML document is not correct,</span><span class="hl-code"> </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-identifier">Spyc</span><span class="hl-code">::</span><span class="hl-identifier">YAMLLoadString</span><span class="hl-brackets">(</span><span class="hl-var">$string</span><span class="hl-brackets">)</span><span class="hl-code">; </span><span class="hl-brackets">}</span> </pre></div> </div> <p>This way, you have the fastest library used if possible, then the best pure-PHP, and if it fails in a way, that document was badly written (by human being for example), you fall-back to Spyc.</p> <h2><span>Verdict: dumper</span></h2> <p>In my opinion Symphony YAML dumper is the best from the three in terms of usability, portability and interoperability, because its output can be read by both itself and Spyc.</p> <p>However, if you dump YAML often, use (hell faster) Syck for both loading and dumping. The generated YAML won't be readable by Symphony YAML or Spyc, but this is because they don't follow the specification (so not Syck's problem in fact).</p> <p>Also note, that any valid JSON dumper output is readable by standard YAML 1.2 loaders, because JSON is a subset of YAML 1.2. So if using for data exchange (and not for talking to human) any fast JSON dumper can be used.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:july-news</guid>
				<title>July News</title>
				<link>http://piotr.gabryjeluk.pl/dev:july-news</link>
				<description>

&lt;p&gt;Some of you may be more used to me posting more often, than in last time.&lt;br /&gt;
Some of you may wonder why I stopped blogging.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Tue, 28 Jul 2009 15:41:03 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Some of you may be more used to me posting more often, than in last time.<br /> Some of you may wonder why I stopped blogging.</p> <div class="content-separator" style="display: none:"></div> <h2><span>Brussels</span></h2> <p>Last month was full of adventures. It started 1st of July with me going to Brussels meat our friend to talk about wikipedia-like site about art. We're going to help this man build the most complete site about art using Wikidot software!</p> <p>BTW, this was my first flight in lifetime. Quite a strange feeling, but generally fine.</p> <h2><span>Forms</span></h2> <p>I was working on some nice technical and UI improvements to Wikidot, that is crucial for the art site (but really really nice for Wikidot as well, like forms for editing, entering and viewing structured data to wiki pages).</p> <h2><span>Search issues</span></h2> <p>That week was also spent on some massive Wikidot.com search engine tweaks. A stupid one-line bug, which was <strong>not</strong> exporting proper LC_ALL environmental variable in indexing script, caused many sites that used Asian or East-European languages to be not indexed (most notably the great <a href="http://istorijska-biblioteka.wikidot.com/">ИСТОРИЈСКА БИБЛИОТЕКА</a>). At first we though that we can re-index the broken sites, but our re-indexing mechanism was way too slow (would last for weeks for all broken sites).</p> <p>Pieter then challenged me. He said he can index whole Wikidot in 6 hours. I thought it's not even possible, but then I started to work on that and I managed to index the whole Wikidot in less than 2 hours without indexing tags at first. Then with tags, it took 2 hours and 10 minutes or so. That was damn fast!</p> <p>Inspired by this and an accident of disk full error on /var partition of our webserver (but this is why we keep user-uploaded files and other important things on separate disks), I also rewrote the incremental indexer, to work in similar way to the whole-Wikidot-re-indexer.</p> <h2><span><tt>search-api reindex</tt></span></h2> <p>If you care about some technical details:</p> <ul> <li>all search operations are issued with use of search-api, a separate program that can: <ul> <li>re-index whole Wikidot</li> <li>queue indexing page/thread</li> <li>queue deleting page/thread</li> <li>queue re-indexing site</li> <li>flush queue</li> </ul> </li> <li>search-api is written in Python</li> <li>search-api uses PyLucene - a native Java Lucene library binded to CPython objects with PyJCC. Compiled with GNU Java Compiler to native code (like C programs), this binding has improved performance over using Lucene with Sun's Java.</li> <li>before rewriting it to only-Python, search-api was written in BASH and was a wrapper to: <ul> <li><tt>java -jar searchApiHelper.jar search "phrase-to-search"</tt></li> <li><tt>php search-api-helper.php flush</tt></li> </ul> </li> <li>search-api also takes care of file locking to assure that <ul> <li>only one process tries to modify the index</li> <li>items are added to queue one-after-another</li> <li>when doing some big index modification (read: full re-index) queue is not flushed (so that after the re-index all changes are applied to new index)</li> <li>when flushing queue takes more time, and cron tries to run more flushing processes, they simply end (so only one process flushes the queue at a time)</li> </ul> </li> </ul> <h2><span>Union of Rock Festival</span></h2> <p>Just after week spent in Brussels in nice hotel I went to Węgorzewo, Mazury (Poland biggest lakes distinct) to have fun on rock music festival. Unfortunately, the music level was not very impressive, so I mainly enjoyed the atmosphere on the camping area.</p> <p>The weather was not great. It was wet everywhere, the ground was covered in 20 centimeters of mud and it was hard to walk around without getting dirty. But during the first day of being there, I learned to do that.</p> <h2><span>Improved workflow at Wikidot</span></h2> <p>Some of you noticed, that recently we started to work more efficiently, but this is not quite true. In fact we work as efficiently as before, but we are better organized, and have better priorities on tasks. Also we keep track of what we do, so we can then tell what we've done. So for us, this is a little more work of "documenting" our work (so maybe we work even less efficiently than before?), but for the outside world, we make more noise (in a positive meaning) around that. So basically, people know what we do, what we are going to do, when they can expect changes and most importantly, they understand why some feature request is being postponed. This is (and was) because we have more important things to do, but before they couldn't tell it.</p> <p><span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/squark" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/160/160264/a16.png" alt="Squark" style="background-image:url(http://www.wikidot.com/userkarma.php?u=160264)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/160/160264/a16.png" alt="Squark" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=160264,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/squark" >Squark</a></span> turned into a professional project manager, that manages our time. <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/pieterh" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/0/99/a16.png" alt="pieterh" style="background-image:url(http://www.wikidot.com/userkarma.php?u=99)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/0/99/a16.png" alt="pieterh" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=99,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/pieterh" >pieterh</a></span> decided to <a href="http://blog.wikidot.com/">talk</a> to the Community and listen to their complaints (he reads or at least skims every post on Community forums). He tells Łukasz what needs to be done, Łukasz knows when we will have time to do this. This way communication inside Wikidot improved. Also we (<span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/michal-frackowiak" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/0/1/a16.png" alt="michal frackowiak" style="background-image:url(http://www.wikidot.com/userkarma.php?u=1)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/0/1/a16.png" alt="michal frackowiak" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=1,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/michal-frackowiak" >michal frackowiak</a></span> and me) no longer look on Community forums (some of you may regret), but this allows us to concentrate on our work.</p> <h2><span>The work continues</span></h2> <p>As I mentioned before, we want to introduce a great feature to Wikidot, which is <em>forms</em>. But the implementation now concentrates on the <a href="http://www.wikidot.org/">open source version of Wikidot software</a> (once it's ready, working and tested we'll copy the feature to the Wikidot.com service).</p> <h2><span><tt>aptitude install wikidot</tt></span></h2> <p>As forms is a huge change, I started to prepare a good ground for it and closed most important bugs in Wikidot open source and I'm about to start making Ubuntu packages for it to allow even-simpler installation on Debian-based systems. Now the installation involves only <a href="http://www.wikidot.org/installation-guide">6 child-easy steps</a> and in fact can be done by copying&amp;pasting a few commands.</p> <h2><span>Yesterday's party</span></h2> <p>Yesterday I went to met some old-school-times friends in the heart of the city. It was meant to be a meeting for "a beer or two" but evolved into beer and dancing till morning. That was first time I get a morning bus (not even the first) to my home just after partying.</p> <p>It was such a great fun and great folks I met.</p> <h2><span>Summary</span></h2> <p>I hope with this long blog post (but divided into friendly sections ;) ) I recompensed long period of not-posting anything here.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:black-clouds-silver-linings</guid>
				<title>Black Clouds &amp; Silver Linings</title>
				<link>http://piotr.gabryjeluk.pl/dev:black-clouds-silver-linings</link>
				<description>

&lt;p&gt;Dostałem ten krążek niespodziewanie. Chciałem trochę się przygotować na ten moment, ale to było zaskoczenie i miły gest ze strony najbliższej osoby. &quot;Żebyś miał co słuchać w czasie podróży&quot;.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Sat, 04 Jul 2009 14:38:53 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Dostałem ten krążek niespodziewanie. Chciałem trochę się przygotować na ten moment, ale to było zaskoczenie i miły gest ze strony najbliższej osoby. "Żebyś miał co słuchać w czasie podróży".</p> <div class="content-separator" style="display: none:"></div> <p>Zgrałem sobie piosenki na komputer i na oggówkę<sup class="footnoteref"><a id="footnoteref-204223-1" href="javascript:;" class="footnoteref" >1</a></sup> i zacząłem słuchać na dzień przed podróżą w łóżku przed snem.</p> <p>Dobre ciężkie riffy, melodyczne fragmenty i nagle, błeee, co to? Jakiś okropny wokal, bez emocji i wyrazu, za chwilę dźwięk klasycznej gitary. Totalne dno. Masakra.</p> <p>Powracam do krążka w czasie podróży. Nie mogę wytrzymać, zmieniam utwory. W końcu słucham innego albumu.</p> <p>W pracy słucham tej muzyki w tle. Wychwytuję ciekawe fragmenty. 5 minut, 10 minut i znowu jakieś dno.</p> <p>Jeśli chodzi o krążek, jego poziom jest równy — każda piosenka jest równie beznadziejna. Jeśli chodzi o piosenki: praktycznie każda jest nierówna. Zaczyna się fajnie, mięsiście, męsko, mocno, metalowo, z wyrazem i potem ni stąd ni zowąd pojawia się jakiś popowy szajs.</p> <p>Żal mi tych dobrych fragmentów porozsiewanych po sześciu piosenkach, bo wciąż Dream Theater to dobry zespół i te powiedzmy 20 minut mogłoby się złożyć na jedną dobrą piosenkę, dla której warto byłoby kupić album (podobnie jak utwór A Change of Seasons sprawia, że warto kupić album A Change of Seasons). A w związku z tym fatalnym przemieszaniem "good shit" with "just shit" ta płyta nie jest warta zakupu.</p> <p>Dream Theater: duży minus dla Was. Mam nadzieję, że na koncercie nie będziecie próbować promować tej płyty, bo to nie ma żadnego sensu.</p> <p>PS: duży minus również dla sekcji wokalnej. Nie odnalazłem na całym albumie ani minuty ciekawego, żywego i ekspresyjnego wokalu, jakiego pełna jest każda inna płyta zespołu.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> <div class="footnotes-footer"> <div class="title">Footnotes</div> <div class="footnote-footer" id="footnote-204223-1"><a href="javascript:;" >1</a>. przenośny odtwarzacz plików Ogg/Vorbis (tak jak empetrójka to przenośny otwarzacz plików MP3)</div> </div> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:lucene-replaces-local-searches</guid>
				<title>Lucene Replaces Local Searches</title>
				<link>http://piotr.gabryjeluk.pl/dev:lucene-replaces-local-searches</link>
				<description>

&lt;p&gt;As some of you know, some time ago I worked on a new &lt;a href=&quot;http://piotr.gabryjeluk.pl/dev:wikidot-search-launched&quot;&gt;Wikidot search&lt;/a&gt;. It is used for the &lt;a href=&quot;http://www.wikidot.com/search:all&quot;&gt;Search all sites&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;This work was done, because searching the whole Wikidot database was far from being fast. At first we used Google Custom Search Engine to solve the problem, but we wanted to be independent from it. Also we wanted to include search results that are accessible by the person that searches but not by search engines (like private sites).&lt;/p&gt;
&lt;p&gt;This worked really good. The only problem was long time spent to display the results. It was like 20 seconds, which was far better than when using previous search, but much worse than Google. This was strange, because from previous tests, we calculated the average search time should be about a second or two.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Tue, 23 Jun 2009 18:25:58 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>As some of you know, some time ago I worked on a new <a href="http://piotr.gabryjeluk.pl/dev:wikidot-search-launched">Wikidot search</a>. It is used for the <a href="http://www.wikidot.com/search:all">Search all sites</a> page.</p> <p>This work was done, because searching the whole Wikidot database was far from being fast. At first we used Google Custom Search Engine to solve the problem, but we wanted to be independent from it. Also we wanted to include search results that are accessible by the person that searches but not by search engines (like private sites).</p> <p>This worked really good. The only problem was long time spent to display the results. It was like 20 seconds, which was far better than when using previous search, but much worse than Google. This was strange, because from previous tests, we calculated the average search time should be about a second or two.</p> <div class="content-separator" style="display: none:"></div> <p>It started to be clear, when we noticed that only 20-30 searches per day are performed. The index is quite big, and it needs to be cached in RAM to work with sufficient performance.</p> <p>Today I did more tests under heavy load and it seams Lucene can handle big number of queries. When users search often, the index is partially or even fully cached by the filesystem and searches are really quick!</p> <p>But our main problem to solve today was slow local search a.k.a. "search this site". Moreover many concurrent queries were degrading database performance (not only for searching), so we decided to enable Lucene for local searches as well.</p> <p>I must say it works really nice, fast and has a nice set of syntax tricks you can do with it, for example you can search for pages with something in tags. Just search for <em>youtube tags:embed</em>. This would search for pages matching <em>youtube</em> (in tags, title or content) and with <em>embed</em> in tags. If no such pages are found, partial matches are also returned, like: pages matching <em>youtube</em> (but with no <em>embed</em> in tags) or pages with <em>embed</em> in tags, (but not matching <em>youtube</em>).</p> <p>To sum up, new search is faster, gives more accurate results, saves the database performance (which was the main goal) and allows nicer syntax than the old one.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:php-as-fastcgi-backend</guid>
				<title>PHP as FastCGI backend and Lighttpd</title>
				<link>http://piotr.gabryjeluk.pl/dev:php-as-fastcgi-backend</link>
				<description>

&lt;h1&gt;&lt;span&gt;Wikidot + Lighttpd + PHP5&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;At Wikidot we use PHP5 as FastCGI backend to Lighttpd light-and-fast webserver. It works like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;there are a few hundreds of php5-cgi processes (name is cgi, but they also support FastCGI mode) running and waiting to be used&lt;/li&gt;
&lt;li&gt;lighttpd (only one needed!) process manages the network connections to all the clients and once the request is ready serves a static file or forwards the request to one of PHP backends processes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Mon, 15 Jun 2009 20:59:29 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <h1><span>Wikidot + Lighttpd + PHP5</span></h1> <p>At Wikidot we use PHP5 as FastCGI backend to Lighttpd light-and-fast webserver. It works like this:</p> <ul> <li>there are a few hundreds of php5-cgi processes (name is cgi, but they also support FastCGI mode) running and waiting to be used</li> <li>lighttpd (only one needed!) process manages the network connections to all the clients and once the request is ready serves a static file or forwards the request to one of PHP backends processes.</li> </ul> <div class="content-separator" style="display: none:"></div> <p>We used to use internal Lighttpd FastCGI process manager, meaning the lighttpd processes actually used to start the PHPs.</p> <h1><span>Problems</span></h1> <p>We encountered some known problems of 500 (server side) errors appearing after some random time, especially under a high traffic. The typical message appearing at the Lighttpd's error.log was:</p> <div class="code"> <pre> <code>&lt;some date&gt;: (mod_fastcgi.c.2494) unexpected end-of-file (perhaps the fastcgi process died): pid: ...</code> </pre></div> <p>There are plenty of reports on this in both <a href="http://forum.lighttpd.net/topic/93190">Lighttpd</a>'s and <a href="http://bugs.php.net/bug.php?id=43295">PHP</a>'s <a href="http://forum.lighttpd.net/topic/93190">forums</a>, <a href="http://pecl.php.net/bugs/bug.php?id=12608">bug</a> <a href="http://redmine.lighttpd.net/issues/1466">trackers</a> and even <a href="http://www.rooftopsolutions.nl/article/201">some</a> <a href="http://jcj.net/?p=24">blogs</a>.</p> <h1><span>Workarounds</span></h1> <p>We managed to write some hacky scripts that detected the situation and restarted the backends when needed. The reaction was so quick, that almost no-one noticed the error, but damn, this is not how WE solve problems.</p> <h1><span>A blind try</span></h1> <p>We decided to give spawn-fcgi a shot. What is it? It is a program that spawns FastCGI backends (independently from Lighttpd server). Why trying it? I've read somewhere, that it works more reliably than the internal Lighttpd spawner. What's interesting is that this program comes from lighttpd package, so we're in family anyway. It's mainly intended to run the FastCGI backends from different user than the webserver user or to run them on different machine(s) than the webserver machine. This can be used naturally for some smart load-balancing.</p> <p>The only problem of this solution we encountered was internal limit of number of processes to spawn by a single process which was 256 (hardcoded, fixed in next versions). But at the same time, we decided to build a few FastCGI bridges (each spawning ~200 PHPs) anyway so that was no longer a problem for us.</p> <p>What was quite surprising (but honestly, I deeply believed in this), our problems with 500 server errors and PHP disappeared. This configuration works for about 2 weeks now with absolutely no hacky scripts involved and no restarting needed. Cool.</p> <h1><span>Why I wrote this</span></h1> <p>I wrote this short note just for the record and to let other people know, that using spawn-fcgi instead of the internal Lighttpd's FastCGI spawner might solve their problems with PHP (FastCGI) and 500 internal server errors.</p> <p>Hope this helps someone.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:new-things-new-ideas</guid>
				<title>New Things, New Ideas</title>
				<link>http://piotr.gabryjeluk.pl/dev:new-things-new-ideas</link>
				<description>

&lt;p&gt;OK, this is a very short note, because I&#039;m trying to learn to my Friday exam and would prefer to pass it.&lt;/p&gt;
&lt;p&gt;During last time, I though it would be nice to have at least two things. One is a total revolution and probably won&#039;t be ready in near time, but second is quite easily implementable.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 10 Jun 2009 18:09:29 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>OK, this is a very short note, because I'm trying to learn to my Friday exam and would prefer to pass it.</p> <p>During last time, I though it would be nice to have at least two things. One is a total revolution and probably won't be ready in near time, but second is quite easily implementable.</p> <div class="content-separator" style="display: none:"></div> <h1><span>Events and PUSH</span></h1> <p>The first thing is to have a <span style="text-decoration: underline;">totally</span> event-driven Linux and web services built on top of that. What does it mean? Every system event — file created, TCP connection set up, terminal window popped out, AC adapter plugged in, IM contact went on-line, … should be broadcasted to every application that registered for this event.</p> <p>There should be two kind of events — synchronous and asynchronous. Synchronous means that each event listener can stop event (or delay it). For example messenger client can listen for suspend event, react by disconnecting you from IM networks and then let the suspend continue. Asynchronous are just some signals that are informational only, that are not to be interrupted — like "new wifi network detected".</p> <p>What to build on top of that? Imagine the following scheme:</p> <ul> <li>file is created in /home/ directory signal is immediately send</li> <li>signal is caught by an application that calculates disk usage. Disk usage changes to 98%. Signal is immediately broadcasted</li> <li>the signal is caught by "low-space-notifier" application, that immediately sends you an email</li> <li>email is received and put into your INBOX</li> <li>if you have your mail client connected to mail server, you get the notification about the new mail immediately</li> <li>mail client shows you a nice notification about disk usage going to 98% on some other machine.</li> </ul> <p>parsing everything including sending email and other things is less than 5 seconds. So you get the message "just as it's sent".</p> <p>Some of the concepts in the example are already implemented, like inotify for file changes, IMAP push mode, but the problem is that in each case, this is solved individually, and what I would want is a UNIVERSAL and FAST solution for all event-driven computing.</p> <p>On the other hand we (now) have polling. So Linux polls the CD drive for new disks every 2 seconds, mail client poll server each minute, RSS aggregators ask servers about news every 15 minutes and so.</p> <p>The problem comes if you want to forward a message using polling. For example I have a mail account on some server and I want some messages to be forwarded to other server. Polling the first mailbox each 1 minute and doing processing mails makes the mail appear in the second mailbox 1 minute later (in the worst case). If I poll for mails in the second mailbox as well, the message is delayed for 2 minutes. If I want to pass the message to next mailboxes, the distribution time raises.</p> <p>The solution for that is to poll services very very often (like every 10 seconds). 10 seconds multiplied by 4-5 mailboxes (in chain) is like 1 minute delay, which is in most cases acceptable. But this is just not needed to ask server for new messages each 10 seconds! How much much better would be to ask server, to notify about the message just as they come!</p> <p>All problems with polling are just about "what polling time is OK". Polling to often means additional server work for answering "no, nothing new yet", and polling to rarely means outdated information. Either way polling is bad. And as it may seem inefficient to send messages as they come, it can be much more efficient than dealing with clients asking for new messages each 10 seconds.</p> <p>This is first dream. Event-driven world, that delivers messages as fast as it can (not a new idea, it is used in old SMTP for example).</p> <h1><span>FsDb</span></h1> <p>The second dream is having a filesystem as powerful as a database. Why?</p> <ul> <li>There are good tools to deal with filesystems: ls, mv, rm, cp, ln</li> <li>You can serve filesystems with WWW, FTP, SAMBA, NFS servers</li> <li>Files are supported nicely in all programming languages I know</li> </ul> <p>What database features I would like to have in filesystems:</p> <p>1. Automatic backlinks. In database I have cars that belong to user:</p> <div class="code"> <pre> <code>CREATE TABLE Car ( name: STRING; year: INT; user_id: FOREIGN KEY (User); );</code> </pre></div> <p>but I can use that relation to User in the reverse:</p> <div class="code"> <pre> <code>SELECT * FROM Car WHERE user_id = 7;</code> </pre></div> <p>where 7 is my user_id. This works fast (even having millions of cars). If I have it in filesystem:</p> <div class="code"> <pre> <code>$ ls cars/porsche -l name year user -&gt; ../users/gabrys</code> </pre></div> <p>I can do something like:</p> <div class="code"> <pre> <code>$ cd cars $ for car in *; do ls -l $car | grep 'user -&gt; ../users/gabrys' 1&gt;/dev/null &amp;&amp; echo $car; done porsche</code> </pre></div> <p>but this is counter-effective. It just goes through ALL cars and see if they have user linking to users/gabrys.</p> <p>2. sorting/grouping by given field/property<br /> 3. paging (page 3, 10 items per page)<br /> 4. searching<br /> 5. <span style="text-decoration: line-through;">full text searching</span> — this is rarely used in databases as it's always better idea to have separate application for that, like Lucene, so this is not to be needed in the filesystem.</p> <h1><span>How to do this</span></h1> <p>I believe all (or nearly all) of this can be done having a simple fs as the backend and doing additional integrity tasks after given operations. Most notably, when you link from car to user:</p> <div class="code"> <pre> <code>$ ln -s ../users/gabrys cars/porsche/owner</code> </pre></div> <p>There should be also something like this done automatically:</p> <div class="code"> <pre> <code>$ ln -s ../cars/porsche users/gabrys/cars/</code> </pre></div> <p>Then listing Gabrys' cars would be:</p> <div class="code"> <pre> <code>$ ls users/gabrys/cars</code> </pre></div> <p>And this would list links to the cars that have links to gabrys. So it's just automatic backlink mechanism. It's just that easy, and that powerful.</p> <p>Other things that make this nice is that you can easily back up the "database" (by having a special snapshot-enabled filesystem as a backend), NFS-mount it, replicate, rsync, encrypt, split to different hosts and easily debug with standard filesystem tools. Also there would be no big magic in that, so everyone could work with it.</p> <p>The problem yet to think of is how to define the schema of data to be stored in the "database". But maybe the schema is even not needed by having a few conventions of special directories for example (like .backlinks directory storing backlinks, .fields directory storing field values and that kind of stuff).</p> <p>Wish me luck with exams!</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotr.gabryjeluk.pl/dev:wire-wrapped-jewelry</guid>
				<title>Wire Wrapped Jewelry</title>
				<link>http://piotr.gabryjeluk.pl/dev:wire-wrapped-jewelry</link>
				<description>

&lt;p&gt;I would like to present new high quality earrings made by my fiancée.&lt;/p&gt;
&lt;p&gt;They are called &lt;strong&gt;Forget-Me-Not&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;!--[if gte IE 7]&gt;&lt;!--&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common--images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;!--&lt;![endif]--&gt;&lt;!--[if lt IE 7]&gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/common&amp;#45;&amp;#45;images/avatars/2/2462/a16.png&quot; alt=&quot;Gabrys&quot; style=&quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod=&#039;scale&#039;)&quot;/&gt;&lt;![endif]--&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 03 Jun 2009 09:18:46 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>I would like to present new high quality earrings made by my fiancée.</p> <p>They are called <strong>Forget-Me-Not</strong>.</p> <div class="content-separator" style="display: none:"></div> <p style="text-align: center;"><img src="http://chaber-bizuteria.wdfiles.com/local--resized-images/kolczyki:niezapominajki/main.jpg/medium.jpg" alt="medium.jpg" class="image" /></p> <p>They are effect of a great design and many hours of work. The great look comes from wire-wrapping — a technique hard enough to not be used by many artists. Also what counts is very high precision, which makes earrings look gorgeous.</p> <p>Carefully chosen color of the nacre makes them just perfect.</p> <p>If you want to buy them, contact me at <span class="wiki-email">lp.kooltsal|rtoip#lp.kooltsal|rtoip</span> (or leave comment on this page). I can prepare them and send to EU or even US. Payment with PayPal or international bank transfer. Including posting to EU, price would be <span style="font-size:large;"><strong>€20</strong></span> (20 Euro).</p> <p>See the whole collection on <a href="http://chaber.art.pl/">this site</a> (in Polish language).</p> <p><strong>UPDATE</strong>: I forgot to mention about dimensions of them. The total length (height) of them (including hooks) is 50&nbsp;mm. Also we decided to even lower the price to <strong>15 Euro including shipping to EU</strong> just to make your decision easier!</p> <p><strong>This is a great opportunity. No-one else has earrings like this, guarantied!</strong></p> <p><strong>UPDATE</strong>: earrings are sold. Look at similar ones at the following link <a class="newpage" href="http://piotr.gabryjeluk.pl/wire:wrapping">biżuteria wire wrapping</a>.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><!--[if gte IE 7]><!--><img class="small" src="http://www.wikidot.com/common--images/avatars/2/2462/a16.png" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /><!--<![endif]--><!--[if lt IE 7]><img class="small" src="http://www.wikidot.com/common&#45;&#45;images/avatars/2/2462/a16.png" alt="Gabrys" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=http://www.wikidot.com/userkarma.php?u=2462,sizingMethod='scale')"/><![endif]--></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
				</channel>
</rss>