Analitycs

пятница, 10 февраля 2012 г.

Как запускать периодические задачи на Tornado? PeriodicCallback!

Продолжая тему периодических задач в Twisted, в Tornado это делается немного по другому - с помощью специального tornado.ioloop.PeriodicCallback.

Примерчик - если кому пригодится

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import tornado.web
import tornado.httpserver
import tornado.ioloop

PERIOD = 30 # в минутах

class MyApplication(tornado.web.Application):

  def period_run(self):
    # чего-то тут делаем
    pass

...

app = MyApplication(handlers=urls, **settings)

http_server = tornado.httpserver.HTTPServer(app, xheaders=True)
 
loop = tornado.ioloop.IOLoop.instance()
period_cbk = tornado.ioloop.PeriodicCallback(app.period_run, 1000*60*PERIOD, loop)

period_cbk.start()

loop.start()

вторник, 7 февраля 2012 г.

Как сделать hard-reset на LG Optimus Black?

Шаманство с зажатием Volume Down + Power + Home при включении не прокатило, может граната у меня не той системы?

В итоге - hard-reset через коды

dial 3845#*970#

Разумеется - все данные похерятся.


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

Сервер боевой или production? - или лингвистические особенности

Забавный лингвистический факт.

Сервера, на которых крутятся сайты/сервисы для клиентов:

  • в английском языке они всегда называются production server - PRODUCTION, то есть производственные. 
  • в русском же языке сплошь и рядом - БОЕВЫЕ сервера. То есть - те, на которые идешь в бой, соответсвенно - либо победишь, либо проиграешь.

Ох, не спроста имеется эта разница в национальных названиях... ох не спроста ;-) ;-)

пятница, 3 февраля 2012 г.

Как перезапустить демонизированный процесс в Supervisord?

Если в supervisord запущено несколько процессов и один из них отвалился, не нужно перезапускать демон целиком - есть консольная утилитка supervisorctl.

# supervisorctl
api-test-data                    RUNNING    pid 22443, uptime 1 day, 16:52:01
api-test-empty                   FATAL      Exited too quickly (process log may have details)
auth-service                     RUNNING    pid 22444, uptime 1 day, 16:52:01

Ага, вот процесс-виновник - перезапускаем халявщика

supervisor> start api-test-empty
api-test-empty: started

supervisor> status
api-test-data                    RUNNING    pid 22443, uptime 1 day, 16:52:29
api-test-empty                   RUNNING    pid 27360, uptime 0:00:13
auth-service                     RUNNING    pid 22444, uptime 1 day, 16:52:29
supervisor> 

Все ОК - "13 секунд, полёт нормальный. Хьюстон, у нас НЕТ проблемы" (с)

вторник, 31 января 2012 г.

Python/PHP - запятая - казнить нельзя помиловать

Сегодня ловлю баг в сервисе - в JSON-результате вместо поля с integer  выдается список элементов-integer, то есть вместо

data : {
  'id' : 1
}

упорно получаю

data : {
  'id' : [1]
}

Перепроверяю код 20 раз - ничего не могу понять... вроде все правильно, должен быть идентификатор ОДИН, но хоть ты тресни - список. Подвисаю на несколько минут, иду попить кофе, снова смотрю в код...

Через несколько минут доходит - начинаю истерически хохотать

def bla-bla(self, args): 
    data = {
      'bla-bla' : bla_bla,
      'name' : name,
      'id' : temp_id,
    }
  return data


Правлю один символ - все работает. После хохота начинаю вспоминать хорошего PHP team-leader, с которым работал много-много лет назад.

Он был большим аккуратистом в плане чистоты форматирования кода и железнобетонно приучил меня расставлять меня запятые в ассоциативных массивах в КАЖДОМ элементе, включая последний.  Так как в случае необходимости быстро переставить элементы в коде - не пришлось бы искать потенциальную ошибку c пропущенной запятой.

А для Python - это собственно - сокращенный формат списка-последовательности.

Так что вот вам прекрасный пример того, что старые привычки часто вредят, а иногда - вредят ОЧЕНЬ сильно. "Казнить нельзя помиловать" (с)   ;-)

Ну и верный вариант - БЕЗ запятой ;-)

def bla-bla(self, args): 
    data = {
      'bla-bla' : bla_bla,
      'name' : name,
      'id' : temp_id
    }
  return data

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

Javascript+Flash мультизагрузчики картинок (SWFUpload, Uploadify) и Error #2038

Иногда мультизагрузчики изображений с использованием Flash (SWFUpload, Uploadify и т.д) дают ошибку #2038 при загрузке на случайных картинках без всяких видимых причин.

Как выяснилось - может быть целая куча разномастных серверных проблем - причем проблем преимущественно backend'овских.

TODO-list
  • обновляем Flash загрузчик до последней версии;
  • проверяем, что POST приходит на сервер в скрипт загрузки нормально - без всяких HTTP авторизаций, сессии нормально передаются, пользователь распознается залогиненным и т.д.;
  • и внимание - ЭПИЧНАЯ ОШИБКА: Размер разрешенных вложений должен быть <= размеру upload_max_filesize в php.ini;

И только потом лезем в настройки сервера - для nginx решение

Открываем nginx.conf и в http секцию добавляем директиву

client_max_body_size 500m;  

И удаляем из конфига директиву keepalive_timeout

Через некоторое время, когда у пользователей обновится кеш браузера - начинает все работать

пятница, 27 января 2012 г.

Python implode/join - TypeError: sequence item 0: expected string, int found

Одна из частых функций в PHP проектах - implode/explode.

На Python (по идее/по мануалу) это делается так

tmp = [1,2,3,4,5]
','.join( tmp )

Но в результате - получаем ошибку TypeError: sequence item 0: expected string, int found

Проблема - в том, что у нас числа, а не строки

 В итоге - нужно так

','.join( map( str, tmp ) )
'1,2,3,4,5'

Но вот пресловутое неявное приведение типов-то в PHP как помогает, а? ;-)