Как стать автором
Обновить

Комментарии 42

я не ставил себе целью сразу писать целую книгу про Nagare. Все будет! Функционал там отнюдь не стандартный, просто это пока не очень заметно :)
про «премилую гостевую книгу» — скрин бы не помешал.
вот она, аж слезы наворачиваются:



:)
хе-хе, там скорей всего два поля и кнопка, что ж там смотреть то? :) Это ж стартовый пример.
Эхъ молодёж, вам не понять…
Но-но, это мой второй в жизни скриптик на перле был на заре изучения в далёком 99-м!
Вы бы написали основные преимущества и отличия от остальных подобных фреймворков.

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

Стандартный возможности веб-фреймворка думаю мало интересны. Для этого лучше использовать Джанго.

Жду продолжения :)
основная возможность stackless, используемая в Nagare — это сохранение continuations между запросами, так что приложение можно писать «линейно», аналогично десктопному. Но и взаимодействие между потоками можно устроить. Например, при помощи глобальных переменных :)
Да, вот про это интересно почитать будет! :)
да, собственно, технология настолько проста, что почти невидима :)
В приведенном примере

@presentation.render_for(Test1)
def render(self, h, *args):

— так задается функция, аналогичная функции перерисовки в десктопных приложениях. Все глобальные переменные и методы объекта Test1 сохраняются при перезагрузках, можно хранить в них, например, статус авторизованности пользователя. Глобальные переменные еще и общие для всех потоков.
> Но и взаимодействие между потоками можно устроить. Например, при помощи глобальных переменных
Это как? Расскажите, очень интресно.
да банально. На каждую сессию создается экземпляр класса (в данном случае Test1), «локальные переменные» — это поля объектов. Можно задать переменные прямо в модуле, они будут общими для всех объектов.
Race condition? Если его будут менять в несколько потоков, то этот объект очень часто будет в неадекватном состоянии.
вроде в питоне это как-то решается, типа гигантского лока что-то есть. Но, конечно, это самый примитивный метод, ничто не мешает использовать всякие продвинутые способы типа IP с семафорами и т.п., правда, это не будет работать на кластере, наверное.
В том-то и проблема, что гагантский лок убьет всю параллельность — т.к. каждая нить будет упираться в нее и ждать другую. Семафоры это тоже самое, только сделанное Вашими руками. В многопоточных системах глобальные данные это полный ахтунг. Особенно когда начнется неконтролируемое изменение и это повлечет фантомные баги.

Мне интересно есть ли в Нагаре какие-то средства обмена данными между потоками, или придется все в лоб решать?
все зависит от частоты транзакций и их сложности. Думаю, для абсолютного большинства приложений ситуация взаимной блокировки будет большой редкостью.

Вообще-то я пока не разбирался с этой частью функционала. На сайте разработчиков есть пример чата, реализованного по технологии Comet, там, кажется, должно быть именно то, что нужно — взаимодействие между различными сессиями.
Nagare довольно спорное творение — вам часто требовались продолжения? Конечно возможности stackless сериализовать тасклет вызывает некоторый зуд в руках, но нам бы пример не для хомячков — пример, где реально нужны эти самые продолжения.
У меня вот не рождается мысли, где бы это применить.
да практически в любом приложении с нетривиальной логикой или таком, где нужно работать с большим количеством вводимых пользователем данных. Например, вместо того, чтобы делать одну огромную форму, можно очень легко сделать «визард» с кнопками «вперед» и «назад», практически ничего не меняя, поскольку значения с предыдущих шагов будут спокойно лежать в переменных.
Это легко делается без продолжений.
но с продолжениями это делается естественно, а все остальные решения похожи на костыль :)
Не вижу ничего костыльного в сессиях — это их прямое предназначение. А вот сериализация целого тасклета пахнет накладными расходами.
В общем неоднозначен Nagare.
сессии самый что ни на есть костыль для stateless HTTP.
У нас с вами разные понятия о костылях — хранение парочки переменных от запроса до запроса это явно меньший оверхед, чем хранение от запроса до запроса всего тасклета. И в чем принципиальная разница между эти двумя техниками, я не особо улавливаю.
Ну и главное — не вижу ничего ужасного в stateless природе HTTP, это имеет свои преимущества.
Хорошо, можете сказать, зачем нужны сессии, кроме как для обхода этого ограничения? В чем может быть преимущество отсутствия возможности? Если какая-либо возможность есть, ей можно либо пользоваться, либо нет. Хочешь, чистишь память после выполнения запроса, не хочешь — не чистишь.
з.ы. еще и в карму плюнуть не забыл, ну-ну…
Вы правда не читали мой комментарий? Это распространенная проблема, к сожалению.

P.S. не кармадрочерствуйте — да плюнул, наверное для этого там и есть плюсик и минус, как вы считаете?
Nagare где хранит сериализованные тасклеты?
там есть варианты. Наиболее продвинутый — хранить в memcache, что позволяет запускать приложение на кластере.
какая-то жуть — шаблоны через with) Это что, рекомендованный способ там?
это не шаблоны :) Шаблоны там тоже есть, но смысл из примененять в простой программе? Конструкции с with — просто очень красивый способ автоматического закрытия тэгов. Кстати, при использовании шаблонов ничто не мешает вставлять в них куски кода, сгенерированного таким образом, что позволяет, иногда, сильно упростить сами шаблоны.
В том-то и дело, что это не шаблоны)

По-моему так и в этом простом примере html-код было бы писать быстрее, проще, короче, понятнее, а with — ужас!

> with h.td(valign=«top», align=«right»)

тут мало того что в код на python имеем вкрапления html, так этот html еще и используется не только как разметка, но еще и как представление — все эти align=right делаются в css. Напомнило вывод html в php через echo, только с микро-бонусом закрывающихся тегов.

Понятно, что этим синтаксисом можно не пользоваться, но зачем вообще такую возможность давать — непонятно, это ж прям сборник вредных советов Г. Остера)

Чтоб теги сами закрывались, лучше уж что-нибудь вроде haml использовать. Но вообще проблемы не вижу, кстати, с закрытием тегов — они в IDE и так сами закрываются при создании.

Логика в шаблонах — вопрос холиварный, понятное дело) Но мне лично никогда сложной логики в шаблонах не требовалось, а когда требовалось, то выходило, что это вовсе и не логика отображения информации, и ее в шаблон пихать неправильно.
а зачем в данном конкретном примере шаблон? И css? with-конструкции дают возможность писать простой и очень читабельный, чистый код. Никто не призывает верстать с их помощью мегапорталы, хоть это и возможно :)
Видел стенд ребят, что создали этот фреймворк на PyCon. Спасибо за пример… HTML в Python-коде можно писать много где, например, в Nevow. Но я никогда этого не понимал. В современном вебе страница в любом случае имеет дизайн, верстальщик делает шаблоны… Разве что быстро что-то «накидать» и никому никогда не показывать.
html там не главное, я применил этот метод просто для упрощения примера. Это всего лишь одна из побочных, но красивых фич, как и трансляция питона в javascript, например, которая там также присутствует. Если ее оторвать, фреймворк потеряет немного, но эта вещь из тех, что лучше иметь, чем не иметь.
Да, надо будет попробовать его как-нибудь, если подвернется подходящая задача.
В примере не увидел никаких континуаций. Функция Test1.render() рендерит одну страничку, на получение значения из формы вешается банальный колбэк. Когда форму пришлют — свистнем. Примерно также делается во многих фреймворках. Надо чтобы что-то типа

print 'Введите первое значение'
v1 = input()
print 'Введите второе значение'
v2 = input()
print 'Сумма', v1+v2

в вебе выполнялось. Т.е. я понимаю, что видимо это в фреймворке есть, но пример, по-моему, неудачный. Насчет красоты такого употребления with — спорно, в свое время (правда тогда оператора with не было) было подобное в Twisted.web под названием stan, но по-моему умерло — всем когда-нибудь приходит понимание, что нельзя дизайн в код писать.
Такой стиль характерен для CLI, функция render() — для GUI. Поскольку web-приложение это однозначно GUI, то там однозначно стоит использовать render().

Что касается континуаций. Я слегка сократил код, использовав lambda-функции для заполнения полей Test1.name и Test1.text. При наступлении события вызываются методы action() для всех полей формы, выполняются лямбды, которые сохраняют данные в переменных, после чего вызывается action() для submit-а и данные кладутся в базу. По сути, да, тут континуации не нужны. Но с тем же успехом я мог бы класть данные не в базу а дописывать их в массив. Правда, тогда сообщения были бы видны только добавившему их пользователю, что для гостевой книги несколько странно :)

Вот как следовало бы написать код в этом случае:


class Test1(object):
  def __init__(self):
    self.name=var.Var("")
    self.text=var.Var("")
    self.messages=[]

  def add_rec(self):
    self.messages.append([self.name,self.text])

@presentation.render_for(Test1)
def render(self, h, *args):
...............................................

# Вывод ранее введенных сообщений:
  with h.table:
    for r in self.messages:
      with h.tr:
        with h.td(valign="top", align="right"):
          h<<h.b(r[0])<<":"
        with h.td:
          h<<r[1]

.................................................

Упс, «self.messages.append([self.name,self.text])» надо заменить на «self.messages.append([self.name(),self.text()])»
В принципе, да, колбэки — это тоже континуации. Но тогда нет обещанной революционности. Интересным было бы такое (http://cocoon.apache.org/2.1/userdocs/flow/continuations.html у меня теги не работают). Ни одного колбэка. И это уже сейчас реализуется в рамках одного процесса в питоне (даже без stackless-а) с помощью yield.
в которой будет наботать Nagare
поправьте пожалуйста, присоединяюсь к выше высказавшимся участникам обсуждения, хотелось бы что-то типа таблички возможностей, которые дают право жить этому фреймворку
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории