tag:blogger.com,1999:blog-20849787285140292212024-02-19T09:46:44.381+01:00Thomann /dev/blogRainbow puking unicorns, awesome rocket science and comic sans - live from TreppendorfDavidhttp://www.blogger.com/profile/17993611855811846763noreply@blogger.comBlogger11125tag:blogger.com,1999:blog-2084978728514029221.post-24705924721874943632014-02-23T01:06:00.003+01:002014-02-23T01:06:43.529+01:00We've been quite busy the last few weeksChristmas time always is a quite different time for all of us in Treppendorf. Hotline and logistics are working almost 24 hours a day, the local store and even we, the webdevelopers, change our mode from "productivity" to "lean back, watch stats and don't fucking touch anything". We survived the whole christmas sale pretty good without any outage and so we went back to work, which is actually the reason why no one of us was able to write anything here.<div>
<br /></div>
<div>
There are a few upcoming projects that will still keep us quite busy this year, on top of all probably our new search engine (including a redesign of our search result page) and our new mobile page. We have improved our team and our new developer just finished his first big project, the new customer centre (which is going live on Monday).</div>
<div>
<br /></div>
<div>
And that's all? We'll, for the next few weeks, yes. Other upcoming projects are some other pages we lost on our redesign process last year like the category page, the basket and single elements on the product detail page. And still we have some secret projects to work on which are quite exciting (and bring some great benefits to our customers.. we'll talk about that later).</div>
<div>
<br /></div>
<div>
Oh wait, I almost forgot the most important task we're on right now: Finding things we want in our new office building which is being built as I write. German building laws prohibit a slide (not explicit; it's something about fire safety) and so we accepted the challenge to find other weird and funny things to put inside. If you have any great ideas, just let us know. And if you're interested, our social media guys post updates on our <a href="https://www.facebook.com/media/set/?set=a.631578540215096.1073741844.103916239647998&">Facebook page</a> regularly.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
So long!</div>
<div>
<br /></div>
<div>
<br /></div>
Davidhttp://www.blogger.com/profile/17993611855811846763noreply@blogger.com0tag:blogger.com,1999:blog-2084978728514029221.post-8071868548494170182014-01-12T14:53:00.000+01:002014-01-13T09:17:59.397+01:00Drawing Graphs with MySQLDrawing what with what???!?<br />
<br />
Yes you read correctly.
Let's suppose we got the following table layout in MySql:
<br />
<br />
<pre><code class="no-highlight">
+-------------+--------------+------+-----+---------+----------------+
| Fiel | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| createTime | DateTime | YES | | NULL | |
| dur | integer | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
</code></pre>
<br />
It's a very basic logging table that simply stores generic events, its creation time and the time this event took to run in milliseconds.
Lets query that table:
<br />
<pre><code class="sql">SELECT creationTime, executionTime FROM myLogTable</code></pre>
<pre><code class="no-highlight">
+---------------------+---------------+
| creationTime | dur |
+---------------------+---------------+
| 2013-11-23 13:27:00 | 10 |
| 2013-11-23 13:27:08 | 11 |
| 2013-11-23 13:27:11 | 9 |
| 2013-11-23 13:27:18 | 13 |
| 2013-11-23 13:27:20 | 13 |
| 2013-11-23 13:27:21 | 25 |
| 2013-11-23 13:27:30 | 9 |
| 2013-11-23 13:27:35 | 30 |
| 2013-11-23 13:27:37 | 15 |
| 2013-11-23 13:27:45 | 8 |
+---------------------+---------------+
</code></pre>
Obviously this data is a little hard to read, wouldn't it by nice to have some kind of a visualisation?<br />
Let's try this query:
<br />
<pre><code class="sql">SELECT id, creationTime, executionTime, repeat('|', executionTime) as graph FROM myLogTable</code></pre>
<pre><code class="no-highlight">
+---------------------+-----+--------------------------------+
| creationTime | dur | graph |
+---------------------+-----+--------------------------------+
| 2013-11-23 13:27:00 | 10 | |||||||||| |
| 2013-11-23 13:27:08 | 11 | ||||||||||| |
| 2013-11-23 13:27:11 | 9 | ||||||||| |
| 2013-11-23 13:27:18 | 13 | ||||||||||||| |
| 2013-11-23 13:27:20 | 13 | ||||||||||||| |
| 2013-11-23 13:27:21 | 11 | ||||||||||| |
| 2013-11-23 13:27:30 | 9 | ||||||||| |
| 2013-11-23 13:27:35 | 30 | |||||||||||||||||||||||||||||| |
| 2013-11-23 13:27:37 | 15 | ||||||||||||||| |
| 2013-11-23 13:27:45 | 8 | |||||||| |
+---------------------+-----+--------------------------------+
</code></pre>
Now we got a graphic representation of the value that shows us anomaly on the first glance.
Manuel Ernsthttp://www.blogger.com/profile/09684560695569145318noreply@blogger.com0tag:blogger.com,1999:blog-2084978728514029221.post-30011036191295453742014-01-02T10:20:00.000+01:002014-01-02T10:20:26.506+01:00Where true or false is not enough!At some point we've found the following code candy in our source code:<br />
<br />
<pre><code>
function str2bool($str) {
if ($str === false or $str === "0" or $str === 0 or $str === "" or $str === "false" or $str === "FALSE" or $str === "falsch" or $str === "FALSCH") {
return false;
}
return true;
}
</code></pre>
<br />
This piece of code is unused and someone forgot about to delete it. But it looks like it was used in one of our externally connected subsystems to translate values like FALSCH, falsch, FALSE to a boolean false. ("falsch" is german for "false")<br />
<br />
We're not sure if there were ever values like "FALSCH" in our code - but it's a little bit scary for us ;)Christopher Schirnerhttp://www.blogger.com/profile/07360883540025860270noreply@blogger.com0tag:blogger.com,1999:blog-2084978728514029221.post-8367874796308381542013-12-12T12:39:00.000+01:002013-12-12T13:15:49.090+01:00Looking into the high resolution timer of node.jsIn the nodejs core a high resolution timer can be found. It is a method of the global <i>process</i> object called <i>hrtime</i>.
<br />
When the method is called an array is returned:
<br />
<pre><code class="bash">$ node
> process.hrtime();
[ 31013, 815378921 ]
</code></pre>
Well, that does not look too useful.<br />
The <a href="http://nodejs.org/api/process.html#process_process_hrtime">official documentation</a> states:<br />
<blockquote>
It is relative to an arbitrary time in the past. It is not related to the time of day and therefore not subject to clock drift. The primary use is for measuring performance between intervals.</blockquote>
So measuring the time between two events is the actual purpose.
The first event is recorded via an call to process.hrtime():
<br />
<pre><code class="javascript">var start = process.hrtime();</code></pre>
Then when a certain operation has been finished (using <i>setTimeout</i> to simulate this),<i> process.hrtime</i> is called again with the start marker as a parameter:
<br />
<pre><code class="javascript">setTimeout(function() {
var elapsed = process.hrtime(start);
console.log(elapsed);
}, 1000);
</code></pre>
Not the output looks like this:
<br />
<pre><code class="bash">[ 1, 14933877 ]</code></pre>
The first element in the array is the elapsed time in seconds, the second element is the additional time in nanoseconds.<br />
So to get an actual useful value out of this array we have to do a little calculation:
<br />
<pre><code class="javascript">var timeInMilliseconds = elapsed[0] * 1e3 + elapsed[1] / 1e6;</code></pre>
Now the result is something like 1014.96679.<br />
Success!<br />
<br />
The complete code example:
<br />
<pre><code class="javascript">var start = process.hrtime();
setTimeout(function() {
var elapsed = process.hrtime(start);
var timeInMilliseconds = elapsed[0] * 1e3 + elapsed[1] / 1e6;
console.log(timeInMilliseconds);
}, 1000);
</code></pre>
If you dont like to do the same operation over and over again there is a high resolution timer module on npm: <a href="https://npmjs.org/package/hirestime">https://npmjs.org/package/hirestime</a><br />
<br />
Install via:
<br />
<pre><code class="bash">npm install hirestime</code></pre>
<br />
Invokation:
<br />
<pre><code class="javascript">var hirestime = require('hirestime');
//startpoint of the time measurement
var getElapsed = hirestime();
setTimeout(function() {
//returns the elapsed milliseconds
console.log(getElapsed());
}, 1000);
</code></pre>
Optionally a timeunit can be assigned:
<br />
<pre><code class="javascript">var hirestime = require('hirestime');
//startpoint of the time measurement
var getElapsed = hirestime();
setTimeout(function() {
//returns the elapsed seconds
console.log(getElapsed(hirestime.S));
}, 1000);
</code></pre>
Possible time units are:<br />
<br />
<ul>
<li><i>hirestime.S</i> the elapsed time in seconds </li>
<li><i>hirestime.NS</i> the elapsed time in nanoseconds </li>
<li>hirestime.MS the elapsed time in milliseconds </li>
</ul>
The timeunit defaults to milliseconds.Manuel Ernsthttp://www.blogger.com/profile/09684560695569145318noreply@blogger.com0tag:blogger.com,1999:blog-2084978728514029221.post-23453209264372065662013-11-27T10:19:00.006+01:002013-12-02T09:58:23.233+01:00Sorting Data in a MySQL query before groupingIn some cases you have the problem that you need to sort your data before grouping it in a single SQL query. Normally it's impossible to do this in a single SQL SELECT statement, because the result is first grouped, then sorted.<br />
<br />
Given a database table which contain images in different resolutions for products like this:<br />
<br />
<pre><code class="no-highlight">+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| article_id | int(11) | YES | | NULL | |
| width | int(11) | YES | | NULL | |
| height | int(11) | YES | | NULL | |
| filename | varchar(255) | YES | | NULL | |
+------------+--------------+------+-----+---------+----------------+
</code></pre>
<br />
Imagine to select only the biggest image for a couple of article ids you could try something like this:<br />
<br />
<pre><code>SELECT article_id, width, height, filename
FROM article_images
WHERE article_id IN(23, 42)
GROUP by article_id
ORDER by width*height</code></pre>
<br />
But you'll only get the first entry for a given article_id, not for the biggest resolution.<br />
<br />
So let's try another approach:<br />
<br />
<pre><code>SELECT article_id, width, height, filename
FROM (SELECT article_id, width, height, filename
FROM article_images
WHERE article_id IN(23, 42)
ORDER by width*height
) as ghoti
GROUP by article_id
</code></pre>
<br />
This query first selects all images in all resolutions for the given article_ids and sorts it by resolution, copying it into a temporary table named <b>ghoti</b>. The query around this subselect then groups the data by article_id. Because we have sorted by resolution before it results in the biggest image for a given article_id.<br />
<br />
<b>ghoti</b> is our name used internally for that kind of SELECT, because we need it sometimes to transfer less data to our PHP scripts and crunch data on the database server. What <b>ghoti</b> means is described in <a href="http://de.wikipedia.org/wiki/Ghoti">this wikipedia article</a>.Christopher Schirnerhttp://www.blogger.com/profile/07360883540025860270noreply@blogger.com0Treppendorf, 96138 Burgebrach, Germany49.802828 10.73209900000006249.792579499999995 10.711929000000062 49.8130765 10.752269000000062tag:blogger.com,1999:blog-2084978728514029221.post-63754562294362431352013-11-22T11:34:00.000+01:002013-11-27T10:52:19.662+01:00Splunk Data AnalyticsWe're using Splunk> Enterprise for about 3 month now and our conclusion is: It's one of the best decisions for our data analytics and processing we could have made.<br />
<br />
Our previous process for logging and analysing data was to store data in a custom mysql table created for that specific logging purpose and reading it with some PHP scripts and pass it to the google charting library on a custom created page.<br />
<br />
Every new analysis took us some hours to implement which reduced our willingness to log anything to nearly zero.<br />
<br />
With Splunk> the logging just went from "to complicated, won't implement" to "what could we log next?"<br />
<br />
We've crafted a logging class which can be used in our current store as easy as it could get:<br />
<br />
<pre><code>Log::info('fun', 'woot', array(
'monkey' => $amountOfMonkeys
));
</code></pre>
<br />
<br />
This results in a key value log event like specified in the <a href="http://dev.splunk.com/view/logging-best-practices/SP-CAAADP6">Splunk> logging best practice guide </a> like this:<br />
<br />
<pre><code>2013-11-22T10:22:18+00:00 mod=fun evt=woot monkey=13</code></pre>
<br />
Now its really easy to do some analytics in splunk with some easy search queries.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo_Q5zxtHp1NYc3_d3rAI0AZC8pAltaz-8Ei4x_ICUszxtOS5nKF3Mi-r3svhau7xU3acz6S2ygSnvAHTWDG6-xH5t4_w22AkH4b7sKfEuWSZZQwG3BSObhrlBsWshqe_Hxj8qrBDiuDcE/s1600/splunk_monkeys.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo_Q5zxtHp1NYc3_d3rAI0AZC8pAltaz-8Ei4x_ICUszxtOS5nKF3Mi-r3svhau7xU3acz6S2ygSnvAHTWDG6-xH5t4_w22AkH4b7sKfEuWSZZQwG3BSObhrlBsWshqe_Hxj8qrBDiuDcE/s640/splunk_monkeys.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The big advantage is, that we can specify our log format by ourselves and don't have to rely on the log format of third party tools. But even with some custom log events you can extract data with the built-in field extractions using regex and start analyzing your data within minutes.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Thanks Splunk!</div>
<br />Christopher Schirnerhttp://www.blogger.com/profile/07360883540025860270noreply@blogger.com0Treppendorf 30, 96138 Burgebrach, Germany49.8019405 10.73196800000005224.279906 -30.576625999999948 75.323975 52.040562000000051tag:blogger.com,1999:blog-2084978728514029221.post-30744828901320824672013-11-21T18:06:00.001+01:002013-11-21T18:06:18.627+01:00The definition of rock 'n roll: when your ads get rejected by youporn.We're about to put some suggestive ads on several porn sites, but somehow YouPorn rejected our "GILP - guitars I'd like to play" ad. Probably too hardcore for them or something.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvYPhRt7P8h_uuAUHEZr4uKBEoANS9K9o5U0iEmk1Aw9ostbLV2OwqEoqv0Sy0NvNgYpLqtsFHnkLg2hOYLAZysO4y2juqzxwxXC_RxLXw_U1ZH_qukkNPLckZgp1du-djhrTmWIoiJy0/s1600/temp7.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvYPhRt7P8h_uuAUHEZr4uKBEoANS9K9o5U0iEmk1Aw9ostbLV2OwqEoqv0Sy0NvNgYpLqtsFHnkLg2hOYLAZysO4y2juqzxwxXC_RxLXw_U1ZH_qukkNPLckZgp1du-djhrTmWIoiJy0/s400/temp7.jpg" width="322" /></a></div>
Davidhttp://www.blogger.com/profile/17993611855811846763noreply@blogger.com0tag:blogger.com,1999:blog-2084978728514029221.post-21563047736000852402013-11-18T11:28:00.001+01:002013-11-22T11:44:47.627+01:00Multiple Monitors on Linux are quite complicatedAs developers we're using a third display for all our important stuff - or at least my colleagues who are using windows... :(<br />
<br />
I tried several times to get my third display up and running on a Ubuntu 12.04 using an Nvidia Quadro NVS 450 graphics card with 4 display ports - and it looks like there's the problem.<br />
<br />
The nvidia graphics card consists of two GPUs with each 2 display ports which can be joined with some tricks.<br />
<br />
<h3>
First Try:</h3>
<br />
First i fired up <b>nvidia-settings </b>and configure my third display to be a seperate X server. Nvidia supports the mode "<b>TwinView</b>" as you suggest for only two monitors. TwinView provides a layer above the first two displays to behave like a single one to my window manager Gnome.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2VcqJwP7-Ys4ntfyj6aO4ZoewocjAHq0oVF7qE2OxeiE5F3mJW9GThPAMjiaLQDnKVkbK_hQggaPCgkw9a_QlfAEnJAeqoT21g99-6Dq3w_2VcrueJ0NfDss5Z2mcrBbwNN5I8C5e0m4U/s1600/displays_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="103" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2VcqJwP7-Ys4ntfyj6aO4ZoewocjAHq0oVF7qE2OxeiE5F3mJW9GThPAMjiaLQDnKVkbK_hQggaPCgkw9a_QlfAEnJAeqoT21g99-6Dq3w_2VcrueJ0NfDss5Z2mcrBbwNN5I8C5e0m4U/s320/displays_1.png" width="320" /></a></div>
<br />
<br />
After storing these changes to my Xorg.conf and rebooting the machine i ended up with a gray background on the third display - which looks like a <a href="https://bugs.launchpad.net/ubuntu-gnome/+bug/1159430">bug in nautilus</a>. Furthermore i can't move the application windows to the seperate X screen by drag and drop.<br />
<br />
But even worse: After disabling the third screen i ended up with additional menus on the top and bottom of my main screen every time I login.<br />
<br />
Which looks like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi660n-jFNi8b1WEFjoZmTpCCMWkJ5Pwiq3WipyIS5ozqBrjkyujdBLw5QWY5qkQDb98IYak7iLUSET3QQMoMf6qsqf7zyUXdwaSnbqsmbV35Q5Km15Q0WVMsYl7d1vswQ_mj4_X0LANIRj/s1600/xYaF3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi660n-jFNi8b1WEFjoZmTpCCMWkJ5Pwiq3WipyIS5ozqBrjkyujdBLw5QWY5qkQDb98IYak7iLUSET3QQMoMf6qsqf7zyUXdwaSnbqsmbV35Q5Km15Q0WVMsYl7d1vswQ_mj4_X0LANIRj/s320/xYaF3.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="color: #999999; font-size: x-small;">source: <a href="http://askubuntu.com/questions/177226/duplicated-menu-panel-indicators-and-taskbar">askubuntu.com/177226</a></span></div>
<br />
The only solution for me was to delete all my gnome config settings in .gnome2 and .config/gnome-* and set all my configurations (shortcurts, etc..) again.<br />
<br />
<h3>
Second Try:</h3>
<br />
Another possibility for this setup is to use "Xinerama" on top of TwinView and the seperate X-Server. Xinerama is a layer on top of this configuration with groups all displays to one big as TwinView would do... but actually it behaves different<br />
<br />
If i click on fullscreen on a single application, my window is stretched across all displays like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwB_jdpJJz6phfyeXdPj_zKLR0DpzbXM11_CFDiIJtB-ssJbs2t9IaeroGsOWYydbkI17qVkfcfCp7Afnihc-j4ZDAOUIIq_hnjGmQPgNuemFYbw33t-AGKW4xfn6kKWg1APP4Fiok2vgA/s1600/xinerama.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="90" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwB_jdpJJz6phfyeXdPj_zKLR0DpzbXM11_CFDiIJtB-ssJbs2t9IaeroGsOWYydbkI17qVkfcfCp7Afnihc-j4ZDAOUIIq_hnjGmQPgNuemFYbw33t-AGKW4xfn6kKWg1APP4Fiok2vgA/s320/xinerama.png" width="320" /></a></div>
<br />
Nevertheless the performance of Xinerama on high display resolutions is quite bad. You can see flickering by scrolling in your browser. For me that's a no-go<br />
<br />
<h3>
Third Try:</h3>
<br />
My for-now last try was to use different window managers like XFCE and awesome (which is my favorite). In XFCE i've experienced quite the same issues like in gnome and awesome behaves totally different as my current workflow is.<br />
<br />
awesome has several workspaces per screen, on my current setup the workspace is shared across all screens which has several advantages like split them into duties (coding, communication (skype, mail...)).<br />
<br />
<h3>
Conclusion:</h3>
<br />
I gave up for now and currently working on two screens, accepting the fun comments from my windows-using colleagues. If you have a solution for this, i would really appreciate if you could share it with me. It totally drives me crazy ;)<br />
<br />
<br />
PS: Switching to windows is not an optionChristopher Schirnerhttp://www.blogger.com/profile/07360883540025860270noreply@blogger.com0tag:blogger.com,1999:blog-2084978728514029221.post-88566151933362540432013-10-31T15:32:00.003+01:002013-10-31T15:32:29.091+01:00Finding good employees is hard<div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial;"><span style="font-size: 15px; line-height: 17px; white-space: pre-wrap;">We’ve been in a very busy hiring phase lately, looking for someone to work at our web development department. We got a lot of applications, a few good guys and many real weird ones.
My favorite is the one who claims:
</span></span><br />
<blockquote class="tr_bq">
<span style="font-family: Arial;"><span style="font-size: 15px; line-height: 17px; white-space: pre-wrap;"> "…by learning several programming languages like HTML and CSS it is possible for me to work on a large spectrum of challenges and to fulfill them."</span></span></blockquote>
<span style="font-family: Arial;"><span style="font-size: 15px; line-height: 17px; white-space: pre-wrap;">
Another one was a constructor of metal planes who likes to work on our website.
Well, what about building our own plane? Maybe that could speed up our deliveries to oversea…
The third candidate was an artist (painter), worked as electrician, with cnc machines, than as a painter, technical drawer, studied architecture, worked at a gas station and in fact did also an educational training as an IT guy.
We’re still hiring, if you know why HTML and CSS are no programming languages, you actually have a web background and ideally love to play and hear music, we want to talk to you!
PS: Bring toilet paper.</span></span></div>
Manuel Ernsthttp://www.blogger.com/profile/09684560695569145318noreply@blogger.com0Burgebrach, Germany49.801987270193543 10.73261260986328149.791738270193541 10.712442609863281 49.812236270193544 10.752782609863281tag:blogger.com,1999:blog-2084978728514029221.post-27593034731679371732013-10-30T17:24:00.000+01:002013-11-18T10:46:48.844+01:00how to kill internet explorer by using cssWhen we started our re-design process earlier in March 2013, we decided to change a few wordings on our webpage (e.g. changing "Thomann Cyberstore" to "Musikhaus Thomann" n stuff). To bypass our quite complicated deploy process for different language files, some developers in our team came to the great idea to transform the first letter of buttons to uppercase using css (which was a requested behaviour by our UX-designer). Later that day we had customers reporting crashes of their browser (Internet Explorer, obviously) and so we started investigating.<br />
<div>
<div>
<br /></div>
<div>
To cut a long story:</div>
<div>
Using a CSS selector with the pseudo-class :first-letter and assigning the text-transform: uppercase; property really isn't a good idea, unless you care for, at least, a minor useable site for IE users (You can see an explanation/demo <a href="http://www.hackerspace-bamberg.de/Benutzer:Schinken/CSS-IE-Crash">here</a>). It somehow crashes all the lonely and unloved Internet Explorer's below and including version 9.<br />
<br />
Fun fact: IE10 was the only version the responsible developer tested before going live. Success!</div>
<div>
<br /></div>
<div>
We also <a href="https://connect.microsoft.com/IE/feedback/details/790265/combination-of-filter-and-first-letter-text-transform-uppercase-freezes-ie8-9">reported this bug</a> to Microsoft, but I guess they're right; it has a limited impact, because transforming a first letter to uppercase by using CSS is simply a bad idea. Period.</div>
</div>
Davidhttp://www.blogger.com/profile/17993611855811846763noreply@blogger.com0tag:blogger.com,1999:blog-2084978728514029221.post-44736831421279480082013-10-30T14:33:00.002+01:002013-10-31T15:33:01.027+01:00memcached key limitations<div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial;"><span style="font-size: 15px; line-height: 17px; white-space: pre-wrap;">We’ve had observed weird cache behaviour on our website, resulting in old or uncached page modules. Our page consists of different parts which are cached separately and it looked like some of them couldn’t write into our memcached cluster. This problem was not reproducible for a single page module, but appeared randomly on the whole page.</span></span><br />
<span style="font-family: Arial;"><span style="font-size: 15px; line-height: 17px; white-space: pre-wrap;"><br /></span></span>
<span style="font-family: Arial;"><span style="font-size: 15px; line-height: 17px; white-space: pre-wrap;">Our default behaviour for cache writing, is to disable the whole cache for the rest of the page if something went wrong. </span></span><br />
<span style="font-family: Arial;"><span style="font-size: 15px; line-height: 17px; white-space: pre-wrap;"><br /></span></span><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 17px; white-space: pre-wrap;">Memcached has some constraints about its key and the data saved inside.</span></span><br />
<span style="font-family: Arial;"><span style="font-size: 15px; line-height: 17px; white-space: pre-wrap;">Some of them are:</span></span><br />
<br />
<ul>
<li><b style="font-family: Arial; font-size: 15px; line-height: 17px; white-space: pre-wrap;">Keys are limited to max. 250 characters</b></li>
<li><b style="font-family: Arial; font-size: 15px; line-height: 17px; white-space: pre-wrap;">Serialized data can’t exceed 1 MB </b></li>
</ul>
<br />
<span style="font-family: Arial;"><span style="font-size: 15px; line-height: 17px; white-space: pre-wrap;">After adding more and more debug messages, which produced gigabytes of log files, we found another (for us) new, relevant memcached key constraint:</span></span><br />
<br />
<ul>
<li><b style="font-family: Arial; font-size: 15px; line-height: 17px; white-space: pre-wrap;">You can’t use spaces in your cachename</b></li>
</ul>
<br />
<span style="font-family: Arial; font-size: 15px; line-height: 17px; white-space: pre-wrap;">That’s even specified in the memcached protocol document</span><br />
<span style="font-family: Arial;"><span style="font-size: 15px; line-height: 17px; white-space: pre-wrap;"><br /></span></span>
<span style="font-family: Arial;"><span style="font-size: 15px; line-height: 17px; white-space: pre-wrap;">But what’s not specified in the document is, that memcached <b>keys </b></span></span><span style="font-family: Arial; font-size: 15px; font-weight: bold; line-height: 17px; white-space: pre-wrap;">can only contain ASCII characters</span><br />
<br />
<span style="font-family: Arial;"><span style="font-size: 15px; line-height: 17px; white-space: pre-wrap;">After fixing these issues our cache hit rate went up again.</span></span></div>
Christopher Schirnerhttp://www.blogger.com/profile/07360883540025860270noreply@blogger.com0