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!