пятница, 20 июня 2008 г.

Motivation loss

Что может плохого случиться с разработчиком в процессе работы над протяжённым во времени масштабным проектом? Он перестаёт видеть перспективу. Проект идёт уже не один год. Да, что-то делается, что-то получается. Что-то откладывается, что-то из тени выходит на первый план. Планы постоянно корректируются. Движуха со всех сторон. Развите полным ходом.
Хех, а я наблюдаю за всем несколько абстрагировавшись от этого паноптикума, и устаю. Мы уже давно не занимались созданием нового - только подкручиванием деталей и копированием функционала между проектами. Сложного программирования - 0. И не предвидится.
Кроме этого - постоянно растёт нагрузка. Эта рутина требует много времени и сил. Постоянно требуются новые фичи. Оценка, комментарии, ЛС, сортировки... Рутина. Скука.
Осложняется положение еще и тем, что я перманентно срывал сроки. Да, тут я кажется еще не писал, у меня есть проблема: я плохо планирую сроки. Не учитываю возможные проблемы от сторонних производителей, не закладываюсь на решение других срочных задач в этот период. Для своих подчинённых, как правило, сроки ставлю как для себя, хотя должен понимать что задачи я буду решать априори быстрее.
Так вот, осложнение в том, что я за дело, которым занимаюсь - болею душой. И, чтобы не подводить людей которые мне доверяют, остаюсь на ночь, работаю в выходные. И фоном всего этого проходит внутреннее чувство вины за срывы. От такого ощущения устаёшь. Особенно когда руководство ничего не делает для улучшения ситуации. И всё опять ложится на тебя. А усталость выливается, в итоге, в безразличие.

суббота, 7 июня 2008 г.

Framework::xCache Data tree

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

Основным кирпичиком системы является сущность - объединение данных и методов их обработки\получения. По сути это чёрный ящик, который имеет несколько функция для общения с внешним миром. Никого не интересует как это работает, как хранятся и получаются данные, есть ли там кеширование и тд. Из этого вытекает необходимость деления кеша по сущностям.

Кроме того, зачастую бывают модули находящиеся не в системе, но желающие использовать механизм кеширования. Так что необходимо делить данные еще и по принадлежности к системе.

Из этих требований и родилась модель данных, которую я использую в фреймворке.

Дерево данных в кеше очень похоже на структуру директорий:
/project/system/entity/dataname.
Первый уровень - имя проекта. Это позволяет нам хранить все данные принадлежащие к одному проекту в одной ветке дерева. Естественно существует ветка для общих данных - она называется default.
Второй уровень - имя системы, из которой используется кеш. Это позволяет нам одновременно работать с одинаковыми сущностями из моей системы и из модулей обработки данных от наших партнёров.
Третий уровень - сущность. Не просто имя сущности, а соединение нескольких параметров инициализации кеша. Это сделано по двум причинам:
- желание использовать несколько веток кешей для одной сущности (зачем - разберу позже)
- возможность задавать множество способов первоначальной инициализации данных (при желании)
Четвертый уровень - просто имя переменной. Никаких изысков.

Каждый уровень - это вершина дерева. То есть в записи каждого уровня без завершающего слеша (/project, /project/system, /project/system/entity) хранится массив из всех вложенных уровней. Например в случае одного проекта (project1) и двух систем (system1 и system2) содержимое записи /project1 будет такое: array("system1","system2").

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

среда, 4 июня 2008 г.

Framework::xCache Introduction

Последние несколько лет я разрабатываю на PHP. Последний год - высоконагруженные проекты входящие в первую десятку согласно статистике Яндекса и LiveInternet'а. Много кода было написано за это время. Большинство успешно отправилось в /dev/null, но кое-что используется на боевом и хорошо себя зарекомендовало. И теперь я хочу немного рассказать об том, что в итоге попало в мой Framework. Это может быть полезным тем, кто забредёт на этот блог в поисках откровений, но, и это гораздо важнее, позволит мне систематизировать накопленный опыт. Начнём с кеширования.

В многих проектах на PHP используют кеширование как опкода, так и данных. Вариантов много, я остановился на xCache по двум причинам:
- опкод хранится в shared memory, а не на диске
- на моих тестах он показал скорость выше чем остальные
Простым подключением модуля можно получить ускорение 30%-50%. Используя всю мощь кеширования данных можно ускоряться практически бесконечно.

Из минусов на данный момент я могу выделить только один: невозможность разделения памяти по проектам. У xCache есть свой административный веб-интерфейс для доступа к которому необходимо проходить стандартную HTTP авторизацию, что логично. Но реализовано это средствами модуля, то есть попытка воспользоваться функционалом инициирует отсылку сервером соответствующих заголовков.

Вообще, всё его API делится на четыре группы:
- административные функции
- общие функции управления данными
- функции управления опкодом
- статистические функции

Из них нам интересны только первые две группы. Как я уже написал - для доступа к административным функциям необходимо пройти HTTP авторизацию. Но в эту группу входят такие крайне необходимые функции как:
- получение дополнительной информации о записях
- список (и количество) записей в кеше
- очистка кеша.
Доступны без авторизации только самые базовые функции:
- получение данных из записи
- установка и удаление данных
- проверка на существование
- инкремент\декремент единичной целочисленной записи.

Есть несколько задач, которые не решаются тривиальными методами:
- очистка кеша всего проекта при выкатывании нового кода
- пересчёт кеш некоторой части кеша при изменении настроек
- блокировка всего (или некоторой части) кеша для заполнения долго-получаемыми данными

Для их решения была придумана модель данных, которую я опишу ниже.