Pyh, sikke en omgang

Bubbles, FC Sunnyvale Udvikler 30. september 2021, 14:43

Jeg har nævnt det flere gange før: når der er stille her på bloggen, så er det fordi vi arbejder på kedelige tekniske eller administrative ting, som ikke er synlige i spillet som nye funktioner.

Ofte er det opgaver som udefrakommende kræfter tvinger os til at smide alt vi har i hænderne for at håndtere. Det er ting, som ødelægger min planlægning og gør at jeg ikke kan forudsige hvornår den næste nye spilfunktion kommer.

Gennem hele 2021 og i sidste halvdel af 2020 har vi været ramt af et nærmest endeløst antal af denne slags opgaver, og det har været ret så frustrerende.

Det er også ting som optimeringer, rapportering og driftsikring, som er nødvendige for at sikre spillets fremtid på lang sigt.

Jeg skriver normalt ikke om disse ting, fordi de ofte er dybt kedelige eller så tekniske at det er sort snak for 99% af befolkningen. Men, nu ser det endelig ud til at vi er ovre puklen, og fordi jeg har haft så lidt at skrive om i lang tid, synes jeg alligevel I skal høre hvad vi har gået og døjet med.

Afrunding af ungdomshold

Betatesten af ungdomshold sluttede i sensommeren sidste år, og de efterfølgende uger brugte vi på fejlrettelser og udvidelser, såsom separat VIFA-rang til ungdomsligaerne.

Integration af fejlmeddelelser i Slack

Slack er et chat-system, som jeg og min freelance-udvikler bruger til vores daglige kommunikation. Fordi jeg gerne ville have styr på de sjældne småfejl, og også hurtigt kunne reagere på pludselige katastrofer, implementerede vi integration af mange forskellige typer fejlmeldinger med vores Slack.

Exceptions, fejlede baggrundsjob, og overbelastning af serverne giver os nu direkte besked i Slack, og jeg får en notifikation på telefonen så jeg kan undersøge hvad der sker, uanset hvor jeg er.

Rigtigt mange små, sjældent opstående fejl, af den type som typisk kun rammer 1 klub ad gangen, er blevet rettet fordi vi nu får øjeblikkelig besked om dem.

Rettelser af gamle, sjældne fejl i taktikeditor

I årenes løb har vi indimellem hørt fra managers, der havde opdaget at de havde spillet 1 mand i undertal nogen tid, og påstod hårdnakket at de var sikre på at de havde sat en komplet taktik.

Men, menneskers hukommelse er notorisk utroværdig, og hvis vi ikke har andet at gå efter end en påstand om noget, der skete for en uge siden - uden nogen detaljer - så er det umuligt at undersøge. Det sker også at nogle forsøger at få en form for erstatning for noget de godt ved er deres egen fejl, ved at påstå at der var en bug.

Det var noget, som vi kun hørte om sjældent, og det var umuligt at genskabe, så derfor er det aldrig blevet bekræftet at der overhovedet var en bug.

Gennembruddet kom da vores admin, FC Razor, oplevede problemet selv, lagde mærke til det med det samme og kunne fortælle præcis hvilken handling, han havde udført med den pågældende spiller.

Det gav mig en mistanke og efter en undersøgelse af koden dannede jeg mig en teori om hvad problemet kunne være, og efter mange forsøg var jeg i stand til at genskabe det.

Problemet viste sig at kunne opstå, når man slap 1 spiller ovenpå en anden. I dette tilfælde sendte javascript-applikationen 2 requests til vores servere:

  1. Fjern Jensen fra plads X
  2. Sæt Hansen ind på plads X

Men, fordi to requests sendt over internettet på samme tid kan tage forskellige ruter, kan vi ikke stole 100% på at de når frem i den rækkefølge, de er sendt. I sjældne tilfælde kan den sidste sendte besked nå frem først. Desuden har vi en load-balancer, som tildeler indkommende requests til en af vores 3 webservere, for at fordele læsset. Derfor kan det også ske at de 2 requests bliver udført af hver sin webserver, og hvis den der modtager den første besked har en lille smule længere kø, kan det også her ske at den sidst sendte besked bliver udført først. Det er brøkdele af sekunder, som kan gøre forskellen.

Den slags er selvfølgelig umuligt at opdage når vi udvikler, for vi har hver vores egen kopi af spillet til at køre på vores egen lokale maskine.

Så, i sjældne tilfælde kunne det ske at beskeden om at sætte Hansen ind på plads X blev forsøgt først, hvilket serveren ville nægte, da Jensen stadig stod på den plads. En brøkdel af et sekund senere ville beskeden om at fjerne Jensen så nå frem, og blive udført - med det resultat at man kom til at spille en mand i undertal. Samtidig ville man ikke opdage det, fordi javascript-applikationen ikke var lavet til at kunne håndtere sådan en fejl, så grafisk ville det se ud som om intet var galt.

Løsningen blev at vi skrev dele af både javascript-applikationen og backenden om, således at en ombytning af 2 spillere kun sendes som 1 besked: "Byt om på Jensen og Hansen". Vi fandt flere situationer, hvor noget lignende i teorien ville kunne opstå, fordi applikationen sendte 2 beskeder, og lavede samme rettelse her.

Vi tilføjede også en fallback-løsning, som simpelthen reloader taktiksiden, hvis applikationen modtager en fejlbesked fra serveren, som den ikke ved hvordan den skal håndtere.

Det krævede meget arbejde, men gjorde at vi langt om længe fik rettet en mystisk, sjælden fejl, som havde spøget i rigtigt mange år.

Cookie-samtykke

I efteråret kom der nye regler fra reklamebranchen, som tvang os til at lave vores cookie-valg og reklamesystem om. Her var vi nødt til at implementere en ny cookievælger, og det krævede forskellige løsninger afhængigt af hvilke valg man foretager, og om det er for Danmark eller udlandet.

Reklamerne forsvandt!

Umiddelbart efter vi havde implementeret ovenstående, forsvandt vores reklamer lige pludseligt.

Både jeg og vores reklameleverandør troede først at det var på grund af cookievælgeren, men det viste sig at være et rent tilfælde at det skete lige efter. Systemerne der bruges ved reklamesalg er utroligt komplekse, og involverer online reklamebørser og auktioner og mange forskellige parter. Derfor var det meget svært at hitte ud af hvad der skete.

Til sidst fandt vi frem til at det skyldtes at en større spiller på markedet havde blacklistet os fra deres reklameplatform, som vores leverandør anvender. Det skete på grund af en gammel sag omkring noget upassende materiale en bruger havde lagt i et brugerforum for næsten 9 år siden.

Hvorfor den sag pludselig dukkede op igen, og hvorfor de ikke kunne finde vores gamle appelsag er stadig en gåde, men vi var nødt at foretage gennemgribende ændringer i kontrol og validering af brugergenereret indhold, deriblandt:

  • accept af regler ved signup
  • tilføjelser til forumreglerne
  • accept af forumregler første gang man skriver i forum
  • accept af forumregler når man opretter brugerforum
  • fjernelse af reklamer fra næsten alle sider med brugergenereret indhold
  • automatisk oprydning af brugerfora
  • påkrævning af login for at se det meste brugeregenererede indhold
  • skjulning af brugerprofiler osv. ved klubber som er bannet eller har været inaktive i lang tid
  • generel sikring mod at man kan producere og tilgå brugergenereret indhold anonymt

Jeg skulle så aflevere en længere redegørelse for alle disse tiltag, samt dem vi tog dengang for 9 år siden, beskrive hvordan vi modererer de forskellige slags brugergenereret indhold - og så vente på en afgørelse.

Disse måneder uden danske reklamer kostede virkeligt dyrt på bundlinjen, men vi fik dem endelig tilbage i december.

Julekalender

Lidt før december afsatte jeg tid til at vi langt om længe kunne få indført et nyt sjovt indslag i julemåneden - noget som har manglet i mange år.

Koden til de forskellige typer af gaver bag lågerne blev implementeret løbende i starten af måneden, da de ikke alle kunne nå at være klar til 1. december.

Vi implementerede også løbende masser af rettelser og forbedringer til kalenderen og dens UI/design.

Skift til nyt kort-betalingssystem

I starten af året informerede vores betalingsudbyder os om at de snart ville lukke deres gamle betalingssystem og tilhørende API på grund af nye krav fra kortudbyderne, og at vi derfor skulle over på deres nye system.

Dette krævede en komplet omskrivning af hele vores kortbetalingssystem, og forsinkede os mindst en måned.

Mystiske performance-problemer

Vi blev også nødt til at tage hånd om et mystisk performance-problem, som havde plaget sitet i noget tid, og altid opstod søndag aften efter sæsonopdateringen (men ikke under).

Problemet var mystisk fordi hverken webserverne eller databasen så ud til at være særligt belastede. Men vi gik i gang med at undersøge og optimere alle de steder vi kunne finde, hvor koden godt kunne gøres hurtigere.

Vi bruger tjenesten NewRelic til at analysere på det kørende system, og det giver os detaljeret indsigt i hvordan koden kører på hvert enkelt sideopslag. Udfra denne information gik vi simpelthen i gang med at optimere alle de steder, hvor det så ud som om der var noget at hente.

En af metoderne, vi tog i brug for at optimere, var fragment-caching. Fragment-caching fungerer ved at man gemmer brudstykker af en side i RAM, så man sparer den processering og de databaseopslag, som er krævet for at generere den del.

F.eks er ligatabellen cachet, og det samme HTML-fragment bruges 5 forskellige steder på sitet - det bliver bare stylet forskelligt med CSS de steder det optræder. Hver gang ligaens stilling ændrer sig, bliver cachen genopfrisket.

Kunsten består i at vælge de dele ud som det kan betale sig at cache, og så sørge for at cachen altid er frisk. Sidstnævnte skabte nogle problemer rundt omkring, fordi vi aldrig har brugt fragment-caching før og der er mange faldgruber, som kan gøre at man kommer til at vise gammel data fra cachen - så man skal holde tungen lige i munden.

Vi kunne se at vores optimeringer virkede og de normale svartider blev hurtigere. Men, selv efter alle disse optimeringer varede problemet om søndagen ved, og var stadig et mysterie.

Derfor satte vi en ekstra server op, hvor vi implementerede et system som løbende henter og fletter logfilerne fra de 3 webservere, analyserer dem, og viser os et live-opdateret dashboard med overblik over en masse forskellige datapunkter omkring hvor og hvordan sitet belastes.

Så fandt vi endelig ud af at problemet skyldtes en 3.partsside, som så ud til at gå amok med en masse fejlbehæftede opslag om søndagen efter sæsonafslutningen pga. den tilstand vores cup-sider kom i indtil det nye cup-kampprogram var lagt mandag morgen.

Jeg synes det er helt fint når nogen laver 3.partssider, som kan vise forskellig nyttig statistik, men det er selvfølgelig noget skidt, hvis de belaster vores servere for meget. Derfor blokerede jeg dem midlertidigt i vores firewall, imens vi arbejdede på en løsning. Selvom problemet kom udefra, så var det heller ikke godt at cupsiderne var sårbare overfor overbelastning. Derfor implementerede vi flere performance-optimeringer, mere caching, og en sikring imod at den type opslag kunne belaste serverne så meget.

Alt i alt forsinkede arbejdet med performance-forbedringer, fragment-caching og live-dashboard os med et par måneder.

Det var dog ikke spildt arbejde, for vi fik nyttig erfaring med fragment-caching, som jeg længe har ønsket at vi skulle i gang med at bruge, og dashboardet vil garanteret hjælpe os i fremtiden. Det kom dog bare på et meget ubelejligt tidspunkt ovenpå alle de andre forsinkelser.

Hackerangreb

I foråret blev vi ramt at et hackerangreb, som varede ved i flere uger.

Vi kunne se at det var den type, hvor nogen havde anskaffet sig en liste af stjålne logins fra andre sites, som de så forsøgte at logge ind på Vman med.

Skumle steder på nettet kan man købe lister med millioner af logins, som er fundet ved at forskellige sites rundt om i verden er blevet hacket. Fordi mange bruger det samme login på flere forskellige sites, så er man i risiko, hvis ens login ender på sådan en liste.

Angrebet kom fra et botnet - altså tusindvis af inficerede maskiner fra alle dele af verden - som man kan leje for et relativt lille beløb. Og så er det en smal sag at få dem til at bombardere et site med loginforsøg, hvor man bare gennemgår listen af logins, og håber på at man er heldig at finde et som fungerer.

Fordi angrebet kom fra så mange forskellige maskiner, var det svært at blokere uden at forstyrre legitime brugere. Udfordringen bestod i løbende at tune vores firewall-regler til at blokere eller forsinke flest mulige mistænkelige loginforsøg.

Vi havde ikke megen erfaring med den slags, så det tog nogen tid og masser af konstante ændringer i reglerne før der kom ro på, uden at forstyrre jer brugere.

Selvom angrebet ikke var rettet mod at bryde vores tekniske sikkerhed, men blot forsøgte at udnytte menneskers skødesløse omgang med passwords, så satte det alligevel mig en skræk i livet. Så efter det værste var overstået brugte vi nogle uger på at gennemgå vores tekniske sikkerhed endnu en gang, og yderligere hærde os imod et fremtidigt angreb.

Selvom der i forvejen er flere lag af sikkerhed rundt om vores servere, tilføjede vi endnu et i form af en middleware-komponent som undersøger og evt. afviser requests før de overhovedet kommer videre til selve Virtualmanager-applikationen. Denne middleware står for rate-limiting af logins, således at der er en grænse for hvor mange gange man kan forsøge at logge ind fra den samme IP-adresse i en vis periode. Den henter også regelmæssigt en opdateret liste af IP-adresser fra datacentre, og blokerer login-forsøg derfra.

Vi genererede også nye, lange passwords for alle inaktive klubber, for at der skulle være mindre at komme efter, hvis nogen skulle forsøge det samme i fremtiden.

Alt i alt kostede dette angreb os omkring 1,5 måneders udviklingstid.

Jeg vil i øvrigt opfordre til at man bruger en unik kode til sin Vman-konto, i stedet for en man har brugt andre steder.

Nye funktioner relateret til handel

På trods af alt bøvlet, formåede vi alligevel også at introducere nogle nye spilfunktioner i foråret.

Blandt andet blev ønskelisten opfrisket og fik tilføjet funktion "stående bud".

Alle de nye ting blev beskrevet i dette blogindlæg.

Skift til nyt SMS-betalingssystem

Endnu en af vores leverandører informerede os om at de ville lukke for deres gamle system, og at vi havde en kort frist til at flytte over på et nyt. Denne gang var det SMS-betalinger, og det krævede igen en komplet omskrivning.

Det viste sig at være overordentligt bøvlet at arbejde med, og det førte til endnu en lang forsinkelse af mine udviklings-planer.

Opfriskning af odds-spillet

I forbindelse med Euro 2020 skulle vi have gang i odsspillet igen. Men, da det efterhånden var en del år siden det sidst var blevet brugt, var der en del gammel kode, som ikke fungerede med vores opgraderede framework. Så disse ting skulle først rettes, og derefter opfriskede vi en del andre ting i spillet, samt implementerede noget mere automatisering, så det ikke krævede nær så meget manuelt arbejde at køre.

Reklamefrit abonnement - Vman-PRO

I hele denne periode har vi også arbejdet på Vman-PRO, men arbejdet er blevet afbrudt igen og igen. Al funktionaliten har nu været færdig i et stykke tid, men har ventet på at vi fik lavet de fornødne ændringer i butikken til at kunne sælge.

Ny Rammeaftale om SMS-betalinger fra 4T

Efter vi allerede havde omskrevet hele vores SMS-betalingssystem en gang skulle vi så på den igen.

Nu var det fordi sammenslutningen af teleselskaber, 4T, havde indgået ny Rammeaftale omkring SMS-betalinger, hvilket krævede yderligere omskrivninger og en ny procedure for SMS-betalinger.

Disse ændringer blev deployet i denne uge, men vi mangler stadig noget finpudsning, da proceduren er lidt bøvlet. Men, vi havde en tidsfrist til at få det gjort færdigt, så vi var nødt til at få det lagt op.

Den nærmeste fremtid

Det ser ud til at vi nu ENDELIG er ovre den store pukkel af møgopgaver, som andre har pålagt os, og som gang på gang har ødelagt min udviklingsplan. I den nærmeste fremtid ser planen således ud:

Understøttelse af Vman-PRO i butikken

Vi er nu endelig vendt tilbage til opgaven med at tilpasse butikken til at kunne sælge Vman-PRO - og det er lige på trapperne.

Release og opfølgning på Vman-PRO

Når butikken er klar, releaser vi Vman-PRO. Herefter skal vi bruge lidt tid på at tjekke om alt kører som det skal, rette evt. fejl, og måske kigge på om vi kan finde på flere små, sjove ting, der kan tilføjes til PRO.

Opgradering af framework

Før vi begynder at arbejde på responsivt design, vil vi først opgradere vores framework (Ruby on Rails) til den nyeste version (6.1).

Umiddelbart ser det ikke ud til at det burde give kæmpestore udfordringer, men det kræver altid nogle tilpasninger og en masse tests.

Blogindlæg, kommunikation

Jeg ved at der er nogle, der ønsker at jeg skrev oftere her i bloggen, men jeg synes ikke det giver mening at skrive om rammeaftaler, cookiesamtykker, fragment-caching, og log-analysering.

Der vil også i fremtiden kunne komme lange perioder uden mange nye spilfunktioner. Sådan er det bare; det kan ikke undgås.

Når vi er begravet under et bjerg af den slags opgaver, jeg har skrevet om her, så er blogindlæg det sidste jeg tænker på.

Blogindlæg får ikke udviklingen til at gå hurtigere.

Men, jeg anerkender behovet for lidt mere liv og glade dage i spillet - det kan bare ikke være baseret udelukkende på nye spilfunktioner.

Derfor undersøger jeg muligheden for at få nogen til at hjælpe mig med at strukturere min kommunikation både med jer og med crewet, og at skabe events og liv i spillet, på måder der ikke kræver en masse ekstra udvikling.

Efter Vman-PRO vil jeg lægge op til en diskussion omkring disse ting på forummet, for at høre om I virkelig gerne vil høre om tekniske detaljer i bloggen, og om hvad vi kan finde på af ting, som gør det fedt at logge ind hver dag, selvom der ikke er nye spilfunktioner i en periode.