to post messages and comments.

В догонку.

Deferred — это сердце framework’а асинхронного сетевого программирования Twisted в Python. Это простая и стройная концепция

далее

На практике обычно мы возвращаем Deferred из функций, которые получают Deferred в процессе своей работы, навешиваем большое количество обработчиков, обрабатываем исключения, некоторые исключения возвращаем через Deferred (выбрасываем наверх).

ЛОЛ ШТО?

Разбираясь в документации twisted'a открыл для себя возможность эмуляции сетевых поключений к серверу без наличия сети. Эта фича кстати активно используется в целях тестирования.

Хотел посмотреть что на замену Twisted питонского. Ну, вдруг что изобрели или советуют помимо EM. И что бы вы подумали? Изобрели и советуют. Что? Node.js. Занавес.
На хабре прочитал о том, что "Node.js сами рубисты используют для нестандартных задач, а рельсы для остальной части сайта", в то время как питонисты используют твистед и в ус не дуют, а EM загибается и остаётся эдаким Pylons, который мало кто уже использует, никому он не нужен, да и не советуют его юзать-то.

class ShittyClass(Deferred):
def __init__(self,fuck):
Deferred.__init__(self)
def real_init(self,data):
self.val = data
return self
d = do_some_asynchronous_shit_with_fuck(fuck)
d.addCallback(real_init)
d.chainDeferred(self)

теперь в инлайнколбэкс коде можно создавать объекты с помощью
shitobj = yield ShittyClass('ololo')
я объебос, да

github.com
Если есть достаточно элитная БИДОНОБЛЯДЬ способная пофиксить — реквестирую. Сам я не осилил, насрал гору кода, но нихуя не смог на иозалупе торнады соорудить поведение твистедовских реакторов.

Давеча решал еще такую задачку. Есть класс-родитель, который реализует некий интерфейс. У него может быть много детей, а сколько и каких — неизвестно. Для автораспознавания таких детей я воспользовался системой плагинов Twisted, и тут напоролся на два косяка.

Первый косяк в том, что implements(IMyInterface) работает только на экземпляре класса, а не на самом классе. Что, в принципе, решается созданием экземпляра прямо в модуле, но ведь не хочется, ведь такой класс не обязан быть синглтоном. Это решается тем, что вместо «implements» мы говорим «classProvides» (естественно, заимпортировав его из zope.interface).

Второй косяк — следствие первого. Дело в том, что на порожденные классы classProvides() не распространяется. Чтобы это обойти, надо сделать метакласс для родительского класса, в __new__() которого для свежеобразованного класса будет вызываться directlyProvides(klass, IMyInterface).

Вот такое вот.

Мне вот рассказали, а я и не знал. Когда вы делаете какой-нибудь Deferred, даете ему addCallback(blabla).addCallback(bleble)…. и так несколько раз, то вся эта цепочка будет выполнена в один присест. Так что, во-первых, не делайте такие цепочки слишком длинными, а то можете реактор раком поставить, а во-вторых, если вам что-то такое эдакое надо циклично жевать неизвестное наперед число раз из одного Deferred'а — используйте twisted.internet.task.coiterate, оно для того и задумывалось.

Кстати, этот факт напрямую из документации неочевиден.

Очередной фейл в твистеде: искал, почему же у j2j всё ещё течёт память. Оказалось, проблема в Twisted: его функция internJID (http://twistedmatrix.com/documents/current/api/twisted.words.protocols.jabber.jid.html#internJID) не имеет нормального описания, но нужна, судя по всему, для кеширования JIDов, чтобы не делать им каждый раз stringprep, экономя таким образом процессорное время. (Иного объяснения я не нашёл.) Так вот, эта функция никогда не очищает кеш. А так как JIDов через j2j проходит достаточно много, через три дня работы их собирается порядка 40К, на ещё более нагруженных сервисах ситуация будет ещё плачевнее (особенно, если сервис будет без регистрации, а пользоваться им будут люди с огромного к-ва разных серверов.) Поэтому, для теста, сваял патчик, который очищает JIDы, не использовавшиеся в течение 10 минут. Теперь, вроде бы, ситуация стабилизировалась. По-хорошему, там бы использовать memcached и не выпендриваться. Если у кого-то есть такая же проблема и желание протестировать, это ли её причина, обратитесь ко мне за патчем.

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

Тихо и незаметно вышел новый Twisted. Где посмотреть Changelog я не нашёл, кто-нибудь знает?
Надо затестить, реально ли хоть на этом запускать эти ваши жабьи транспорты...

Кажется, начал изучать Twisted.
Дежавю. Именно идея с асинхронными колбэками широко используется во Flex. Но там она вызывает отторжение. То ли потому что туда еще и ООП намешали, то ли еще почему...

Пренеприятная бага с постоянным вылетанием J2J уже пофикшена в Twisted 10.2.0. Для него никаких дополнительных патчей уже не требуется. Советую всем обновиться, причём если есть любые транспорты/боты на Twisted.

Наткнулся на багу в твистеде (http://twistedmatrix.com/trac/ticket/4520): [Failure instance: Traceback: : exceptions must be classes, or instances, not type /usr/lib/python2.6/site-packages/twisted/internet/defer.py:307:errback /usr/lib/python2.6/site-packages/twisted/internet/defer.py:354:_startRunCallbacks /usr/lib/python2.6/site-packages/twisted/internet/defer.py:371:_runCallbacks /usr/lib/python2.6/site-packages/twisted/internet/defer.py:879:gotResult --- --- /usr/lib/python2.6/site-packages/twisted/internet/defer.py:821:_inlineCallbacks /usr/lib/python2.6/site-packages/twisted/python/failure.py:338:throwExceptionIntoGenerator site.py:59:respond /usr/lib/python2.6/site-packages/twisted/internet/defer.py:821:_inlineCallbacks /usr/lib/python2.6/site-packages/twisted/python/failure.py:338:throwExceptionIntoGenerator ] Уже 2 месяца прошло, а её не чинят :/

[Failure instance: Traceback: : global name 'fuck' is not defined /home/stil/git/private/bsr_shortstat/tornado/web.py:685:_execute /home/stil/git/private/bsr_shortstat/tornado/web.py:774:wrapper site.py:48:get /usr/lib/python2.6/site-packages/twisted/internet/defer.py:944:unwindGenerator --- --- /usr/lib/python2.6/site-packages/twisted/internet/defer.py:823:_inlineCallbacks site.py:57:respond ]