Thursday, March 29, 2012

Two methods for optimize performance for finding comments for template usage in html-documents

Ok, so we are using comments in our project as placeholders for our templating system. We want to do that, since we don’t want to add unnecessary elements to our DOM-tree.
However, finding comments is not as easy as finding for example a div with an ID, since they aren’t a part of the DOM model. And that was exactly why we want to use them in the first place, remember!? J
So how do we find comment elements? Well, one way as we found was to traverse the document using jQuery, but instead of using children() we use contents(). Contents return all content, including comments, making it possible to find them.
However, finding an object in a document-tree manually, by traversing the elements one by one, is a very expensive operation that scales badly. That’s not good, since we need our site and code to be fast no matter how large our page is.

XPath

So what can be done? Well, it turns out that Firefox and Chrome supports xpath lookups, making the comment finding extremely easy. All you have to do is to use document.evaluate together with comment(): 

But this doesn’t work on IE. Too bad, since it’s extremely fast.
However, we know something about our problem. We aren’t interested in just any comments, but comments to be used with our template system. That means that the comments that we are looking for are more likely to be found close to the root of the document tree. In our first implementation we did a traditional, recursive traverse of the document tree, going from root to branch and leaf, one at a time, finishing the previous branch before starting in the next.
That’s not optimal. For the footer templates that mean that we need to traverse through almost the full tree every time before we find it.

Horizontal versus vertical traversing 

The solution then is to traverse the tree one level at the time, starting with looking for the comments one level down from the document root, then two levels down, then three, etc. But however much faster that it, it still means a lot of tree traversal. And what can we do then? 
Cache

Of course, as we all know, the answer is cache. We want to make the comment easy to find. We can’t really store the comment itself, because we can’t insert DOM elements after it. But what we can do is to save the comment’s parent’s location. That way, the next time we need to find the comment, we will start looking directly at the right branch.
Of course, if the templates changes position, if a template placeholder is within another, the comments we’re after might move, or their parents being removed. That’s easy enough to solve; If that happens, we start a new, smart search.

Results

So what are the results of the smart document tree traversal and caching? A great speedup, actually, that gets better as the DOM grows. For a tiny hml-document our optimized version where 40% faster, for a small page (~600 elements in the DOM-tree) the speedup was 150%, and for a normal sized page (~1500 elements) the speedup was 700%!
That’s a good result. Also, as long as the template comments are close to the document root, the optimized version will scale perfectly no matter how large the document is.

(I did this as a part of a project here at Betsson. We do great stuff here and have a lot of fun as well, so check out Betsson's open positions!)

Tuesday, March 27, 2012

A quick comparisson of performance when creating DOM elements using Javascript

Over lunch we discussed the difference in performance when creating DOM elements with native javascript as compared to using jQuery, and the difference in execution time for creating elements to simply reusing old ones.

To test this, we created a short snippet where we added and removed div elements to the body 10,000 times. We created four different cases.

  1. Create everything with jQuery, lookup for elements to be removed using jQuery.
  2. Create everything with jQuery, but cache the elements so that the extra lookup is avoided.
  3. Create everything with jQuery, but instead of deleting objects, save them and reuse them.
  4. Do everything with native xml functions (createElement, removeElement etc), use cache and reuse elements.

I would have expected that the biggest difference would be between case 1 and 3, since object creation is an "expensive" operation.

The results looked like this:

BrowserCase 1Case 2Case 3Case 4
Firefox 111569ms1359ms1105ms496ms
Chrome 17837ms548ms366ms78ms

The results were kind of surprising. Reusing elements are efficient, but not the kind of performance booster as it is in Flash or Cocoa. But what are very clear are two things: jQuery's DOM append is very expensive, and Chrome are a lot faster than Firefox. On Chrome the difference between the original script and the "optimized" case was especially large, with a performance boost of 10 times!

(I did this as a part of a project here at Betsson. We do great stuff here and have a lot of fun as well, so check out Betsson's open positions!)

Monday, March 19, 2012

The All Mighty Johan Ripås-plugin

Jag funderar på om man skulle ta sig an det här med att länka till Johan Ripås på ett lite mer effektivt sätt. Kanske rent av skriva ett plugin till Wordpress. Med några enkla knapptryckningar skulle man kunna få in en länk till Johan Ripås hemsida på alla hemsidor som installerade pluginet.

Hur utvecklar man då ett sånt plugin? Jo, det första man gör är att skapa ett bibliotek i sin wordpress-installation (givetvis utvecklingsvarianten) under wp-content/plugins med namnet johan_ripas.
I denna placerar vi två filer: readme.txt och johan_ripas.php.
I readme.txt skriver vi det vanliga:

=== Johan Ripås ===
Contributors: Aspelund
Tags: Johan Ripås
Requires at least: 3
Tested up to: 3
Stable tag: 3

This plugin adds links to support the cause of Johan Ripås. Nothing more, nothing less.

== Description ==

This is a simple plugin that adds two links to your blogs footer.
One link to [Johan Ripås](http://www.lindqvist.com/tag/johan-ripas/) and on link to [Johan Ripås](http://johanripas.wordpress.com/).
It is not likely that this plugin will ever be updated.

== Installation ==

Use Wordpress' own installation process in the admin guide.

== Changelog ==



I filen johan_ripas.php skapar vi sedan koden som lägger till länkarna till Johan Ripås och Johan Ripås. Vi hookar upp dem mot actionen wp_footer.

class johanripas {
    function add_johan_ripas_link()  {

        echo '
Jag länkar glatt till Johan Ripås och Johan Ripås.
';     } } add_action('wp_footer',array('johanripas','add_johan_ripas_link')); ?>

Notera att vi lägger koden inuti klassen johanripas. Det innebär att vi undviker namnkonflikter. :)
När detta är gjort har vi vår plugin, och det är bara att aktivera den från admin-sidan.

För att göra det lite lättare så har jag sparat det hela som en färdig fil: Johan Ripås - The plugin.

Sunday, September 11, 2011

Tre steg för att lära sig ny teknik



Att ta sig an ett nytt programmeringsspråk, en ny plattform eller kanske ett nytt ramverk kan ibland kännas som en stor och tuff utmaning. Jag tänkte här dela med mig av en snabbvariant av hur jag gör för att snabbt och enkelt lära mig något nytt.

Jag börjar med några ord om min bakgrund. Jag är 34 år, fick min första dator som åttaåring, är civilingenjör och har arbetat professionellt med bland annat ASP, PHP, MySQL, C#, ASP.Net, Actionscript, Perl, Javascript och Zend Framework. Det är när jag har lärt mig dessa tekniker som jag har tagit fram min ödmjuka, och knappast speciellt revolutionerande inlärningsteknik.


  1. Läs mycket och snabbt
    I det här steget handlar det om att få en översikt över den teknik man ska lära sig. Här vill vi inte lära oss detaljer, utan läser mycket och snabbt. Tjocka datorböcker väldigt bra, typ ”Teach yourself C# in 24 hours”, ”Zend Framework bible”. Långa introduktioner på teknikens webbplats kan också vara en bra start, som hela ”Zend Reference Guide” eller hela iOS Developer Library’s ”Getting Started”. Nyckelordet är att man vill läsa mycket. Läs dock snabbt, lägger man två timmar koncentrerat kan man ta sig igenom nästan vilken datorbok som helst medelst skumläsning.
  2. Nu genomför vi ett antal tutorials. Om det inte är helt ny teknik så finns det alltid en stor mängd tutorials att följa. Följ 2-4 tutorials, och genomför själv i din egen utvecklingsmiljö varenda steg och skapa projekt och program/webbplats/app. Se till att allt fungerar. Här slarvläser vi inte längre. När vi stöter på saker vi inte riktigt förstår så slår vi upp det i den digra litteraturlistan vi plöjde i steg 1. Om vi fortfarande inte förstår det så släpper vi det efter en kort stunds fördjupning. Nyckelordet här är att vi försöker förstå. Vissa saker kanske inte klarnar förrän efter flera veckor, och det är helt ok, men det klarnar inte om vi inte försöker.
  3. Nu är det dags att prova vingarna, och vi skapar helt egna projekt med en tydlig målbild för projektet. I den här fasen är det viktigt att försöka göra så mycket som möjligt själv, utan hjälpmedel. Arbeta koncentrerat.
    Givetvis så tar man hjälp av tutorials och texter när man fastnar, allt annat vore dumt.
    Ibland råkar man göra saker som är helt fel för tekniken. Då är det bara att börja om med ett nytt projekt, skapa, pula och dona. För mig är det ofta i det här steget som saker och ting klarnar, och saker som framstod som obegripliga i steg 1 och 2 ger riktiga aha-upplevelser. 


Efter dessa tre steg är vi redo för skarpa projekt. Vi har en relativt bred, men tunn, teoretisk bas att stå på från steg 1, så vi vet ungefär vad man kan göra med tekniken, och var man kan läsa mer. Genom att följa tutorials i steg två så har vi fått se hur erfarna utvecklare hanterar tekniken, och i steg tre har vi fått viss egen praktisk erfarhet.

Sen återstår bara 5000 timmars arbete med tekniken innan man kan kalla sig expert.

(Foto: itzpapalotl's)

Sunday, September 4, 2011

Testning av en klusteralgoritm

Jag pratade med @mattiasostmar igår om olika metoder för att skapa klustrande algoritmer. Här kommer en något text med något högre detaljnivå på temat:
Något som är viktigt om man gör det, är givetvis att inte överoptimera algoritmen för ett visst resultat som man själv ”vill ha”, utan att ha en metodik som minimerar risken för detta.

Ett enkelt sätt som man kan göra det på är att dela upp sina testdata i tre grupper, grupp A, grupp B och grupp C. Viktigt där är att grupp C ska vara stor, så att man kan få resultat som är signifikant.

Den första gruppen, den använder jag aktivt i min testning. När jag ser utfall, då skruvar jag på min algoritm hur mycket jag vill. Jag testar, skruvar, testar, skruvar, tills jag är nöjd med mitt resultat. Grupp A kan vi kalla experimentdata.
När jag går till grupp B däremot, då ska jag egentligen vara rätt så klar med min algoritm. I den gruppen kanske jag kan skruva något litet, för att få bort en överoptimering, men inte mer än så.

Grupp C, det är den gruppen med data som avgör vad jag presenterar för pricksäkerhet för kunden. Om jag har ett stort antal klassificeringar, där min data klassificeras i olika grupper, så kikar jag på varje grupp och och ser hur ofta min algoritm gjorde rätt. Om vi har n tester för grupp n, där jag har 80% rätt, så hämtar jag min gamla Mathematics handbook och slår upp vad det blir för signifikans på det hela. Målet där är ju att kunna skriva ”80%+-4%” eller något liknande.
:-)

Friday, August 26, 2011

Appar & Collage

En snabb uppdatering om vad som händer på Shoppinggatan - Vi håller som bäst på att färdigställa vår första Shoppinggatan-app. Den blir väldigt bra, och jag tror att många kommer att ha stor nytta av den när den är färdig.

I övrigt så arbetar vi på att göra lite PR för vår collageeditor, där man kan göra fina collage som den nedan:

Sunday, April 3, 2011

Att 301:a-redirecta en hel sajt

För en tid sedan hittade vi en av våra utvecklingssajter på Google. Av någon anledning hade vi glömt robots.txt. Givetvis vill man då inte ha kvar sajten, då det kan bli problem med duplicate content och en mängd annat, samtidigt var vi lite osäkra på exakt hur Google skulle reagera på att ett antal tusen hårdkodade länkar till vår sajt plötsligt försvann; För på vår sajt är vissa länkar kodade relativt, medan andra är hårdkodade.
Det enda riktiga att göra i den situationen tyckte vi var att 301:a alla sidor till den skarpa sajten. På det sättet borde problemen minimeras, även om det inte är helt sjävklart vad som händer när man hanterar problemet.
Sagt och gjort. Att 301:a en hel sajt i Lamp-miljö är ingen stor sak. Tre rader kod i .htaccess för den givna sajten var allt som behövdes:


RewriteEngine on
RewriteBase /
RewriteRule ^(.*)$ http://www.shoppinggatan.se/$1 [R=301,L]


Redirecten slår igenom momentant och Googles robotar kommer att förstå vad som har hänt.

Tuesday, March 29, 2011

Desigual - Spännande kläder

Klänning från Desigual



Det är väldigt spännande att jobba med Shoppinggatan, för man får alltid lära sig massor av nytt. Idag blev jag uppmärksammad av Jenny om klädtillverkaren Desigual: Ett spanskt street-märke med spännande och uttrycksfulla kläder.
Det visade sig att vi har rätt många plagg från Desigual på Shoppinggatan, och en liten googling visade att det är ett väldigt populärt märke i blogosfären, många har upptäckt vilket spännande tilltal de har. Eller vad sägs om den här fantastiska kappan som presenteras under rubriken Dagens Bokfit. Hur snygg som helst!

Det är kul att upptäcka nya märken, speciellt när det är något coolt, snyggt och inspirerande!

Saturday, March 26, 2011

Arbete med Google Page Speed Score

Idag har jag arbetat lite med Google Page Speed Score för vår shoppingsajt Shoppinggatan. Givetvis vill jag att sajten ska vara så snabb som möjligt, men som med allt i livet så handlar det ofta om kompromisser, där man prioriterar det som är viktigast.

Google Page Speed finns som ett instick till Firebug, och man får ett helhetsbetyg för sin sajt (0-100) och en lista över punkter som verktyget granskar. Om man uppfyller verktygets krav så syns det en liten grön "lampa" bredvid punkten, och om man inte gör det så blir lampan orange (om det är lite smådåligt) eller röd (om något är tokdåligt).

Och givetvis försöker man bearbeta de rödmarkerade punkterna först. Idag har jag exempelvis arbetat med cachningen av de bilder som hanteras av Amazons CDN. Genom att lägga till expirtion och cache-control kunde jag enkelt förvandla en röd punkt till en grön.

På många sidor märks inte en sån liten ändring, men på en sajt som Shoppinggatan, där man surfar mellan sidor med kläder, inredning och möbler, får man se hundratals småbilder. Då kan cachning av bilderna göra stor skillnad för användarens sajtupplevelse.

Dagens förmiddagsövning gav ett litet resultat: Sidan gick från 85 till 90 i "betyg" med Google Page Speed Score.

Friday, May 14, 2010

Varumärken på Shoppinggatan

Dagens media kan man idag läsa att Acne, Odd Molly och Cheap Monday är de varumärken som dominerar på webben. Givetvis intressant läsning, och Google Insights visar på samma sak.

I vårt arbete på Shoppinggatan är det givetvis viktigt för oss att ha ett så brett utbud som möjligt inom just mode: Kläder är Shoppinggatans primära målgrupp, så klänningar, jeans, blusar och byxor från bland annat Odd Molly och Cheap Monday såg vi tidigt till att få in i vår sociala sökmotor.

En översyn visar dock att vi just nu faktiskt inte har några produkter från Acne. Ett stort fel med tanke på hur populära de är, och något som vi kommer att ta tag i inom kort.

På Shoppinggatan strävar vi alltid efter att ha ett brett och kvalitativt utbud inom just kläder, inredning och möbler, och vi har i dagsläget över 100,000 varor från Sveriges 150 främsta webbshoppar.

Utveckling i full fart

Just nu håller vi på att göra om utseendet på Shoppinggatan. Sveriges bästa sociala sökmotor inom mode & inredning ska bli snyggare, snabbare och mer social.

När vi valde webbhost för Shoppinggatan la vi stor vikt vid stabilitet, och valde Amazon EC2. Amazon har väldigt stabila tjänster, och nertiden har varit obefintlig.
Dock så är svarstiderna inte riktigt lika bra, och därför lägger vi mycket krut på att göra grafiken mycket mer snabbladdad. Bland annat använder vi oss numera av CSS-sprites, något som säkerligen kommer att minska på laddningstiderna ordentligt.

I juli kommer en uppdaterad, snygg version av Shoppinggatan att se dagens ljus, så kika in på sajten med jämna mellanrum för att se hur arbetet fortskrider.

Thursday, February 11, 2010

Vårt arbete för vår målgrupp ger oss en långsiktig konkurrensfördel

Idag är det drygt ett och ett halvt år sedan vi på 49lights öppnade upp den första versionen av Shoppinggatan.se för allmänheten. Jenny, 49lights vd, hade en tydlig vision av vem hon främst ville attrahera med sajten; Unga, inrednings- och modeintresserade kvinnor mellan 20 och 35 år. Ett naturligt val, då Jenny själv befinner sig mitt i målgruppen. En tydlig målgrupp, som för oss hela tiden har fungerat som ett rättesnöre när det gäller allt från val av webbshoppar, produkter, bokrekommendationer, blogginlägg och reklam. Vi ville naturligtvis också vara attraktiva även mot en bredare målgrupp, sajten ska vara välkomnande och inkluderande för alla, men som sagt fungera extra bra mot vår primära målgrupp.

Jag vet inte hur många gånger vi har suttit runt bordet och bråkat om innehållet. Till synes attraktiva reklamerbjudanden och affiliateavtal har förkastats på grund av felaktig värdegrund (här kan man nog läsa att sajter har försökt sälja kläder med sexuella anspelningar och unga, lättklädda tjejer).

På samma sätt har vi stött och blött SEO-ansatser, där jag och Peter som webbanalytiker har lyft fram sökord som borde ge många besökare. ”Stoppa in fler varumärken i rubriken”, ”En lista över fiffiga sökord längst ner på sidan”, och säkert ytterligare 1000 förslag grundade i SEO.

Men Jenny har stått bergfast i sin syn på sajten. Det som inte har passat med det varumärke som vi tidigt slog fast har inte släppts in. Det som inte tillför besökaren något har heller ingen plats på sajten. Och utifrån de ramarna har vi arbetat med Shoppinggatans SEO.

Som utvecklare och medgrundare av sajten har jag givetvis många gånger känt stor frustration – snabba pengar och snabba ökningar är givetvis något som känns lockande. Just därför känns det numera väldigt skönt när man kikar på segmenterade besökarna i Google Analytics, då jag kan stämma av att just målgruppernas användning av sajten stämmer överens med vår målsättning.

För det gör den. Vi kan exempelvis se att av Shoppinggatans besökare är 75% kvinnor och lojaliteten bland 20-30 åriga tjejer är 181% högre än hos en genomsnittlig besökare. Vi vet alltså att vi har lyckats locka precis de besökare vi ville, och att det viktiga lojalitetsmåttet ser allra bäst ut för den åldersgrupp som ligger närmast vår målgrupp.

Samtidigt kan vi se att besökarantalet hela tiden ökar. Januari 2010 hade 394% fler besökare än januari 2009 och 14% fler än i december 2009, och vi ligger numera på dryga 50,000 unika besökare och 350,000 sidvisningar per månad. Vi är definitivt inte i mål ännu, men tiden talar för oss.

Jag tror att vårt sätt att förhålla oss till en målgrupp är rätt. Det har gett oss ett varumärke som är tydligare än våra konkurrenters, och det ger oss en fördel bland besökare i allmänhet och de i målgruppen i synnerhet.

Tuesday, February 9, 2010

Kvinnor 116% mer klickbenägna på leksaksannons

Inlägget är flyttat till 49buzz - en företagsblogg: Kvinnor 116% mer klickbenägna på leksaksannons.

Friday, July 10, 2009

Javascript MVC


När man jobbat mycket med Javascript så är det lätt hänt att man tappar lite av den kontroll man gärna vill ha i ett projekt. Så därför håller jag på att utveckla en MVC-modell för våra projekt, baserat på prototype.js. So far, efter knappt 600 rader kod, verkar det lovande, jag har försökt att efterlikna sättet Zend Frameworks API, då det onekligen är ett rätt genomtänkt API.

Ett snabbt exempel på hur det kan se ut:

// Script-delar:
...
// Modell för favoriter:
var FNLModel_Favorites = Class.create(FNLModel,{
   init:function($super, params){
      this.primary_key='user_product_id';
      $super(params);
   }
});   
...
// Javascriptdelen av view för favoriter
var FNLView_SingleSmallFavorite = Class.create(FNLView_Simple,{
   init:function(params){
      this.template = 'TEMPLATE_SINGLE_FAVORITE';
   }   
});
// Javascriptdel av en view för en favoritlista
var FNLView_SmallFavoriteList = Class.create(FNLView_Simple,{
   init:function(params){
      this.template = 'TEMPLATE_SMALL_FAVORITE_LIST';      
   },
   render:function($super,self){
      var str = '';
      for(var i=0;i<self.favorites.length && i<15;i++){
         self.favorite = self.favorites[i];
         str += self.render('SingleSmallFavorite');
      }
      self.favoriteContent = str;
      return $super(self);      
   }
});
...
// Controller för favoriter
var FNLController_FavoriteListLeft = Class.create(FNLController,{
   init:function(params){
      var self = this;      
      this.target = params.target;
      var callback = this.callback.bind(this);
// Lyssna efter uppdateringar av favoriter via ajax
      this.fnlTools.addEventListener({id:'favorites',event:FNLToolsEvents.ajaxResponse,callbackFunction:callback});
// Och se till att favoriterna uppdateras vid serveranrop.
      this.fnlTools.registerAjaxListener(this,FNL_CLUB_LISTENER_URL, 'favorites','user_product_id',-1);
      this.id=fnlTools.newUID;
   },
   callback:function(event){
      this.view.favorites = event.model.data;
      this.view.fnl_id = this.id;         
      str = this.view.render('SmallFavoriteList');         
      $(this.target).innerHTML = str;   
            
// Uppdatera serveranroparen så att den bara kollar efter nya favoriter
      this.fnlTools.updateAjaxListener(FNL_CLUB_LISTENER_URL, 'favorites',event.model.max());            
   }
});

...

// init-kod
fnlTools = new FNLToolsClass();
var productListUpdater = fnlTools.getController('ProductList',{target:'productList3'});


samt html-element som fungerar som templates:
<div id='TEMPLATE_SMALL_FAVORITE_LIST' style='display:none'>
#favoriteContent#
</div>
<div id='TEMPLATE_SINGLE_FAVORITE' style='display:none'>
<a target="_blank" href="#favorite.p_url#"><img width="44" title="#favorite.name#" src="http://stat2.shoppinggatan.se/public/images#favorite.thumb_local_url#" style="border: 2px solid rgb(201, 205, 208);"/></a>
</div>



Och vad gör då detta exempel? Jo, ett element med favoritprodukter skapas, och hålls dessutom uppdaterad om nya favoriter läggs till, endera i samma dokument, eller från en annan instans (för samma användare). Givetvis hanterar den dessutom hur många element som helst med samma innehåll, alla hålls uppdaterade i vilket fall. Det är också mycket lätt att hålla koll på alla events som sker på samma sida.

Om man tex skulle skriva ett litet chatrum med den nuvarande modellen så tror jag att det skulle handla om ca 30 minuters arbete, från start till mål. Givetvis inte aktuellt, då jag inte känner någon som chattar längre, men jag tycker ändå att det visar på kodens styrka. Javascripts svaghet med bara visst stöd för klasser syns i koden, men med Prototypes klasshantering så blir det lite enklare att koda.

En fundering som jag har är om det ska vara en instanserad controller per element, eller en instanserad kontroller per aktivitetstyp.

Om du är intresserad av att veta mer om det här, så är det bara att höra av dig.

Sunday, July 5, 2009

Reinfeldt sågar Amazon EC2


Som en del i regeringens förberedelser för höstens IT-proposition har statsministern och samtliga statsråd utvärderat varsin webhost. För statsminister Fredrik Reinfeldt föll lotten på Amazon EC2.
”Jag blev glad när jag fick veta att jag skulle testa Amazon – som partiledare har Amazon länge varit en fantastisk källa för litteratur inom statsvetenskap, och molnet har det talats rätt mycket om i Rosenbads korridorer.”

Men glädjen var kortvarig: ”Amazon är en användarmässig katastrof. Dokumentationen är mycket bristfällig, och arbetet med att skapa en Amazon-instans som passar just regeringens behov tog på tok för lång tid. Jag antar att en riktig Linux-hacker skulle klara det väldigt bra, men för en glad amatör som jag själv har det varit en mardröm.”

Reinfeldts stora kärlek till Open Source och molnlösningar är annars en välkänd historia. ”Hemma kör vi inget annat än Ubuntu. Många kollegor säger att Linux inte kan mäta sig med Windows som skrivbordsoperativ, men med den senaste versionen av Gnome finns det inte längre några ursäkter – Linux borde vara det naturliga valet för alla datoranvändare.”

Inom regeringen går åsikterna dock isär. Sten Tolgfors sägs vara en inbiten Mac-entusiast medan Sven Otto Littorin vägrar köra något annat än Windows XP. Göran Hägglund är den udda fågeln med FreeBSD.
”FreeBSD passar KD utmärkt”, berättar Hägglund. ”Min datortekniker säger att den påminner väldigt mycket om partiet – värdekonservativ men ändå frihetsbejakande. Och liksom KD är operativsystemet något av en underdog.”

Tuesday, June 16, 2009

Camping & Vildmark med Streamline

En av 49lights senaste kunder är Beoutdoor.se. Beoutdoor är störst i sverige inom fiske och vildmark, och har ett utbud som verkligen tillfredsställer friluftsmänniskan inom oss.

Det senaste vi har gjort på Beoutdoor är att lägga in Streamline. På sidan om camping och friluftsliv ser man just Streamline i aktion. Där visas ett utbud av produkter upp, anpassat till just Beoutdoors besökares historiska aktiviteter på campingsidorna.

Om man vill gå in på detaljer så kan man i korthet säga att alla produkter har ett unikt DNA, och att Streamline på sidan placerar ut dem så att produktrummets yta får maximal täckning.

Ta gärna en titt på hur Streamline täcker produktrummen för kategorierna jakt och kläder.

Sunday, May 24, 2009

Amazon EC2 - nu är vi uppe och rullar

Nu har vi äntligen tagit klivet fullt ut och efter en veckas provtid och en vecka av mindre justeringar så ligger nu Shoppinggatan helt på EC2.
Som jag har beskrivit tidigare finns det många anledningar som gör Amazon till en lämplig host för Shoppinggatan. Skalbarheten, enkelheten, låga priser på såväl datorkraft som utrymme gör det helt enkelt tryggt för oss att välkomna nya kunder, nya produkter och nya språk.

Tuesday, May 19, 2009

Amazon EC2 - Prestanda och Raid

Medan jag skriver det här förs den senaste versionen av databasen så sakteliga över från våra gamla servrar till Amazon - vi närmar oss slutspurten i migrationen av Shoppinggatan till Amazons roliga och intressanta EC2.

Under veckan som har gått så har vi testat, utvärderat och ändrat i våra konfigurationer mot EC2, med blandade resultat och bara några få riktiga snedsteg.

Godbitar från veckan:
EC2 disk performance - det är otroligt lätt (och billigt) att sätta upp ett raidsystem, med stor förbättring av prestandan. Det betyder att backup måste göras lite annorlunda (enkel snapshot räcker inte), men hastigheten ökar dramatiskt.
All about Linux Swapspace - utrymmet på EC2 är billigt, så lagom stort växlingsutrymme känns som ett måste.
Sysbench - yum install sysbench är ett underbart litet kommando för att snabbt kunna utvärdera din server.
Recursive text file find and replace - Ett litet script som jag gjorde för att snabbt söka och ersätta i flera textfiler, bra att ha verktyg om jag är tvungen att flytta tex databasservern till en ny instans med ny ip, och därför behöver ändra mina konfigurationsfiler på apacheservern.

Uppdaterat: Raid kan, precis som med fysiska diskar, vara rätt struliga. Jag vill bara poängtera att jag bara rekommenderar RAID på ec2 till den som är väl insatt i det.

Monday, May 11, 2009

Amazon EC2 revisited

Nu i helgen har vi arbetat ytterligare lite med Amazons elastiska moln, Amazon EC2. Den trogna läsaren vet att vi gillar Amazon och kör CloudFront och S3 (för statiska filer). Dessbättre har vi under den senaste tiden drabbats av ett angenämt problem - besökarna ökar på Shoppinggatan samtidigt som våra kunder blir fler och större. Trevligt som sagt, men det innebär också att vår flytt från vår nuvarande serverlösning har blivit än viktigare, och en flytt till Amazons EC2 känns som ett rätt stabilt och prisvärt alternativ med tanke på deras stabilitet och skalbarhet.

När jag kikade på EC2 senast var den europeiska parken relativt ny, och det var lite strul med Amazons verktyg framförallt kring arbetet med AMI'er.
Idag är situationen delvis annorlunda - Amazon har skapat ett trevligt litet webinterface som gör det lätt att hantera instanser, och även deras java-tools fungerar numera som förväntat.

Så här såg vår process ut:
1) Vi valde en bra start-ami (centos) och skapade en ny instans
2) Skapade en stor volym (50 gig) och mountade den mot vår instans
3) Konfigurerade ami så att LAMP fanns och levde tillsammans med alla nödvändiga extensions (Tack gode gud för Yum!)
4) Konfigurerade LAMP så att all data ligger på den mountade volymen.
5) Importera data och se att allt fungerar
6) Skapade en ami av den fungerande instansen med ec2-bundle-vol, ec2-upload-bundle och ec2-register.
7) Reservera en eller två ip-adresser så att vår DNS kan pekas rätt
8) Stoppa instansen och starta en ny - fungerar allt som förväntat?
8) Done - allt klart för att köras - och behövs en ny instans så är allt förberett.

Och det härligaste med EC2 - vi bestämde oss för att lägga databasen på en egen instans. Och en timme senare är det klart, allt hänger bara på din initiala AMI!

Några tips:
* Se till att volymerna är tillräckligt stora. 50 gig i en volym är billigt. Ingen fara om de inte är det förstås, då det är superenkelt att skapa nya volymer och skicka över datan dit.
* Dokumentera allt du gör - ordentligt. Linux kan ibland vara lite som en Minoisk labyrint och du vet aldrig när du måste börja om från början.
* Se till att imagen som du skapar med ec2-bundle-vol är tillräckligt stor, för en AMI ändrar du inte lika snabbt som en volym. (Det tar minst 30 minuter, det vet jag av egen erfarenhet när sda plötsligt var tomt på utrymme imorse :-))
* Lägg inte privata nycklar på AMI'n, lägg dem på en volym
* Ha all data utom temporär på volymen (så försvinner inte allt varje gång du stoppar en instans ;))
* Slösa inte tid på iptables - Amazon har ett fullgott skydd med sina inbyggda zoner.
* Rent praktiskt så ändrade jag i /etc/my.conf för att sätta databas till min mountade volym som alltid mountades på samma ställe.
* Samma sak för httpd, jag la till /etc/httpd/conf.d/fnl.conf som i sin tur inkluderade conffiler från den mountade volymen.
På så sätt kan jag alltid ändra uppställningen via den mountade volymen.
* Tänk på regionerna - en dator i usa ger långsam access för oss svenskar. Själva ligger vi i eu-west-1, eller för att vara mer exakt eu-west-1a.
* Googla som en tokig. Det mesta har gjorts förr. Men tack vare Amazons snabba utveckling är en stor del av dokumentationen obsolet, så förvänta dig ingen 1-2-3 tutorial.

Thursday, April 23, 2009

Med ett öppet API kan funktionsnedsatta Twittra!

Jag fullständigt älskar öppna apier (och jag tror att de gillar mig också). De främjar snabb utveckling och låter oss skapa verktyg för att på bästa möjliga sätt utvinna rätt information för rätt tillfälle. Vi finns här för att göra gott, och har inte så många år på oss, och som vanligt kan samarbete hjälpa oss att nå vår fulla potential.

För Twitter är deras öppna API en förutsättning för deras framgångar, men artikeln om "Twittertelepati" på Wired (hittad via Jardenberg) ger mig rysningar! Neuroforskare vid universitetet i Wisconsin har kopplat ihop en textredigerare, som styrs med hjärnans elektromagnetiska vågor, med just Twitter. Själva apparaten är förvisso imponerande, men den känns som en naturlig utveckling inom medicinteknik. Att koppla den till Twitter däremot, är hur coolt och imponerande som helst!

Kopplingen är förvisso inte svår, men tanken att personen med behov av apparaten för kommunikation helt plötsligt får tillgång till sociala nätverk är fantastisk. Höjningen av livskvalitet och möjligheten att kommunicera på lika villkor finns ju där. Visst är det smått fantastiskt!

Så för att sammanfatta: Ett öppet api behöver inte bara innebära att man främjar asynkront samarbete, utvecklare emellan, utan kan innebära att man gör något riktigt gott för världen! Karma++ på Twitter!