?

Log in

No account? Create an account
здесь могла быть ваша реклама [entries|archive|friends|userinfo]
антон андреевич

[ website | My Website ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Django cleanup sessions [Jan. 11th, 014|07:53 pm]
антон андреевич
[Tags|]

Внезапно, пост по программированию. Из документации к Django <= 1.6 следует, что если использовать механизм сессий из коробки, то они будут "складироваться" в базу данных: https://docs.djangoproject.com/en/1.5/topics/http/sessions/#clearing-the-session-store Всё бы ничего, но фреймворк не умеет самостоятельно их удалять(и это правильно). У одного моего заказчика случилась довольно неприятная история с этим связанная - в базе накопилось почти 19 миллионов записей, которые нужно удалить. Или около 3 гигабайт данных в MySQL, самая большая таблица. Есть команда cleanup, clearsession в новых версиях. https://github.com/django/django/blob/e32095616c50bef9b06dc8637a99584ba947bae5/django/contrib/sessions/management/commands/clearsessions.py Вот только стандартный ORM не умеет делать bulk delete с фильтрацией. Вернее, умеет, но удаляет информацию построчно, с большим использованием памяти. А если что и отвалилось в процессе - делает rollback. На мои 19м записей ушло локально около 45 минут. А на боевом сервере случились проблемы - команда выела всю свободную оперативку, и сайт работал с перерывами, периодически вылетая с 500-ой ошибкой (невозможно получить данные от БД), пока скрипт не был прибит админом. Мысль: может прямо из БД удалить? Отвергаем: слишком рискованно, я не знаю как точно работают сессии, где и как они используются. Решение первое, пробное: попробовать удалять данные не за полтора года, а по месяцам. Реализация: скопировали код команды к себе, и добавили опцию даты, до которой нужно удалять:
from datetime import datetime

from django.db import transaction
from django.core.management.base import BaseCommand
from django.contrib.sessions.models import Session


class Command(BaseCommand):
    help = "Cleans expired sessions due to specified date."

    def handle(self, *args, **options):
        for date_ in args:
            expire_date =  datetime.strptime(date_,'%Y-%m-%d')

            if expire_date is not None:
                Session.objects.filter(expire_date__lt=expire_date).delete()
                transaction.commit_unless_managed()
запускаем: manage.py cleanup_due_date 2012-07-30. Получаем: 10 минут свободного плавания, 1Гб заполненной памяти. Долго, дорого. Второй подход: а буду-ка я удалять данные не по датам, а порциями, скажем, в 1000 записей. Завернем в shell скрипт, который за нас всё и удалит: from django.db import transaction from django.core.management.base import BaseCommand from django.contrib.sessions.models import Session class Command(BaseCommand): help = "Cleans expired sessions by specified count number." def handle(self, *args, **options): for number_ in args: if number_ is not None: Session.objects.filter(session_key__in=Session.objects.values_list('session_key')[:number_]).delete() transaction.commit_unless_managed() И опять неудача: django.db.utils.DatabaseError: (1235, "This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'") Мой локальный мускул не поддерживает такие запросы. Разбираться долго не хочется, идём по третьему пути. Третий раз. Проанализируем кол-во записей в бд, рассортируем когда и сколько их было, и будем удалять первым скриптом, но с оглядкой, что бы больше 60к записей не было. Примерно вот такой запрос, составленный с помощью интернетов: SELECT DATE_FORMAT(expire_date, '%Y') as 'year', DATE_FORMAT(expire_date, '%m') as 'month', DATE_FORMAT(expire_date, '%d') as 'day', COUNT(session_key) as 'total' FROM django_session GROUP BY DATE_FORMAT(expire_date, '%Y%m%d') Такой подход работает, и даже за два часа удалось удалить пару месяцев, но всё равно нужно искать дальнейшие пути. Четвертый путь, пока теоретический. Забыть про команду из Джанги, и удалять по одной записи. Долго, зато с минимальным количеством памяти. Как сделаю - расскажу
LinkLeave a comment

Про программирование как строительство [Mar. 12th, 013|01:45 am]
антон андреевич
Один мой сотрудник написал мысль про программирование в фейсбуке:
Часто слышал, как проводят аналогии между строительством дома и программированием. Считал всегда это неточным сравнением.

А вот сегодня Dmytro Maslenko предложил новое отношение: "Программирование это как строительство нового дома без плана. Абсолютно все ты будешь пробовать и переделывать: от фундамента до замка во входной двери"

И это очень похоже на правду, поскольку в IT все меняется насктолько быстро, что с каждой новой технологией ты начинаешь грабли ловить по-новой... Построил, разрушил, зато теперь знаешь как надо было строить. Но вот вышла новая технология...


Так вот, послушайте мои сопли:
Все было написано на Си более четверти века назад. Пришел С++ - новая технология. Особо не понимая зачем и кому это все нужно, решили вкусить ООП. Но почему-то решили реализовать его сами. Не доверяли, наверное. Видеть классы, исключения, stdlib написанный самостоятельно на Си - то еще удовольствие. Начали пихать такой себе самопальный ООП на Си. Потом пришли макросы. Окей, пихаем макросы куда захотим. Тут вдруг - мак не круто, а винда круто. Берем стороннюю технологию(бинарную, платную), продолжаем писать как написанно. Вдруг компания со сторонней технологией обонкрачивается. Какой-то правдой неправдой удалось утащить сорцы. Но когда посмотрели туда... Вообщем, приход кокоа вместо карбона означал одно - большие проблемы. Начали писать. Вроде бы, только выдохнули, как вдруг - 64 бита. А все сорцы в сторонней библиотеке чуть более чем полностью на битовых сдвигах к 32 битам привазана. В это время стало понятно - QA'ев не оберешься. Давайте автоматизировать! По старой привычке, решили писать все сами. И соблазн был ТАК велик попробовать новую технологию с теплым именем Джава... Но программисты, которые 10 лет писали на Си, на С++ и на Джаве все равно пишут как на Си. Конечно, ресурсов давали мало, и выучить джаву полностью не дали. Где не знали как сделать - вставляли Перл. Кто ж перл-то не знает?! В джавовских Input/Output streams классах тоже не заморачивались - решили вставить shell. Ах да, не просто шелл, а специальный, 99-го года, лицензированный! Кому-то дали задание написать фронт энд. А он хотел выучить C#. Ну он выучил. Ну как выучил... Написал как на Перле, но общее видение технологии получил. И уволился. Только никто не понимает как оно работает.

Я это к чему. Искренне завидую, что можно выкинуть все старое и написать заново. Я о таких проектах не слышал. Возьмите меня на такой проект! Все что я видел в своей жизни - это дописать новое так, что бы старое не обвалилось. Или обвалилось не более, чем на половину. Потому что про любое изменение, которое не относится к фиче я получаю слова No business value. Или еще лучше - оно уже 10 лет работает, зачем его менять. Тот момент, что все спрашивают друг друга а КАК оно работает, никого не интересует. Я не чувствую себя строителем, я археолог. Я вижу пласты технологий, один на другом, которые если тронешь один - повалятся все остальные. В этом плане очень интересные пласты "платить за строчки кода" и "преждевременная оптимизация". Было еще "платить за количество новых файлов", но это быстро убрали. Находить комментарий #если дофига памяти то тогда делаем по этому алгоритму IF(MEMORY > 2megabytes) очень забавно. Очень забавно, что джавовский код собирают перловым скриптом. Очень забавно видеть, что "отсутсвие third-party фреймворков" является плюсом, а не минусом. Но изменить ничего нельзя. No bussiness value.

Когда проект перевалил за 5миллионов строчек, начинать писать юнит тесты, потому что TDD стало модным, тоже было интересной идеей. 5 процентов покрыли, ребята молодцы :) Остальные 95 процентов требовали решительных измений в коде, решительного рефакторинга. Но отдел Sales не знает как продавать рефакторинг. Они умеют продавать фичи. Bussiness value.

Я смотрю на все это и завидую людям, у которых проекты длятся по пол года, по три месяца. Написал, и отдал. ВСЕ! Есть результат, есть что показать, есть за что гордиться и рассказать на собеседовании. Переходи в новое место, с повышением зарплаты в два раза и становись синьйором в 23 года. А мне что рассказать? Что я боролся за продвижение мавена для сборки джава кода? Или удалял копипаст из кода, но переписка по мейлу для проталкивания этих изменений длилась три месяца? Или что если ты пишешь фронтэнд на GWT, то он должен уметь запускать перловые скрипты?)

Кстати, эмейлы. Прочитав "Code complete" я был очень удивлен цифрой - 3000 стрчоек кода в ГОД среднестатистическим программистом. Я тогда подумал - да я минимум в 10 раз продуктивнее срендестатистического программиста. Дай бог, что бы в месяц я писал 600 строчек кода(и это с копипастом). Зато эмейлов более чем на 3000 в месяц, я уверен.

Вопрос такой - почему я сижу на этом проекте?! Потому что я романтик. Я верю, что смогу протолкнуть удаление бестолковых внутренних фреймворков в пользу open source. Что смогу уменьшить сложность кода. Что критичные вещи покрою юнит тестами. Мне претит сама мысль, что я попал на проект, и сбежал с него испугавшись сложностей. Я отлично осознаю, что мне за это не доплатят. Что я все равно принесу пару багов, за которые потом припомнят. Но код благодаря мне станет лучше, легче тестируемый, документированный, легко поддерживаемый, покрытый тестами.

Мне вообще кажется, что если бы заказчик остался у себя на родине - прогорел бы уже. Потому что меня окружают такие же люди, которые так же как и я верят в качество. Вот только качество сейчас как-то мало кого интересует. Кстати, технология скрама в этом тоже отчасти виновата - напишем в этом спринте, поправим в следующем. Упс, ушло на золото, ну ладно, через пол года будет новая версия :)

Фух. Выговорился.
Link10 comments|Leave a comment

navigation
[ viewing | most recent entries ]