Сегодня, SF Pride '09, мэр Сан-Франциско Гэвин Ньюсом.

(06-24) 13:20 PDT ЮЖНОЕ САН-ФРАНЦИСКО — Бездомный врезал скейтбоурдом по лицу другого бездомного в результате спора на тему квантовой физики и расщепления атомов. SFGate
Интересное случилось на работе. Началось всё с того, что некоторые тесты при своем падении начали тащить за собой весь фреймворк. Т. е. выполняется тест, в тестируемом файле вылезает какая-нибудь ошибка и, вместо того, чтобы записать её в лог и красиво закончить работу, вся тестинговая подсистема падает с сообщением AttributeError: 'NoneType' object has no attribute 'startswith'. Это проявлялось только у меня на компьютере, поэтому, вооружившись дебаггером, я начал ковырять один такой тест.
Сразу выяснилось, что traceback.extract_tb иногда возвращал None вместо содержимого строки, на котором произошла ошибка. Далее джанга пыталась безуспешно вызвать метод startswith у None в результате чего и падала .
Функция extract_tb возвращает None вместо содержимого строки только тогда, когда исходный текст модуля не доступен. Я начал дебаггить модули traceback и linecache, чтобы понять почему мы не можем прочитать прекрасно читаемый файл и обнаружил чудесное:
(Pdb) tb.tb_frame.f_code
<code object click at 0x10894e8, \
file "/home/anton/disqus/disqus/contrib/selenium.py", line 268>
Дело в том, что у меня ни то, что этого файла, у меня даже /home на компьютере нет (на OS X пользовательские директории находятся в /Users). Т. е. в какой-то момент исключение генерировалось из несуществующего файла (cправедливости ради, стоит отметить, что правильная мысль о причине AttributeError у меня была ещё в самом начале, но я её почему-то отбросил). Увидев это, я понял отчего несуществующие файлы у меня бросаются исключениями. Осталось только провести небольшой эксперимент: найти правильный selenium.py, изменить дату модификации и запустить тест заново.
Всё дело в том, что я какое-то время пользовался этой же инсталляцией с удаленной линукс машины, монтировав директорию через sshfs. Линуксовый питон создавал .pyc файлы а, поскольку файл с того момента не менялся, мой текущий питон файлы не пересобирал и соответственно модуль selenium думал, что он находится по старому адресу и этот адрес отдавал дальше по запросу. Модуль traceback, получив такой адрес, пытался прочитать исходный текст файла, не находил его и возвращал None.
Музей компьтерной истории
Скопировал с фотоаппарата и выложил в сеть фотографии, которые я сделал в музее компьютерной истории, что в Маунтин-Вью.
MongoDB
Сегодня был в компании Slide на докладе о MongoDB. MongoDB это высоко-производительная, документо-ориентированная система без формальной схемы базы данных (если я правильно перевел high-performance, document-oriented schema-free database). Половину доклада можно было, в принципе, прочитать у них на сайте, а вот вторая половина — про автоматический шардинг — получилась весьма интересной.
Мы, на работе, тоже используем Монго, но пока только для нескольких небольших проектов. К примеру, все данные для нашего шортера адресов хранятся именно в этой базе данных.
Кстати, интересный факт: поскольку шелл для этой базы данных написан с использованием джаваскрипта, они используют джаваскрипт-интерпретатор. Так вот, раньше они пользовались V8, но недавно переключились на SpiderMonkey. Сегодня я спросил у авторов о причине и оказалось, что V8 очень трудно портировать на 64 битные системы. Вот и весь интересный факт.
Сан-Франциско
В Сан-Франциско холодно и нет солнца и это не смотря на то, что сейчас лето. Последние два-три дня вообще постоянные тучи и туманы.
Google I/O
Нашел себя среди официальных фотографий с Google I/O.
Минут 10 назад, Сергей Брин дает интервью на Google I/O:

Около часа назад, демонстрация возле Верховного Суда Калифорнии.

Суд оставил Prop 8 в силе, тем самым оставив браки между геями вне закона.
UPD: Остальные фотографии.
Когда таблица в классической, реляционной базе данных достигает определенного размера процесс какого-либо изменения её структуры становится очень болезненным. Однако, по мере того, как ваша программа развивается и обрастает новым функционалом, добавлять дополнительную информацию просто необходимо.
У нас чаще всего к большим таблицам нужно добавлять поля-флаги: разрешены ли комментарии в треде, подтвердил ли пользователь свой эл. адрес и так далее. К примеру, с тем пор как мы запустили «социальные комментарии» (на русском это название звучит ещё хуже, чем на английском) к нашим источникам добавились ещё два сайта: Reddit и News YC. А это два новых флага в таблице.
Решение этой задачки далеко не ново и было взято моим коллегой Эндрю из Си: чтобы компактно хранить данные булевого типа в одном поле можно использовать битовые поля. С такими полями нет необходимости каждый раз менять структуру таблиц, достаточно лишь закрепить в коде следующий свободный бит за соответствующим флагом.
Ниже я написал небольшой пример, основанный на используемом нами подходе:
from functools import partial
def bitfield_handler(field, bit):
mask = 2**bit
def _bit_handler(self, value=None):
if value is not None:
oldvalue = (getattr(self, field, 0) or 0)
if value:
setattr(self, field, oldvalue | mask)
else:
setattr(self, field, oldvalue & (~mask))
curvalue = (getattr(self, field, 0) or 0)
return curvalue & mask
return _bit_handler
properties_handler = partial(bitfield_handler, 'properties')
class User(object):
def __init__(self):
self.properties = 0
IS_VERIFIED = properties_handler(0)
RECEIVE_NOTIFICATIONS = properties_handler(1)
if __name__ == '__main__':
user = User()
user.IS_VERIFIED(True)
assert(user.IS_VERIFIED())
assert(not user.RECEIVE_NOTIFICATIONS())
user.IS_VERIFIED(False)
user.RECEIVES_NOTIFICATIONS(True)
assert(not user.IS_VERIFIED())
assert(user.RECEIVE_NOTIFICATIONS())
В принципе, код вполне себе понятный, но если есть какие-либо вопросы — с радостью отвечу на них в комментариях. Вы можете заметить, что конкретно эту имплементацию можно улучшить: использовать свойства вместо обычных методов, не возвращать ничего при установке бита и т. д. Я с этим согласен, но эта заметка не про конкретную реализацию, а про общий подход.
В среду и четверг я буду на конференции Google I/O. Вроде все доклады, на которые хочу сходить, выбрал и занес себе в календарик. Хотя одна дыра всё таки осталась, но её заполню уже на месте. Очень жду V8: Building a High Performance JavaScript Engine и Even Faster Websites.

Создал на фликре коллекцию, куда буду складывать фотографии из Кремниевой Долины. Пока выложил Гуглплекс, Стэнфордский университет и кусочки маленьких американских городков.
Изнутри офисы Гугла мне посмотреть не удалось, потому что я там был проездом, а у них без знакомого сотрудника внутрь не пускают. Как найду кого-нибудь, кто согласится устроить мне тур, так и посмотрю (хотя коллеги по работе говорят, что ничего особенного внутри нет — офисы, как офисы; но всё равно интересно).
Стэнфорд — огромный университет (все красные крыши на фотографиях — здания университета), по территории разбросаны скульптуры Родена, бегают белки и студенты.
|