Analitycs

Показаны сообщения с ярлыком twisted. Показать все сообщения
Показаны сообщения с ярлыком twisted. Показать все сообщения

воскресенье, 29 апреля 2012 г.

Востребованность Python Tornado/Twisted

Кстати - об асинхронных фреймворках и их востребованности.

Решил пробить количество вакансий на асинхронные фреймворки на Python - Twisted и Tornado.

Далее факты - и ничего кроме фактов.

Linkedin

  • python twisted - 10 вакансий против 1026 участников
  • python tornado - 14 вакансий  против 815 участников

HH

  • python tornado - 0
  • python twisted - 1 вакансия

Moikrug

  • python twisted - 2 вакансии
  • python tornado  - 1 вакансия

То есть в мире - на 1 открытую вакансию на асинхронный питон приходится 100 кандидатов для twsted и 59 - tornado.

Что интересней -  linkedin по запросу python django дает 208 вакансий 18469 участников - на 1 вакансию 71 потенциальный кандидат.

Что как-бы намекает...

Ну а php -  вообще полный ахтунг - 2060 вакансий и 634347 кандидатов -> 308 человек на одну позицию.

Кстати, хороший Python-dev с Торнадой/Twisted по прежнему - ищется.

понедельник, 27 февраля 2012 г.

Ищу Python developer - Junior, СПб


Ищу будущих коллег и хороших людей:


Обязанности:

Разработка и сопровождение серверной части проекта Омлет.ру (легальный видео-контент);

Что хотим  от вас?

  • Хороший опыт работы с бекендами сайтов
  • Опыт разработки на Python или устойчивое желание его изучить - при наличии знаний других языков (С#, PHP, Perl , Ruby);
  • Знание MySQL;
  • Аналитический склад ума,
  • Коммуникабельность,
  • Знание основ ООП,
  • Самообучение и саморазвитие,
  • Чувство юмора и адекватность - обязательно.

Вы кандидат нашей мечты, если...

  • уже работали с Python
  • есть опыт работы с no-SQL решениями,
  • есть опыт работы с высоконагруженными веб-сервисами/сайтами - не стесняйтесь показывать портфолио - нам это интересно;
  • владеете хорошей математической базой;
  • знаете и применяете различные языки программирования, новейшие технологии,
  •  владеете английским языком
Если есть практический опыт Tornado/Twisted - вам большой такой плюс, перекрывающий многие минусы.

Что мы предлагаем?

  • Возможность забросить PHP - вам еще не надоело? 
  • Работу в большом и интересном проекте
  • Офис - ст. метро Василеостровская + 5 минут ходьбы - и то прогулочным шагом 
  • Неординарные задачи
  • Полностью белое оформление и ЗП
  • Повышенный отпуск - как компенсация за ненормированный рабочий день
  • Корпоративную симку для связи
  •  После испытательного срока - ДМС

При наличии знаний и умений из способностей кандидата нашей мечты - позиция может быть повышена, причем - значительно, начинаем от 50к белыми.

вторник, 27 декабря 2011 г.

Twisted или Tornado - без разницы - все идиоты

Внимание - Важное сообщение для блоггеров-питонистов!


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

Похоже, что уже всем стало ясно что "матч века" - Twisted.web против Tornado от Friendfeed показал, что ни одна из сторон не особо победила, но и не особо проиграла - и в тоже время стопудово - что обе стороны выглядят достаточно глупо.


Во-первых, Twisted. Сейчас моя компания использует его за небольшую часть функциональности, потому что ТОГДА - это был самый простой способ, что мы нашли для отправки трафика через различные сетевые интерфейсы на Linux машинах. Мы никогда не имели с ним никаких проблем. Единственная причина, по которой мне необходимо его когда-нибудь тронуть - это чтобы увидеть, как что работает.

Тем не менее, Twisted, вероятно, самая запарная программная библиотека. Каждый раз, когда я открываю этот код, я чувствую, что я забрел в ночной бар на берегу Джерси, где все пьяные в хлам и уже давно сорвали свои рубашки. Twisted классная библиотека, но в тоже время - НЕДОСТАТОЧНО классная, чтобы действительно называться "Twisted". Это Python- программистская версия одежды и бейсболок Ed Hardy, которая все еще висит в стороне (модная вещь, которая не используется). Когда я копался в этом коде и мои коллеги спрашивают меня, что случилось, единственным адекватным ответом было я "НЕ СЕЙЧАС, шеф - я запускаю этот хренов реактор ".

Теперь вы можете понять, почему появилась и существует такая хрень, как Tornado.

Хотя я постоянно не рекомендую делать такие вещи как Tornado - Friendfeed все-таки ее сделали. Из тех графиков, которые я видел, Tornado просто незначительно быстрее, чем Twisted на обслуживании большого количества одновременных запросов. НЕЗНАЧИТЕЛЬНО. Очевидно, в Friendfeed полагали, что достаточно небольшая разница в скорости была достаточным основанием тратить свое время и что-то переписывать заново- что обычно и делает каждый разработчик, которому становится скучно на работе. Веб-фреймворк на Python? О боже - как это оригинально! Я думаю, что это один из последних уроков книжки "Изучи Python за 24 часа".

В Friendfeed потратили много времени, пытаясь оптимизировать количество запросов в секунду, отображаемого на графике, но, возможно, им следовало бы тратить больше времени на оптимизацию ВОТ ЭТОГО графика - вместо первого:

Во всяком случае, когда речь идет о выборе Twisted vs Торнадо для веб-фреймворка, я использую Django. Почему? Потому что это работает, и мое время ценно.

Достаточно вольный перевод вот этой заметки. Спасибо автору

Кстати, достаточно интересно пишет, хотя и многие слова приходится долго думать - перед тем как перевести на русский.

пятница, 9 декабря 2011 г.

HeadHunt: нужны Highload Python, AppManager и тестеры

Мы ищем несколько человек - специалистов по highload Python, один application manager и хороших тестировщиков в СПб.

"Мы" - это ООО «Стрим», дочерняя компания ОАО «МТС»

Разработчик платформенных решений ( Python, Highload)

Обязанности:

  • разработка и дальнейшее сопровождение серверной части медийных сервисов для проекта Омлет.ру (в первую очередь сервиса управления и распространения легального видео-контента);
  • консультирование по вопросам высоконагруженных систем.
Требования:
  • опыт разработки на Python от 2 лет;
  • хорошее знание SQL, опыт работы, а так же оптимизации и тюнинга СУБД PostgreSQL или MySQL;
  • опыт работы с no-SQL решениями,  в проектах по запуску высоконагруженных веб-сервисов (от 500 тыс показов в сутки);
  • аналитический склад ума, коммуникабельность, знание основ ООП, хорошая математическая база;
  • дополнительными плюсами являются: знание и опыт применения различных языков программирования, новейших технологий, самообучение и саморазвитие, английский язык, опыт создания несложных UI
Если будет практический опыт Tornado/Twisted - вам большой такой плюс.

Специалист по передаче в эксплуатацию (application manager)

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

Задачи:
  • написание скриптов деплоя приложений или настройка специализированной среды развертывания приложений;
  • приемка серверных приложений после тестирования;
  • передача приложения в эксплуатацию;
  • валидация документации по установке приложений;
  • написание документации по эксплуатации;
  • анализ поведения приложений при эксплуатации, выявление сложностей эксплуатации приложений; 
Требования к кандидату:
  • владение linux на уровне базового администрирования;
  • владение windows на уровне продвинутого пользователя;
  • опыт написания скриптов на shell;
  • знание одного из языков: php, ruby, python;
  • опыт написания документации;
  • аналитический склад ума;

Специалист по тестированию

Обязанности:
  • тестирование серверных компонент видео-сервиса и всего сервиса в целом, в том числе - автоматизация тестирования и нагрузочное тестирование
Требования:
  • образование в сфере ИТ, желательно понимание основ программирования;
  • опыт функционального и нагрузочного тестирования от 2 лет;
  • хорошее знание SQL;
  • опыт работы в проектах по запуску высоконагруженных веб-сервисов (от 500 тыс. показов в сутки);
  • аналитический склад ума, коммуникабельность, знание основ ООП;
  • владение инструментами JMeter или аналогичными;
  • дополнительными плюсами являются: знание и опыт применения различных языков программирования, знание английского языка.
Условия для всех вакансий:
  • вся белая ЗП, оформление по ТК;
  • ненормированный рабочий день;
  • 31 день оплачиваемого отпуска;
  • испытательный срок 3 мес.
  • ДМС после прохождения испытательного срока;
  • корпоративная мобильная связь;
  • квартальные и годовые бонусы;

Если ваше резюме удовлетворяет требованиям на 3/4 - смело шлите его на michael(dot)neradkov(dog)gmail(dot)com. 

Буду признателен, если поделитесь информацией со своими знакомыми.

Заранее спасибо!



понедельник, 14 ноября 2011 г.

Как реализовать периодические задачи в Twisted? (cron vs LoopingCall)

Первое что делают все программисты на Twisted, чтобы сделать периодические задачи - это лезут в cron. Я сам так раньше делал - и, к сожалению, не было никого рядом, чтобы стукнуть меня бамбуковой палкой по рукам.

Есть же методически грамотное, ВСТРОЕННОЕ решение - и нашел я его сегодня случайно, когда искал совершенно другую вещь.

from twisted.internet.task import LoopingCall

#==============================================================================
class MySuperServer(MyServer, twisted.web.server.Site):
    '''
    мой собственный веб-сервер, с блекджеком и шлюхами ;-)
    '''

    def __init__(self):
        lp = LoopingCall(self.checkStatus)
        lp.start(1.0) # период в секундах    

    def checkStatus(self):
        #self._log('Looping call')
        pass

четверг, 3 ноября 2011 г.

Python, Twisted, logging - Как логгировать несколько процессов/демонов в один файл?

Давайте поговорим немного про логгирование в Python.

Да, меня это ДЕЙСТВИТЕЛЬНО беспокоит, и я хочу об этом поговорить ;-)

Совсем недавно столкнулся с тем, что достаточно серьезный проект при портировании с Linux на MacOS потерял логгирование. Ну нет лог файла - и все тут. Полез в код разбираться - выяснилось, что разработчики очень любили изобретать велосипеды и делали логгирование через файл, открытый ручками и обычную запись туда переменных - прямо в файл. Все это работало... до поры до времени. Пришлось на скору руку переписывать.

В общем, мораль сей басни такова...

Есть в Python СТАНДАРТНЫЙ модуль logging  - его и нужно использовать для разного типа логгирования. Батарейка-то уже включена ;-)

Чтобы пример кода не был совсем тривиальным - приведу решение для той ситуации, когда у нас есть несколько многопроцессных РАЗНЫХ демонов на Twisted на одной машине, а еще и cron-скрипт запускается время от времени. И всю жизнедеятельность этого дурдома нужно логгировать в один файл

import os
import logging
from twisted.python import log                                                                                   

CURRENT_PATH = os.path.realpath(os.path.dirname(__file__))

# Все это "по уму" обычно запихивается в нормальный конфиг-файл
LOG_DIR = os.path.join(CURRENT_PATH, 'logs')                            
LOG_FILE = os.path.join(LOG_DIR, 'super-puper.log')  
LOG_LEVEL = logging.INFO
 
# инициализируем
FORMAT = ('%(asctime)-15s %(levelname)s %(message)s') 

if not os.path.exists(LOG_DIR):
    os.mkdir(LOG_DIR) 
 
logging.basicConfig(format=FORMAT, filename=LOG_FILE, handler=logging.handlers.RotatingFileHandler)   
observer = log.PythonLoggingObserver(loggerName='twisted')
observer.start()
observer.logger.setLevel(LOG_LEVEL)  

# класс-примесь для логгирования - в принципе - необязательно, реализация может быть разная - хоть функциями
class BasicLogClass():

    def _log(self, msg):
        log.msg(msg, logLevel=logging.INFO)

    def _error(self, msg):
        log.msg(msg, logLevel=logging.ERROR)

    def _warning(self, msg):
        log.msg(msg, logLevel=logging.WARNING)

В данном варианте работоспособность не проверял, но логика применения именно такая - выкусил из работающего проекта.

Кстати, если у кроновских скриптов нет использования twisted'овского reactor, то могуть быть проблемы, нужно подумать. Как вариант - использовать развилку в инициализации и логгировании без применения observer, но не уверен.

пятница, 28 октября 2011 г.

Распространение приложений на twisted

Как выяснилось - nobody cares по поводу фигурок, так что продолжу сношать вам мозг выкладывать технические статьи и старые переводы.

Моя работа — создание различных приложений на Twisted для работы с многочисленными веб-сервисами. В отличие от проектов на TurboGears, которые я распространяю как eggs с помощью easy_install (через setuptools) у меня не было удобного способа «выкатить» проекты на Twisted.

До этого момента.

Twisted преодставляет удобную систему плагинов, которые позволяют приложениям встраиваться в «twistd» стартер.

Только одна проблема — полное отсутствие приличной документации об этом процессе.

Ниже я хочу привести небольшой рассказ о том, как можно собрать простое приложение в пакет twisted. На самом деле — я возьму известный туториал — Twisted finger и допишу шаг №12: «Как создать пакет для finger как приложение Twisted для twistd» (aka «Пропущенный шаг»).

Step 12: How to package the finger service as an installable Twisted application plugin for twistd

Создайте структуру каталогов, как показано ниже

finger
finger/__init__.py
finger/finger.py
MANIFEST.in
setup.py
twisted
twisted/plugins
twisted/plugins/finger_plugin.py

finger/finger.py — приложение finger отсюда. twisted/plugins — структура каталогов, содержит файл finger_plugin.py, который будет описан ниже.

Обратите внимание — никаких файлов __init__.py в каталогах twisted и twisted/plugins — это важно!

 finger_plugin.py реализует интерфейсы IServiceMaker и IPlugin.
# ==== twisted/plugins/finger_plugin.py ====
# - Zope modules -
from zope.interface import implements

# - Twisted modules -
from twisted.python import usage
from twisted.application.service import IServiceMaker
from twisted.plugin import IPlugin

# - Finger modules -
from finger import finger

class Options(usage.Options):
    synopsis = "[options]"
    longdesc = "Make a finger server."
    optParameters = [
        ['file', 'f', '/etc/users'],
        ['templates', 't', '/usr/share/finger/templates'],
        ['ircnick', 'n', 'fingerbot'],
        ['ircserver', None, 'irc.freenode.net'],
        ['pbport', 'p', 8889],
    ]
    
    optFlags = [['ssl', 's']]

class MyServiceMaker(object):
    implements(IServiceMaker, IPlugin)
    
    tapname = "finger"
    description = "Finger server."
    options = Options
    
    def makeService(self, config):
        return finger.makeService(config)

serviceMaker = MyServiceMaker()


setup.py стандартный файл установщика. Обратите внимание на аргументы «packages» и «package_data» в функции setup() и функцию- refresh_plugin_cache(), которая вызывается после того, как полностью отработает setup()s. Последняя вручную сбросит кэш плагинов Twisted (twisted/plugins/dropin.cache).
# ==== twisted/plugins/finger_plugin.py ====
'''setup.py for finger.

This is an extension of the Twisted finger tutorial demonstrating how
to package the Twisted application as an installable Python package and
twistd plugin (consider it "Step 12" if you like).

Uses twisted.python.dist.setup() to make this package installable as
a Twisted Application Plugin.

After installation the application should be manageable as a twistd
command.

For example, to start it in the foreground enter:
$ twistd -n finger

To view the options for finger enter:
$ twistd finger --help
'''

__author__ = 'Chris Miles'


import sys

try:
    import twisted
except ImportError:
    raise SystemExit("twisted not found.  Make sure you "
                     "have installed the Twisted core package.")

from distutils.core import setup

def refresh_plugin_cache():
    from twisted.plugin import IPlugin, getPlugins
    list(getPlugins(IPlugin))

if __name__ == '__main__':
    
    if sys.version_info[:2] >= (2, 4):
        extraMeta = dict(
            classifiers=[
                "Development Status :: 4 - Beta",
                "Environment :: No Input/Output (Daemon)",
                "Programming Language :: Python",
            ])
    else:
        extraMeta = {}

    setup(
        name="finger",
        version='0.1',
        description="Finger server.",
        author=__author__,
        author_email="you@email.address",
        url="http://twistedmatrix.com/projects/core/documentation/howto/tutorial/index.html",
        packages=[
            "finger",
            "twisted.plugins",
        ],
        package_data={
            'twisted': ['plugins/finger_plugin.py'],
        },
        **extraMeta)
    
    refresh_plugin_cache()

MANIFEST.in содержит одну строчку, которая, как я полагаю, указывает distutils изменить существующий пакет Twisted (для установки twisted/plugin/finger_plugin.py) и нечто наподобие. graft twisted Это все для того, чтобы можно было начать установку пакета обычным способом:

$ python setup.py install

После этого нужно запустить twistd — чтобы убедится, чтто приложение установилось нормально и доступно. Посмотрите на опции twistd:

$ twistd --help

Usage: twistd [options]

 ...

Commands:
 athena-widget Create a service which starts a NevowSite with a single
 page with a single widget.
 ftp An FTP server.
 telnet A simple, telnet-based remote debugging service.
 socks A SOCKSv4 proxy service.
 manhole-old An interactive remote debugger service.
 portforward A simple port-forwarder.
 web A general-purpose web server which can serve from a
 filesystem or application resource.
 inetd An inetd(8) replacement.
 vencoderd Locayta Media Farm vencoderd video encoding server.
 news A news server.
 words A modern words server
 toc An AIM TOC service.
 finger Finger server.
 dns A domain name server.
 mail An email service
 manhole An interactive remote debugger service accessible via
 telnet and ssh and providing syntax coloring and basic
 line editing functionality.
 conch A Conch SSH service.


Посмотрим опции нашего сервера finger в плагине:

$ twistd finger --help
Usage: twistd [options] finger [options]

Options:

 -s, --ssl 
 -f, --file= [default: /etc/users]
 -t, --templates= [default: /usr/share/finger/templates]
 -n, --ircnick= [default: fingerbot]
 --ircserver= [default: irc.freenode.net]
 -p, --pbport= [default: 8889]
 --version 
 --help Display this help and exit.

Make a finger server.


Запустим сервер finger в консоли:

$ sudo twistd -n finger --file=users

2007/12/23 22:12 +1100 [-] Log opened.
2007/12/23 22:12 +1100 [-] twistd 2.5.0 (/Library/Frameworks/Python.framework/
Versions/2.5/Resources/Python.app/Contents/MacOS/Python 2.5.0) starting up
2007/12/23 22:12 +1100 [-] reactor class: 
2007/12/23 22:12 +1100 [-] finger.finger.FingerFactoryFromService starting on 79
2007/12/23 22:12 +1100 [-] Starting factory 
2007/12/23 22:12 +1100 [-] twisted.web.server.Site starting on 8000
2007/12/23 22:12 +1100 [-] Starting factory 
2007/12/23 22:12 +1100 [-] twisted.spread.pb.PBServerFactory starting on 8889
2007/12/23 22:12 +1100 [-] Starting factory 
2007/12/23 22:12 +1100 [-] Starting factory 

twistd предоставляет многочисленные полезные возможности — такие как запуск демона, указания расположения лог и pid файлов и т.д…

К сожалению Twisted и setuptools не очень хорошо взаимодействуют вместе, так что я не смог упаковать мое приложение Twisted как egg, нужно повозится с системой разрешения зависимостей setuptools, или установить используя easy_install.

Ссылки



Источник, хабра

вторник, 25 октября 2011 г.

Сравнение нагрузки PyCurl vs HTTPClientFactory+Deferred в сервисе на Twisted

Решил перевыложить с хабры свое небольшое старое исследование по поводу производительности Twisted при использовании  PyCurl и HTTPClientFactory - пусть лежит все в одном месте, раз уж начал активно писать в блог.

В процессе разработки одного проекта на Python+Twisted (распределителя запросов между несколькими СМС гейтами Kannel) пришлось переписать вызов URL различных сервисов с разных серверов c блокирующего вызова через PyCurl на неблокирующий (client.HTTPClientFactory + deferred). Чтобы иметь перед глазами реальные данные о нагрузке, решил дать много запросов и посмотреть на результаты

Описание теста

Использовался Jakarta/Apache Jmeter - очень полезная софтинка, к сожалению, почему-то применяют ее для тестов достаточно редко (может, просто не знают о ее существовании?), но мне она весьма нравится - ибо возможности у нее большие и даже краткое описание наврядли влезет в несколько постов - если кому интересно, могу потом пробежаться по ней вкратце.
В 200 потоков прогнано 100 запросов на один и тот же сервер, но со случайными данными (чтобы исключить кэширование). Прогонялось на обыкновенной рабочей машине с GUI под Ubunta — так, для примерной оценки.

Результаты теста

Одна ошибка — не справилась база, так что погрешностью можно пренебречь.

Графики распределения

Блокирующий (PyCurl)
Неблокирующий (deferred)

Итоги

Как видно из результата теста — при одинаковой нагрузке при использовании defered минимальное значение отклика сервера почти в 2.5 раза меньше (из-за отказа базы), а максимальное — меньше в два раза, чем у блокирующего. Среднее значение - также меньше в 2 раза.

Америку я, конечно, не открыл, но по-крайней мере — теперь на руках конкретные цифры по производительности. Надеюсь, кому-нибудь они пригодятся.

четверг, 20 октября 2011 г.

Как демонизировать(daemon) проект на Twisted?

Есть три способа демонизировать проект на Twisted.

1) использование родного демона twistd. По идее - это более "методически грамотный" способ, но в свое время что-то не завелся у меня "в лоб", по этому до сих пор применяю второй.

2) скрестить старый работающий демон с реактором Twisted

#!/usr/bin/python                                                                                               
import sys
import src.daemon
import procname

class YourServer(twisted.web.server.Site):
    pass

class YourDaemon(Daemon):
    name   = 'yourserverd'
    site   = None
    server = None

    #--------------------------------------------------------------------------
    def __init__(self):
        self.server = YourServer()
        Daemon.__init__(self, pidfile='/var/run/%s.pid' % (self.name.lower()) )
        procname.setprocname(self.name)

    #--------------------------------------------------------------------------
    def run(self):
        self.server = YourServer()
        reactor.listenTCP(self.server.port, self.server)
        reactor.run()

if __name__ == '__main__':
      daemon = YourDaemon()
      daemon.processAction(sys.argv)

Да, procname служит для переименования процесса, о чем писал тут.


3) есть еще правда и python-daemon (PEP-3143), надо бы повнимательней изучить, но думаю что родной twistd оптимальней.