Basic personligt

Daniel Brahneborgs blogg

Den italienska buggen

För ungefär ett år sedan gjorde jag en anpassning av vår SMS-gateway åt en kund i Kanada, för att förändra beteendet på den lite grand. De testade järnet ur den, för att sedan skicka den till sin kund i Italien. Det dök upp lite småsaker på vägen, men inget avancerat.

Men, så för några veckor sedan, började det hända konstigheter. Det speciella med den här installationen var att det inte skulle finnas några köer, utan allting skulle skickas omedelbart. Det började bra, men plötsligt så fanns det hos italienarna inte bara köer, utan det var även förseningar på uppåt en halvtimme. Att kalla det för oacceptabelt var bara förnamnet. SMS blev duplicerade, billingen blev helt uppfuckad, italienarnas kunder blev tokiga, osv. Det blev helt GALET, kort sagt.

Jag hittade problemet, vilket nästan helt och hållet var en konfigurationsmiss. Så som vårt system och de runt omkring var konfigurerade, gick det helt enkelt inte att klara sig undan vissa förseningar. Så jag beskrev situationen, och förklarade vad de behövde göra. Dagen efter är det telefonmöte, då italienarna kräver att jag åker ner, för att hantera denna allvarliga situation. Öh, va? Problemet var ju liksom fixat redan?

Nåja, jag åker ner, förklarar allting några gånger till, och sitter sedan mest på hotellrummet och jobbar med mer normala saker. Jag och min chef kommer till slut överens om att det är dags att åka hem, varvid italienska chefen får frispel och skäller på kanadensarna för att jag inte stannade längre. Helt förvirrande. Tydligen skulle någonting bli bättre i världen om jag satt och ruttnade i ett hotellrum i en vecka till. Att sitta på deras kontor gick alltså inte, eftersom det inte fanns någon fungerande internetuppkoppling.

När jag har varit hemma någon dag så händer det som verkligen inte får hända, det börjar dyka upp köer och förseningar igen. Jag skriver flera småprogram för att analysera logfilerna, men hittar ingenting. Bläddrar för hand upp och ner, men ser inga mönster. Inga teorier håller. Nytt telefonmöte, ännu surare italienare, och ännu mer frustrerade kanadensare.

Till slut går italienarna med på att köra med maximal loggning på en av maskinerna. Då ser jag i vilket område det går fel, så de får en ny version med extra mycket loggning just där. Medan jag väntar på de loggarna blir italienarna ännu tokigare, och kräver att jag åker ner igen. Det skulle vara ett telefonmöte om det igår eftermiddag. Chefen är offline, och jag har egentligen varken mandat att åka iväg eller begära pengar från någon kund för det. Nåja, det skulle få lösa sig i så fall.

IgÃ¥r förmiddag fick jag de nya loggfilerna, och förstod till slut vad som var fel. I vissa situationer används tvÃ¥ köer istället för bara en, och koden som ska plocka saker frÃ¥n kön kollar dÃ¥ frÃ¥n fel kö. Tänk dig tvÃ¥ kassor pÃ¥ Ica, där den enda kassörskan sitter i den kassa som det stÃ¥r “Stängd” pÃ¥. DÃ¥ gÃ¥r det inte sÃ¥ fort att handla. Jag vet faktiskt inte hur jag ska beskriva hur det kändes att äntligen se sambandet efter en veckas grävande, med sura kunder som blir alltmer frustrerade och vill se det fixat omedelbums. Hade det inte varit för att jag inte dansar, sÃ¥ hade jag gjort det.

De fick snabbt en ny version, men skulle inte köra den i produktion förrän i morgon. Sedan är det bara att hålla tummarna.

Som extra humor… det jag hade jobbat med om jag inte hade behövt Ã¥ka fram och tillbaka till Milano förut, eller sitta i telefonmöten och förklara samma sak som man precis har beskrivit i mail till samma personer, är att implementera nya funktioner beställda av samma kanadensare, som förmodligen ska användas av precis samma italienare. Ibland blir det bara knäppt.

April 12th, 2011 Posted by Daniel Brahneborg | blogg | no comments

C-programmerare sökes

Som bekant så jobbar jag som C-programmerare på Infoflex Connect. Viss tid går åt till PDF-generatorn form2pdf, men den mesta tiden tillbringas med att vidareutveckla SMS-gatewayen EMG. Vissa dagar består mest av supportmail av den här typen:

Kund: Hur gör man bla-bla-bla?

Jag: Man sätter flaggan hejsan-hoppsan.

Kund: Tack, nu funkar det.

Jag stänger ärendet.

Men så finns det ju då de där projekten som vi ibland skjuter framför oss i flera år, helt enkelt för att vi inte kommer på en tillräckligt bra lösning. I det senaste fallet är vi nu uppe på den fjärde implementationen innan vi fick acceptabel stabilitet (får aldrig strula någonsin) och prestanda (så snabbt att det förmodligen bryter mot några naturlagar). Inte för att någon av oss är korkade, utan för att är så komplext.

Samtidigt som man jobbar med en sådan implementation i någon månad eller två innan allting sitter som det ska, dyker det vanligen upp supportmail där man får sitta och gräva i några hundra MB med logfiler, skapade av dussintals eller ibland hundratals separata trådar. De mailen är sällskapssjuka, så de kommer ofta ett par stycken på samma gång. Problemet är nästan alltid att systemet i andra änden är buggigt, eller bryter mot någon specifikation.

När jag pratade med personerna frÃ¥n en rekryteringsfirma nyligen, sÃ¥ pÃ¥stod de att en beskrivning av jobbet som “sÃ¥ komplext att man sliter sitt hÃ¥r, dunkar huvudet i bordet och funderar pÃ¥ när man ska börja kräkas av blödande magsÃ¥r” inte lät lockande. Skumt. Riktigt sÃ¥ illa är det kanske inte, men risken för att det ska kännas slentrian och lÃ¥ngtrÃ¥kigt är exakt noll.

Yup, jag är stolt som fan över EMG. Men, nu är det dags att öka tempot, så jag ska få en kollega. Gillar du utmaningar, tycker jag att du ska höra av dig.

March 27th, 2011 Posted by Daniel Brahneborg | blogg | 2 comments

Grekisk telefonröstning

För tredje året i rad så stod vår mjukvara EMG för hanteringen av SMS-röster i den grekiska uttagningen till melodifestivalen. Jag skrev lite om det första året, men tydligen missade jag att skriva någonting förra gången.

I år hade de köpt en ny server, så vi hjälpte till att flytta över mjukvara och konfigurationsfiler. Vissa saker hade ändrats, så det har blivit en del pillande och testande fram och tillbaka. Till slut verkade allting fungera, med bra prestanda.

De hade avtal med tre operatörer. Den ena skulle använda en ny uppkoppling, men detaljerna var inte klara förrän i går morse. Lite småstrul senare så funkade även det, så 16.30 begav jag mig hemåt. Programmet skulle börja 21.00, så det kändes bra.

Halvvägs hemma så kollar jag läget i mailboxen, och ser att sms från den här tredje operatören plötsligt inte fungerar. Innehållet ser konstigt ut i logfilerna, och rösterna räknas inte. Skoj.

Det enda sättet att testa var att min kontakt i Grekland, som jag nu hade i en skypechat, fick skicka premium-sms för 5 kronor styck varje gång. Jag avslöjade att det var min ondskefulla plan för att ruinera den grekiska ekonomin (som om den behövde hjälp med det), men några kodändringar och konfigurationsändringar senare så gick allting igenom igen. Klockan närmade sig då halv åtta, så vi gick iväg och hämtade några grillspett från den grekiska restaurangen precis bredvid. Påminn mig förresten om att inte köpa hämtmat när det är kallt ute. Att ha en marginal på ett par timmar inför ett live-arrangemang är väl helt ok?

Programmet sändes pÃ¥ nätet, sÃ¥ jag la upp ett browserfönster pÃ¥ tv’n, samtidigt som datorskärmen täcktes av skypechatten, där nu hans kollegor hade gjort oss sällskap, ett browserfönster med realtidsinformation om rösterna, och ett fönster som visade status pÃ¥ servern.

Det märktes verkligen att Grekland är fattigt. Det var den trÃ¥kigaste budgetproduktion jag har sett. Lokal-TV pÃ¥ 80-talet, ungefär. Publiken bestod av ett par dussin människor, som tydligen dessutom satt i ett annat rum. Programlederskan fick namnet “isdrottningen” av grekerna i skypefönstret. Hennes enda reaktion efter de 6 lÃ¥tarna var ett totalt känslokallt “bravo”. Tänk Teliapappans “du var jätteduktig”, fast utan nÃ¥gon inlevelse. Sanslöst.

När det var röstningsdags så kom det ungefär en tiondel av den trafikmängd vi hade klarat av, men det verkar till stor del ha berott på operatörerna. Svaren köades upp och skickades efter att omröstningen var klar, och det gick banne mig inte snabbt. Allting verkar ha hanterats korrekt i alla fall.

Vinnare blev en kille som verkar ha fÃ¥tt betalt efter hur länge han kunde hÃ¥lla varje ton, ackompanjerad av rapparen “Stereo Mike”, samt nÃ¥gra akrobater som hoppade upp och ned pÃ¥ ett pingisbord. Det känns inte som en högoddsare att säga att Grekland inte kommer avgÃ¥ med segern i Tyskland senare i vÃ¥r. ÄndÃ¥ blev det en utklassningsseger, där han fick lika mÃ¥nga röster som de andra fem sammanlagt. Helt galet.

Men ändå. Att veta att det är min kod som körs när de där rösterna kommer in, är häftigt som fan.

March 3rd, 2011 Posted by Daniel Brahneborg | blogg | no comments

Mitt namn i en bok!

Den korta versionen:

Jag är med som “technical reviewer” i den nya “The Linux Programming Interface“!

Den långa versionen:

1976 träffade min mamma Håkan. Då och då umgicks vi med hans barndomskompisar, bland annat Janne. Janne i sin tur jobbade som programmerare på Paralog, med fritextdatabasen Trip. Den kördes i VMS, och från 1989 och några år framåt jobbade jag där för att stegvis flytta den från Pascal i VMS till C i Unix. 1990 eller 1991 fick jag gå en unixkurs, och som lärare hade vi en kille som hette Michael Kerrisk.

Många år senare hittade jag honom igen, varvid det visade sig att han höll på att skriva en bok om just Unix. Det skulle handla om systemprogrammering, dvs så nära operativsystemets kärna som det går att komma. Det var på den nivån jag hade jobbat med Trip, så jag fick några tidiga versioner av ett par kapitel för att korrekturläsa både text och programkod. Det blev några vändor fram och tillbaka.

Det gick nÃ¥gra Ã¥r till, Michael Kerrisk jobbade mycket med dokumentationen till Linux, och nu lite innan jul släpptes boken till slut. Drygt 1500 sidor, 2,3 kg. Först kommer ett “brief contents” pÃ¥ 3 sidor, och sedan en mer fullständig innehÃ¥llslista pÃ¥ 19 sidor till. Massvis med tabeller och programlistningar.

Det snälla bokförlaget (no starch press) gick med pÃ¥ att skicka ett exemplar till alla som hade hjälpt till med boken, vilket inkluderade mig. Jag är även med i en “thanks to”-lista i förordet, vilket känns lagom bisarrt. Kul, men bisarrt.

Den innehåller verkligen hur mycket information som helst om hur man programmerar multitrådat, sockets, och allt vad det är. Av naturliga skäl har jag inte hunnit gräva så djupt i den än, så en mer fullständig sammanfattning och recension kommer så småningom. Dessutom har jag tyvärr ett halvdussin databöcker på min läslista redan.

January 22nd, 2011 Posted by Daniel Brahneborg | blogg | no comments

Bekräftat: Berkeley DB stödjer inte massiv parallellism

Jag upptäckte ju tidigare att Berkeley DB inte klarar av att det är mer än kanske max 100 trådar som samtidigt anropar funktioner i det, utan att prestanda rasar ner till löjliga nivåer. I mitt fall löste jag det genom att samla ihop anropen till 10 trådar med en connection pool, men det kändes mer som en pinsam workaround än en korrekt lösning. Oracle fick därför en fråga om varför det var på det här sättet.

Efter att ha skickat mina testprogram och skruvat på massor av parametrar för att förbättra prestandan, fick jag till slut ett tydligt svar. De höll med om att min pool var ett bra sätt att lösa det hela på.

The slowdown is not caused by a linear search, but by the low-level latching primitives provided by nearly all existing instruction sets. We use these primitives (e.g., test-and-set or locked compare and exchange) to implement mutexes and shared latches. As the number of threads “fighting” for a mutex increases, there is more overhead, both down in the CPU chip’s cache coherency system as well as in the operating system and BDB software above it.

De använder tydligen posix mutexar för den här synkroniseringen. Min pool är gjord med pthread, som uppenbarligen skalar bättre. Det är lite konstigt att de inte redan stödjer pthread i Berkeley DB, men det kanske kommer i en senare version.

Allt det här gäller i Linux, som jag har för mig har just en ovanligt bra pthread-implementation. Saker kan vara annorlunda i andra unixar.

Läs även andra bloggares åsikter om datorer, programmering, teknik, berkeley, oracle, connection pool, linux, pthread.

February 24th, 2010 Posted by Daniel Brahneborg | blogg | 3 comments

Workaround för Berkeleyproblemet

För några veckor sedan lyckades jag ju isolera ett problem med Berkeley-databasen. Den blev helt enkelt lite missnöjd med livet när det var för många trådar som accessade den samtidigt. I början så lyckades ju Oracle återskapa problemet, så det såg ljust ut. Tyvärr visade det sig vara en bugg i mitt testprogram, och när det var rättat så försvann krascherna. Attans.

Tyvärr fungerade det fortfarande inte helt bra, men det var inte helt tydligt var felet låg. I testsetupen till den riktiga applikationen så är det två andra program inblandade, och det var inte helt säkert att det inte fanns problem där också. Vissa buggar hittade jag faktiskt, men det var länge väldigt osäkert vart tiden egentligen tog vägen. Det gick bara ofantligt långsamt efter ett tag.

Till slut hade jag i alla fall lyckats mutera det lilla testprogrammet så pass mycket att det började visa upp samma symptom som det riktiga. Efter en massa testande och skruvande på parametrar stod det då klart att Berkeley DB börjar få problem när det är mer än något dussin trådar som samtidigt försöker skriva i databasen. Prestanda rasar, det blir deadlocks som gör att massa operationer måste göras om från början, och emellanåt så kraschar den helt och hållet.

Jag testade att sätta ett stort lås runt alla Berkeley-operationer, så att det alltid bara skedde en operation i taget. Först när allting var klart så fick nästa tråd göra någonting. Prestandan blev ju inte så jättebra eftersom det var så många trådar som inte gjorde något annat än att vänta, men det var i alla fall stabilt. Jag drog slutsatsen att det var antalet aktiva trådar som var det besvärliga. Ändå ville jag inte dra ner det till en enstaka tråd. Berkeley ska trots allt vara trådsäkert, och om trådarna jobbar på olika filer eller i olika delar av en fil, så borde det ju inte vara något problem.

De hundratals trådarna, i vissa fall uppåt två tusen stycken, behövde därför kokas ner till kanske 10 stycken. Alltså behövdes en datastruktur och algoritmer för att låta 10 trådar få passera samtidigt, men den 11:e skulle få vänta till någon av de 10 hade blivit klar. Jag behövde inte leta så länge innan jag hittade den perfekta lösningen: Min connection pool som jag skrev till MySQL-drivern! Den var skriven för att vara helt oberoende av vilken resurs som den hanterade, så det krävdes inte en enda ändring.

Några testkörningar senare så var det tydligt att testprogrammet inte brydde sig det minsta om antalet trådar som använder poolen, det gick lika fort ändå. Antalet deadlocks var inte noll, men ytterst få. I början fick jag deadlocks på varannan operation, och nu var jag nere på ensiffrigt av 100.000 poster. Det såg ljust ut.

På grund av hård refaktorering behövde jag bara ändra i tre små funktioner för att lägga till poolen i riktiga applikationen. Även där var prestandan nu helt stabil, oavsett hur många tusen poster den hade hanterat. Den ska få gå i mer full fart och lite längre tid i morgon, men det verkar som att problemet är löst.

För att använda Berkeley DB i en intensivt multitrådad applikation, behöver man alltså använda någon form av filter så att antalet samtidiga operationer maximeras till runt 10. Har man färre trådar än så behöver man självklart inte göra någonting, men det är vi högre upp på skalan som får problem. Oracle har fått en ny buggrapport.

Läs även andra bloggares åsikter om datorer, programmering, teknik, berkeley, oracle, race condition, connection pool.

February 9th, 2010 Posted by Daniel Brahneborg | blogg | 8 comments

Matte handlar om att kunna tänka

Richard Gatarski skrev nyligen ett blogginlägg där han argumenterar för att man ska ta bort “Matematik” som kärnämne, minska antalet lektionstimmar, och ersätta det med nÃ¥got mer “användbart”. I en intervju med Skolvärlden sa han:

… dom flesta behöver bara 3 % av den matte dom fÃ¥tt lära sig (iofs en siffra huggen ur luften). AlltsÃ¥, om man typ tvingats lära sig 100 mattesaker i skolan, sÃ¥ är det bara tre man har nytta av efterÃ¥t. Visst slöseri liksom. DÃ¥ är det nog bättre att ta bort 96 saker och fÃ¥ tid att kunskapa om nÃ¥got vettigare i stället.

Att 96 + 3 inte blir 100 blir lite extra humor i sammanhanget, men ändå.

Jag blir bara ledsen när jag läser sÃ¥dant här, för jag tycker det är direkt tragiskt med personer som tror att allting man lär sig i skolan är fakta som ska vara direkt användbara, helst i kassan pÃ¥ Ica. Egentligen behöver man ju dÃ¥ inte lära sig nÃ¥got annat än alfabetet, sÃ¥ man kan söka pÃ¥ wikipedia. SÃ¥ är det självklart inte. Man gÃ¥r inte i skolan för att lära sig “kunskaper”.

Till att börja med sÃ¥ finns det ingen onödig kunskap. Alla fakta vi lär oss bidrar till att bygga upp en större och mer stabil mental bild av verkligheten. PÃ¥ det sättet blir det dels lättare att lära sig nya fakta, men det blir ocksÃ¥ lättare att förstÃ¥ nya saker. Anledningen är att mer av det nya redan finns i skallen. Ta till exempel “koka vatten”. Att förstÃ¥ vad som händer när vatten kokar är en ganska avancerad historia, som inkluderar bÃ¥de fysik och kemi (och lite annat, beroende pÃ¥ hur noga man vill vara). Om man sedan ska lära sig vad som händer när nÃ¥gon annan vätska kokar, är 99% av kunskapen redan där. Ju mer man kan, desto enklare blir det att lära sig mer.

Har man lärt sig tio huvudstäder sÃ¥ hjälper inte det för att lära sig namnet pÃ¥ den elfte, men man har förmodligen en lite större förstÃ¥else av konceptet “huvudstad” än innan.

När jag gick pÃ¥ universitetet i UmeÃ¥ sÃ¥ var det nÃ¥gon som undrade varför Datavetenskapliga linjen började med sÃ¥ mycket matte (50%). Svaret frÃ¥n en av lärarna var ungefär “för att ni ska lära er att tänka”. Det lÃ¥ter knäppt, men är i grunden ganska enkelt. Matematik rör sig i en abstrakt värld, liksom programmering. För att bli en bra programmerare är det därför nödvändigt att utan problem kunna röra sig i den här abstrakta världen, och ett av de enklaste sätten att fÃ¥ folk att göra det mentala hoppet är att lära dem massor med matte. Inte för att man har användning av matten i sig, utan för att lära sig byta ut allt man vet om den fysiska världen (gravitation, massors tröghet osv), och föra resonemang och röra sig runt i en abstrakt värld, definierad av helt egna regler. Om man lär sig abstrakt tänkande enbart med hjälp av programmering, är risken stor att man fastnar i ett visst programmeringssprÃ¥ks syntax. Jag har flera vänner som hamnade i den fällan.

Att kunna tänka abstrakt är naturligtvis ingenting som bara programmerare behöver, det har alla nytta av. De som tror att de bara “behöver” 3% (dvs 3 saker av 100, för er som skolkade pÃ¥ mattelektionerna) av den matte de lärde sig i grundskolan, har bara inte förstÃ¥tt hur den ska användas.

Det är inte konstigare än att det är bra för barn att lära sig krypa när de är smÃ¥, nÃ¥got som bara vissa typer av soldater har nÃ¥gon faktisk nytta av. Det finns inga normala vuxna som har “nytta” av att kunna krypa, men det betyder inte att det är ett slöseri med tid att göra det som liten.

Med tanke på hur konstigt folk hanterar sin ekonomi så skulle å andra sidan många både behövt ha lärt sig mer matte, och dessutom behövt få lära sig hur den ska appliceras i det dagliga livet. Ett av mina favoritexempel är en sak jag har fått från Cornucopia, nämligen folk som skaffar amorteringsfria bostadslån. Visserligen kan det vara lite klurigt att räkna ut exakt hur mycket högre totalkostnaden blir, men det borde vara uppenbart för alla att den blir det.

Så, dels har man nytta av bra mycket mer matematik i vardagen än vad många tror, och dels så gör resten att vår mentala mappning av världen blir bättre.

Däremot behöver matematikundervisningen i Sverige bli mycket bättre, där har Richard helt rätt. Man behöver i början fÃ¥ se en tydligare koppling till verkligheten, sÃ¥ att det blir lättare att göra det här hoppet till den abstrakta världen. Studenter kommer ju till KTH utan att kunna mer än de fyra räknesätten, enligt flera artiklar i Ny Teknik förra Ã¥ret. Personligen tror jag att det beror till stor del just pÃ¥ det här “vad ska jag med just det HÄR till”-tänket. Antingen sÃ¥ visar det sig senare, eller sÃ¥ har du blivit bättre pÃ¥ att tänka abstrakt. Det är en win-win-situation, sÃ¥ länge som man fÃ¥r tillräckligt mÃ¥nga exempel pÃ¥ det förra, för att sluta oroa sig.

Att “matte” inte anses coolt och därför ska tas bort, är helt fel lösning pÃ¥ problemet. Matte behövs, och behöver därför fÃ¥ en bättre image. Som den marknadsförare Richard är borde det vara en trevlig utmaning. När Festis ansÃ¥gs o-coolt, paketerades drycken om och fick lite ball marknadsföring. Drycken i sig är densamma. Det är snarare nÃ¥got sÃ¥dant som behövs. Matten behövs, men behöver lite ny paketering och reklam. InnehÃ¥llet behöver inte förändras för det.

Läs även andra bloggares åsikter om datorer, programmering, ekonomi, vetenskap, pedagogik, richard gatarski, festis, reklam, matematik.

January 24th, 2010 Posted by Daniel Brahneborg | blogg | 16 comments

Berkeley DB är inte helt trådsäker

På jobbet började vi för ett tag sedan använda den gamla hederliga Berkeley-databasen i en av våra produkter. Den har ju många år på nacken och används i alla möjliga Unixverktyg, så det kändes tryggt.

Den första strategin gick ut på att använda flera olika index för att kunna traversera posterna på olika sätt. Framför allt skulle det göra att ingenting behövde läsas in vid uppstart, och i praktiken göra oss helt oberoende av köstorlekar. Sådant är bra.

Att använda olika index från olika trådar samtidigt var dock inte så populärt. Med intensiv trafik så kraschade nämligen alltid programmet ganska snart någonstans inne i Berkeley-koden. Trots support från flera av Berkeleyutvecklarna lyckades vi aldrig hitta anledningen.

Istället bytte vi strategi, och gick tillbaka till minnesbaserade köer istället. Databasen blev därmed reducerad till operationerna “lagra post X”, “läs in alla poster”, och “ta bort post X”. Det blev lite enklare kod och lite bättre prestanda, sÃ¥ det var ok.

När jag sedan började göra en del tyngre stresstester med massor med trÃ¥dar, började databasen krascha igen. Det verkar inte som att jag har glömt nÃ¥got fundamentalt, som att skicka med DB_THREAD till db->open, vilket innebär att Berkeley DB i den aktuella versionen 4.8 än sÃ¥ länge inte är helt trÃ¥dsäker. Den är ganska trÃ¥dsäker, men med nÃ¥gra dussin trÃ¥dar som inte gör nÃ¥got annat än att skapa och ta bort poster, hittar man uppenbarligen nÃ¥got som är trasigt. Förmodligen är det vad som brukar kallas för ett “race condition”, dvs programmet förutsätter att tvÃ¥ operationer sker i en viss ordning, men har glömt att säkerställa det.

Det kan som exempel se ut så här. Först finns tråd 1:

  1. Gör operation A.
  2. Vänta på att tråd 2 släpper lås Z.
  3. Gör någonting som tar lång tid.
  4. Gör operation B.

Sedan tråd 2:

  1. Gör operation C.
  2. Släpp lås Z.
  3. Gör någonting som tar kort tid.
  4. Gör operation D.

Av det här så vet vi att A sker före B, C sker före D, och att A sker före D.

Däremot så vet vi inte vad som händer först av A och C.

Rimligtvis borde D ske före B, eftersom båda trådarna passerar punkt 2 samtidigt. Här finns då ett race condition, för plötsligt kanske tråd 2 inte får köra på länge, vilket gör att tråd 1 hinner göra operation B innan tråd 2 hinner fram till operation D.

I verkligheten har man sedan kanske något hundratal trådar, en handfull lås, och några hundra operationer som parvis lite slumpmässigt måste göras i rätt ordning. Om det nu var någon som tyckte att det där exemplet lät alldeles för trivialt.

Nu återstår att se vad Oracle säger om det hela. Kanske har jag trots allt glömt någonting, kanske finns det en bugg.

Uppdatering: Oracle har nu bekräftat att de kan reproducera problemet, och har skickat det vidare till utvecklarna. Kul!

Läs även andra bloggares åsikter om datorer, programmering, teknik, berkeley, oracle, race condition.

January 20th, 2010 Posted by Daniel Brahneborg | blogg | no comments

HAML + acts_as_taggable_redux = #fail

I ett av mina små Rails-projekt vill jag ha taggar, och hittade efter lite letande acts_as_taggable_redux. Den var ganska cool, och gjorde att flera personer kunde tagga samma objekt, men bara ändra de taggar de hade satt själva. Däremot kunde alla se alla andras taggar. Perfect för community-taggning.

Sedan hittade jag Haml, ett markupspråk för Rails. Extremt kompakt, och mycket vackert.

Jag installerade det, och började pÃ¥ en tom vy. Nähä, “edit.erb not found”. HallÃ¥ nu, filen heter edit.html.haml, och eftersom Haml är installerat ska den automatiskt hitta den. Jag googlade som en tok i gÃ¥r kväll, men hittade inga ledtrÃ¥dar. Att byta railsversion mellan 2.3.2 och 2.3.4 gjorde ingen skillnad.

Till slut skapade jag ett helt nytt railsprojekt, skapade en haml-vy, och självklart fungerade det perfekt. Genom att jämföra filerna med de jag hade i mitt “trasiga” projekt och sedan stegvis kopiera över en fil i taget tills vyn gick sönder, hittade jag till slut den skyldige. Min tagging-plugin.

Visserligen skulle jag behöva slänga ut den pluginen och skriva en egen som använder named_scope istället för en massa komplex SQL, men det är andra saker som är viktigare. Idag dök dessutom en konkurrentsajt upp på nätet, så nu börjar det bli dags att få det hela releasebart. Lite irriterande, för det hade varit trevligt att kunna använda Haml.

Läs även andra bloggares åsikter om rails, ruby on rails, programmering, haml, acts_as_taggable_redux, markup, taggar.

October 9th, 2009 Posted by Daniel Brahneborg | blogg | one comment

Connection Pool

PÃ¥ jobbet hamnade jag i en situation som skulle kunna göra att vÃ¥ra stackars kunder skulle fÃ¥ tusentals samtidiga uppkopplingar till sin MySQL-databas. Tio kanske är ok, i bästa fall hundra, men därefter tror jag inte att databasen blir sÃ¥ glad längre. AlltsÃ¥ behövdes en “connection pool”,  sÃ¥ att det bara behövdes sÃ¥ mÃ¥nga uppkopplingar som faktiskt användes samtidigt. Om det behövdes för mÃ¥nga uppkopplingar, fick de trÃ¥darna helt enkelt ställa sig pÃ¥ kö. SÃ¥ lÃ¥ngt var det det ju inget konstigt.

Tyvärr är vår applikation skriven i C, så alla färdiga paket för sådant här, som nästan alltid är skrivna i Java, går inte att använda. Istället för att ägna halva dagen åt att leta upp något existerande som gick att använda från C, bedöma om licensen gjorde det användbart, fundera över prislappen, anpassa till vår produkt osv, så satte vi oss ner och skissade på en egen implementation.

Först behövs en struct för poolen.

  • int size // antalet skapade resurser (uppkopplingar)
  • int maxsize // det maximala antalet tillÃ¥tna resurser, typiskt 10 eller sÃ¥
  • lock // lÃ¥s, sÃ¥ att inte flera trÃ¥dar försöker komma Ã¥t poolen samtidigt
  • list available // lediga resurser
  • list waiting // lÃ¥s för trÃ¥dar som väntar pÃ¥ en ledig resurs
  • creator // funktion som skapar en ny resurs

Sedan behövs två små algoritmer. Först den för att hämta en resurs ur poolen.

  1. LÃ¥s pool.lock.
  2. Om det finns något i available-listan:
    1. Plocka ut första objektet i available-listan.
  3. Annars, om size < maxsize, dvs vi kan skapa fler resurser:
    1. Anropa creator-funktionen, och låt det objektet bli det som ska returneras.
    2. Räkna upp size.
  4. Annars:
    1. Hämta trådens lås från treadlocal.
    2. Lås trådens lås, och lägg det sist i waiting-listan.
  5. LÃ¥s upp pool.lock.
  6. Om vi ska vänta:
    1. Lås trådens lås igen, vilket gör att tråden hänger.
    2. När låset släpps, börja om från början.
  7. Returnera resursen.

Det behövs självklart också en liten algoritm för att lämna tillbaka resursen när den inte längre behövs.

  1. LÃ¥s pool.lock.
  2. Lägg tillbaka resursen i available-listan.
  3. Om waiting-listan inte är tom:
    1. Plocka ut första låset ur waiting-listan, och lås upp det.
  4. LÃ¥s upp pool.lock.

Om det finns lediga objekt krävs därför bara ett lås, annars två. Eftersom man plockar ut låsen ur en ordnad lista, är den helt rättvis. Det sker ingen busywait. Det skulle enkelt gå att öka maxsize i ett körande system, och med ett litet tillägg vid återlämnandet kan maxsize även minskas. Själva implementationen, inklusive några justeringar av algoritmen, var klar strax efter lunch.

Läs även andra bloggares åsikter om datorer, programmering, teknik, databas, mysql, connection pool.

August 26th, 2009 Posted by Daniel Brahneborg | blogg | no comments

« Äldre | Nyare »