lördag 24 maj 2008

Stored procedures, MySQL, ASP.NET och Loopia

Jag har under den senaste månaden jobbat på en webbsajt som ska ligga på ett konto på webbhotellet Loopia. Jag gillar verkligen Loopia, de har bra support, schyssta priser/tjänster och är trevliga att ha att göra med. Tidigare har jag mest kodat webb i PHP, men eftersom jag numera enbart sysslar med .NET i mitt vanliga jobb tänkte jag att det är lika bra att jag kör på med en teknik även på min egna tid. Man lär sig ju grejer hela tiden, och det känns effektivast att koncentrera sig på ett spår i taget.

Hursomhelst! Från och med version 5 finns det stöd för stored procedures i MySQL. Och MySQL har till och med varit så vänliga att de utvecklat en ADO.NET-provider som är specialanpassad för kommunikation just mellan .NET-applikationer och MySQL-databaser. Loopia tillhandahåller den senaste versionen av denna komponent på sina servrar. Bra förutsättningar för att utveckla seriösa webbapplikationer av medelstorlek alltså.

När jag utvecklat den här webbplatsen har jag kört den lokalt och låtit den gå mot min egen Loopia-databas. Det har funkat mycket bra och har fördelen att jag kunnat sätta upp en testsajt på mitt Loopia-konto också, med samma databas, som jag kunnat låta valda personer ha tillgång till.

Nu inför lanseringen av webbplatsen laddade jag upp den till det Loopia-konto där den ska ligga, satte upp databastabeller och stored procedures i kontots databas och tänkte att det borde funka smärtfritt från början just eftersom det är samma webbhotell och funkat så bra innan. Där bedrog jag mig!

När man gick in på en sida som anropar en stored procedure möttes man av följande glada meddelande från MySQL Connector/NET:
Unable to retrieve stored procedure metadata. Either grant SELECT privilege to mysql.proc for this user or use "use procedure bodies=false" with your connection string.

Vad var nu detta? Jag hade ju skapat en databasanvändare speciellt för webbapplikationen, med precis de rättigheter som ska behövas. Och det kunde inte vara något fel på applikations- eller stored procedure-koden, för det hade ju funkat fint i utvecklingsmiljön, som är mycket lik produktionsmiljön.

Efter att ha bankat huvudet i väggen en stund gick jag in och tittade på ROUTINES-tabellen i information_schema-databasen som hör till varje MySQL-databas. Där kunde jag se att mina stored procedures fanns upplagda korrekt, att det var ett särskilt administrationskonto som skapat dem - ett konto som jag själv lagt upp just för detta - och även att något som heter SECURITY_TYPE var satt till "DEFINER" på samtliga stored procedures. Det sistnämnda verkade intressant! Efter ett par snabba tester kunde jag konstatera följande:
I Loopias MySQL-konfiguration är det endast den databasanvändare som skapade stored procedure:n som kan exekvera den.

Är det smart eller bara irriterande? Jag är nog inte rätt person att bedöma det, men jag vet att det tog en stund för mig att lista ut det.
Uppdatering: Felmeddelandet jag fick ovan antydde att man kunde lösa det genom att ge SELECT-rättigheter för tabellen mysql.proc till aktuell användare, alternativt använda parametern use procedure bodies=false i sin connectionstring. Eftersom man sällan har möjlighet att dela ut godtyckliga rättigheter till höger och vänster om man använder ett webbhotell så testade jag det andra alternativet. Och det funkade! Det man måste tänka på då är att alla parametrar man skickar in till sina stored procedures måste anges i rätt ordning (alltså den ordning som stored procedure:n förväntar sig dem) och med rätt datatyp. Detta eftersom man helt går förbi den kontroll av parametrarna som annars görs av MySQL med hjälp av tabellen mysql.proc.

En annan lurig grej med Loopia har att göra med omstarter av ASP.NET-applikationer. I normala fall håller ASP.NET koll på om de filer som ingår i en webbapplikation ändras, varpå applikationen startas om så att ändringarna blir verksamma. Det kan handla om allt ifrån en ny version av källkoden till en enkel justering av ett parametervärde i en konfigurationsfil. Att hela denna apparat är nödvändig har att göra med att en ASP.NET-sajt faktiskt är kompilerad kod, till skillnad från exempelvis en PHP-lösning, där det rör sig om script som parsas när de efterfrågas. I normala fall fungerar det hursomhelst bra, även om själva omstarten/kompileringen av applikationen oftast innebär att besökaren/användaren får sitta och vänta några extra sekunder vid just det anropet.

Men på Loopia fungerar det inte så här. Enligt dem själva använder de en stor NAS där allt kundmaterial ligger - alltså alla webbapplikationer. Tydligen är den filstrukturen för omfattande för att ASP.NET ska kunna övervaka alla ändringar som görs (låter inte helt ologiskt), vilket rent funktionellt inneb¤r att den här omladdningsfunktionen helt är satt ur spel. Som ett alternativ finns det en automatiskt recycle-process som körs ungefär var 26:e timme, då applikationerna laddas om oavsett om det egentligen behövs eller inte.

Men det duger ju inte om man sitter och utvecklar eller testar en sajt! Vadå, ska man ladda upp filerna, konstatera att man råkat missa en inställning i Web.config och sedan vänta i upp till 26 timmar på att en korrigerad version ska börja användas av sajten? Det är naturligtvis helt ohållbart.

För att försöka lindra frustrationen har Loopia utvecklat en funktion i den kontrollpanel som man som kund har tillgång till där man manuellt kan begära en omladdning. En enkel knapptryckning så läses de aktuella versionerna av filerna in i minnet. På Loopias supportforum står det:
"...i Loopia Kundzon kan du själv begära att ASP.NET-applikationen ska laddas om, exempelvis efter att du gjort en ändring."

Då är ju allt bra! Eller är det? När jag har använt funktionen har jag ofta upplevt ett märkligt beteende hos applikationen. Ibland laddas den verkligen om och får de senaste uppdateringarna, men om man sedan startar om den igen så kan den gå tillbaka till en gammal version. Och ibland verkar ingenting alls hända. Trots att det mycket tydligt står i kontrollpanelen att "applikationen startades om med ett lyckat resultat".

Efter korrespondens med Loopia har de bekräftat att funktionen inte alls fungerar som det står på supportsidorna. I verkligheten fungerar den bara en gång per recycle-intervall, vilket alltså betyder att man kan använda den en gång var 26:e timme. Jag kan alltså som mest uppdatera mina webbapplikationer två gånger per dygn, ungefär. Vilken lyx!

Loopia hävdar att de jobbar på att få fram en mer hållbar lösning på detta problem, men att det inte finns något datum för när det ska vara klart. Vilket betyder att de lika gärna kunde säga att man får leva med det system som finns idag.

7 kommentarer:

  1. David Andersson26 maj 2008 20:13

    Låter väldigt olikt Loopia att vara så långsamma. Du kan ju inte vara den enda med samma problem.

    Sista åren tycker jag Loopia i alla fall har haft ett väldigt bra informationsarbete och jag har förtroende för dem. Även support har de varit väldigt bra på.

    Men det här känns väl ändå lite, förlåt uttrycket, lol.

    SvaraRadera
  2. Nej, du är inte ensam. Jag slet mig i håret i timmar medan jag försökte utveckla en mindre webbapplikation åt en kund. Det slutade med att jag skrev och testade allting lokalt, för att sedan ladda upp det på sajten. Det fungerade i mitt fall, eftersom det var några enkla script, men jag fasar för att utveckla stÃrre grejer som ska ligga hos Loopia.

    SvaraRadera
  3. Loopia har nu stöd för att starta om ASP.NET applikationer ett obegränsat antal gånger per dygn genom Loopia Kundzon.

    Så borde vara lättare för er att fixa era applikationer hos loopia nu.

    SvaraRadera
  4. Loopia har nu stöd för att starta om ASP.NET applikationer ett obegränsat antal gånger per dygn genom Loopia Kundzon.

    Så borde vara lättare för er att fixa era applikationer hos loopia nu.

    SvaraRadera
  5. Alltså ... jag utvecklar en större sajt åt en kund. På Loopia. Skjut mig!

    Ja man kan starta om sin app från kontrollpanelen, men det funkar inte 100%. Och det är en rätt omständig process att behöva logga in där och vänta på det hela. Har aldrig behövt böka med det på andra webbhotell, där är det bara skjuts upp med filerna - F5 - presto! Som det ska vara.

    Sen ... de kör i Medium Trust. Vilket innebär att du är extremt begränsad till vad du får göra. Jag fick skriva om en massa kod för att jag använt ASP.NET Ajax på det gamla sättet med egna referenser och dll:er, Loopia har allt i sin GAC. Efter jag lyckats fixa allt det så visar det sig att min app inte funkar förrän alla mina egna "settings" i configSections tagits bort, t.ex. min databasanslutning.

    Efter detta funkar sajten. Men! Jag har några DLL:er i min bin eftersom jag jobbar med Youtubes API ... så fort jag går in på en sida som vill ha de DLL:erna smäller det högt. Detta kan dock bero på att omstarterna inte funkar helt via kontrollpanelen.

    Men seriöst, så mycket slitet hår och svordomar över Loopia + ASP.NET gör att jag aldrig går dit igen. Kommer säga upp avtalet där. Min kund som står för det dock men kommer lätt ersätta honom varenda krona bara han byter och spar mig huvudvärken att jobba mot Loopia.

    SvaraRadera
  6. Håller med om att det är drygt att behöva starta om applikationen manuellt.

    Medium trust är nog däremot mer eller mindre standard när man använder ett webbhotell med delad hosting, och det ska vi nog vara glada för - tanken är ju att den delade miljön ska vara så pass säker att man inte behöver oroa sig för vad andra kunders applikationer har för sig.

    Vill du köra full trust skulle jag tro att du kommer behöva hyra en egen server (virtuell eller fysisk). Det behöver inte ens bli särskilt dyrt, kolla exempelvis på City Cloud, de har en tjänst jag tycker verkar intressant. Du får en Windows Server 2008 DC med SQL Server Web Edition för drygt en femhundring per månad. Så klart väsentligt dyrare än ett webbhotellskonto, men då har du å andra sidan full kontroll över din miljö.

    Annars gillar jag Binero. Inga problem med omstarter av applikationer och nu har de dessutom börjat inkludera SQL Server i alla Windowskonton - föredömligt. Där får du som ny kund lastbalansering på köpet, rätt läckert.

    SvaraRadera
  7. Hej grabbar. jag kör ASP.NET 2.0 OCH mysql 5.0 hos web10.se. 25kr/mån. billigt som f...
    jag lämnade loopia och gick över till web10.se

    På web10.se funkar allt utan problem. Nackdelen är att de inte har telefon-support, utan enbart via email. Men å andra sidan har man ju inga problem hos dem. Dvd såna problem som man har hos loopia.

    SvaraRadera