Glemt å rydde etter deg?
Sessionhåndtering i Rails har en "liten" gotcha: den rydder ikke opp etter seg selv. Heldigvis er det ikke noe stort problem å holde orden i sesjonsdata, men det må naturligvis settes opp på forhånd.
Problemet
Jeg må innrømme at jeg nylig løp rett inn i dette problemet trass i at jeg tidligere har lest en artikkel (eller var det nevnt i Agile Web Development With Rails?) som beskrev nøyaktig den samme situasjonen.
Situasjonen er følgende: med default-oppsettet til Rails så lagrer den sesjonsdata i filer under tmp/sessions. Her blir data liggende til du selv rydder opp. Selv med minimalt bruk av session (typ, kun flash) vil det fort bli liggende en del filer her. Over tid vil det bli så mange filer at du møter på denne ublide meldingen:
[/min/rails/app/tmp/sessions]$ ls -la
ls: malloc: Cannot allocate memory
Oops! Avhengig av hvor lang tid det har gått siden du sist ryddet og hvor mange besøkende tjenesten din har, vil denne mappen potensielt inneholde mange tusen filer, noe som vil påvirke ytelsen etterhvert som mappen og filene der begynner å bli tunge å aksessere.
Fiks - bli kvitt alle filene
Kommer man utfor dette er første skritt selvfølgelig å rydde opp rotet man har laget. Når du ikke har minne nok til å gjøre ls har du heller ikke minne nok til andre ting som leser hele fillisten inn i minne. Desverre gjelder dette også rm.
Løsningen er å bruke find til å fjerne alle filer som er opprettet mer enn x antall dager siden. På denne måten kan du dele opp sletteoperasjonen i spiselige biter:
$ cd /min/rails/app
$ find tmp/sessions -name "ruby_sess.*" -ctime +60 -exec rm {} \;
Denne kommandoen finner og sletter alle session-filer som ble opprettet for mer enn to måneder siden. Hvilke tidsbegrensninger du går for her er avhengig av ressursene du har tilgjengelig, og hvor stor skaden er. Det er fullt mulig å gjøre
$ find tmp/sessions -name "ruby_sess.*" -ctime +1 -exec rm {} \;
med en gang for å ta alle filene som er opprettet før "igår", men det tar en stund.
Langvarig løsning
Den langvarige løsningen, som er den man burde hatt på plass til å begynne med er ikke så ulik den umiddelbare fiksen. Sett opp en lignende kommando i en daglig (eller ukentlig, eller lignende, ditt behov bestemmer) cron-jobb:
find /min/rails/app/tmp/sessions -name "ruby_sess.*" -atime +1 -exec rm {} \;
Denne vil daglig fjerne alle sesjonsfiler som ikke er aksessert innen siste døgn, noe som i de fleste tilfeller vil være rimelig.
Andre lagringsformer
Fillagring er bare én måte å lagre sesjonsdata på, og bruker du sesjoner mye går du sikkert for en annen vri, som for eksempel databaselagring. I så fall er det grei skuring å lage for eksempel en rake-task som kjører en delete from-spørring mot basen din for å fjerne gamle sesjoner.
Man kan advares mot mye rart, men enkelte ting må man liksom slepe trynet sitt igjennom før det sitter... Det er ikke alltid så moro, men man blir ihvertfall en erfaring rikere :) La oss håpe at de av dere som leser dette har bedre hukommelse enn meg.