Comments 42
стандартный для фреймворка функционал
Нуйня этот ваш нагар
Нуйня этот ваш нагар
я не ставил себе целью сразу писать целую книгу про Nagare. Все будет! Функционал там отнюдь не стандартный, просто это пока не очень заметно :)
Вы бы написали основные преимущества и отличия от остальных подобных фреймворков.
Такую гостевую книгу можно на чём угодно написать. Ещё неизвестно, где удобнее.
Такую гостевую книгу можно на чём угодно написать. Ещё неизвестно, где удобнее.
Интересно почитать примеры, где Nagare использует возможности Stackless. Если я правильно понимаю, то на нем можно эффективно реализовывать системы с большим кол-вом коммуникаций между потоками. Например, хотя бы стандартный чат, где все общаются со всеми.
Стандартный возможности веб-фреймворка думаю мало интересны. Для этого лучше использовать Джанго.
Жду продолжения :)
Стандартный возможности веб-фреймворка думаю мало интересны. Для этого лучше использовать Джанго.
Жду продолжения :)
основная возможность stackless, используемая в Nagare — это сохранение continuations между запросами, так что приложение можно писать «линейно», аналогично десктопному. Но и взаимодействие между потоками можно устроить. Например, при помощи глобальных переменных :)
Да, вот про это интересно почитать будет! :)
да, собственно, технология настолько проста, что почти невидима :)
В приведенном примере
@presentation.render_for(Test1)
def render(self, h, *args):
— так задается функция, аналогичная функции перерисовки в десктопных приложениях. Все глобальные переменные и методы объекта Test1 сохраняются при перезагрузках, можно хранить в них, например, статус авторизованности пользователя. Глобальные переменные еще и общие для всех потоков.
В приведенном примере
@presentation.render_for(Test1)
def render(self, h, *args):
— так задается функция, аналогичная функции перерисовки в десктопных приложениях. Все глобальные переменные и методы объекта Test1 сохраняются при перезагрузках, можно хранить в них, например, статус авторизованности пользователя. Глобальные переменные еще и общие для всех потоков.
> Но и взаимодействие между потоками можно устроить. Например, при помощи глобальных переменных
Это как? Расскажите, очень интресно.
Это как? Расскажите, очень интресно.
да банально. На каждую сессию создается экземпляр класса (в данном случае Test1), «локальные переменные» — это поля объектов. Можно задать переменные прямо в модуле, они будут общими для всех объектов.
Race condition? Если его будут менять в несколько потоков, то этот объект очень часто будет в неадекватном состоянии.
вроде в питоне это как-то решается, типа гигантского лока что-то есть. Но, конечно, это самый примитивный метод, ничто не мешает использовать всякие продвинутые способы типа IP с семафорами и т.п., правда, это не будет работать на кластере, наверное.
В том-то и проблема, что гагантский лок убьет всю параллельность — т.к. каждая нить будет упираться в нее и ждать другую. Семафоры это тоже самое, только сделанное Вашими руками. В многопоточных системах глобальные данные это полный ахтунг. Особенно когда начнется неконтролируемое изменение и это повлечет фантомные баги.
Мне интересно есть ли в Нагаре какие-то средства обмена данными между потоками, или придется все в лоб решать?
Мне интересно есть ли в Нагаре какие-то средства обмена данными между потоками, или придется все в лоб решать?
все зависит от частоты транзакций и их сложности. Думаю, для абсолютного большинства приложений ситуация взаимной блокировки будет большой редкостью.
Вообще-то я пока не разбирался с этой частью функционала. На сайте разработчиков есть пример чата, реализованного по технологии Comet, там, кажется, должно быть именно то, что нужно — взаимодействие между различными сессиями.
Вообще-то я пока не разбирался с этой частью функционала. На сайте разработчиков есть пример чата, реализованного по технологии Comet, там, кажется, должно быть именно то, что нужно — взаимодействие между различными сессиями.
Nagare довольно спорное творение — вам часто требовались продолжения? Конечно возможности stackless сериализовать тасклет вызывает некоторый зуд в руках, но нам бы пример не для хомячков — пример, где реально нужны эти самые продолжения.
У меня вот не рождается мысли, где бы это применить.
У меня вот не рождается мысли, где бы это применить.
да практически в любом приложении с нетривиальной логикой или таком, где нужно работать с большим количеством вводимых пользователем данных. Например, вместо того, чтобы делать одну огромную форму, можно очень легко сделать «визард» с кнопками «вперед» и «назад», практически ничего не меняя, поскольку значения с предыдущих шагов будут спокойно лежать в переменных.
Это легко делается без продолжений.
но с продолжениями это делается естественно, а все остальные решения похожи на костыль :)
Не вижу ничего костыльного в сессиях — это их прямое предназначение. А вот сериализация целого тасклета пахнет накладными расходами.
В общем неоднозначен Nagare.
В общем неоднозначен Nagare.
сессии самый что ни на есть костыль для stateless HTTP.
У нас с вами разные понятия о костылях — хранение парочки переменных от запроса до запроса это явно меньший оверхед, чем хранение от запроса до запроса всего тасклета. И в чем принципиальная разница между эти двумя техниками, я не особо улавливаю.
Ну и главное — не вижу ничего ужасного в stateless природе HTTP, это имеет свои преимущества.
Ну и главное — не вижу ничего ужасного в stateless природе HTTP, это имеет свои преимущества.
Хорошо, можете сказать, зачем нужны сессии, кроме как для обхода этого ограничения? В чем может быть преимущество отсутствия возможности? Если какая-либо возможность есть, ей можно либо пользоваться, либо нет. Хочешь, чистишь память после выполнения запроса, не хочешь — не чистишь.
з.ы. еще и в карму плюнуть не забыл, ну-ну…
з.ы. еще и в карму плюнуть не забыл, ну-ну…
Nagare где хранит сериализованные тасклеты?
какая-то жуть — шаблоны через with) Это что, рекомендованный способ там?
это не шаблоны :) Шаблоны там тоже есть, но смысл из примененять в простой программе? Конструкции с with — просто очень красивый способ автоматического закрытия тэгов. Кстати, при использовании шаблонов ничто не мешает вставлять в них куски кода, сгенерированного таким образом, что позволяет, иногда, сильно упростить сами шаблоны.
В том-то и дело, что это не шаблоны)
По-моему так и в этом простом примере html-код было бы писать быстрее, проще, короче, понятнее, а with — ужас!
> with h.td(valign=«top», align=«right»)
тут мало того что в код на python имеем вкрапления html, так этот html еще и используется не только как разметка, но еще и как представление — все эти align=right делаются в css. Напомнило вывод html в php через echo, только с микро-бонусом закрывающихся тегов.
Понятно, что этим синтаксисом можно не пользоваться, но зачем вообще такую возможность давать — непонятно, это ж прям сборник вредных советов Г. Остера)
Чтоб теги сами закрывались, лучше уж что-нибудь вроде haml использовать. Но вообще проблемы не вижу, кстати, с закрытием тегов — они в IDE и так сами закрываются при создании.
Логика в шаблонах — вопрос холиварный, понятное дело) Но мне лично никогда сложной логики в шаблонах не требовалось, а когда требовалось, то выходило, что это вовсе и не логика отображения информации, и ее в шаблон пихать неправильно.
По-моему так и в этом простом примере html-код было бы писать быстрее, проще, короче, понятнее, а with — ужас!
> with h.td(valign=«top», align=«right»)
тут мало того что в код на python имеем вкрапления html, так этот html еще и используется не только как разметка, но еще и как представление — все эти align=right делаются в css. Напомнило вывод html в php через echo, только с микро-бонусом закрывающихся тегов.
Понятно, что этим синтаксисом можно не пользоваться, но зачем вообще такую возможность давать — непонятно, это ж прям сборник вредных советов Г. Остера)
Чтоб теги сами закрывались, лучше уж что-нибудь вроде haml использовать. Но вообще проблемы не вижу, кстати, с закрытием тегов — они в IDE и так сами закрываются при создании.
Логика в шаблонах — вопрос холиварный, понятное дело) Но мне лично никогда сложной логики в шаблонах не требовалось, а когда требовалось, то выходило, что это вовсе и не логика отображения информации, и ее в шаблон пихать неправильно.
Видел стенд ребят, что создали этот фреймворк на PyCon. Спасибо за пример… HTML в Python-коде можно писать много где, например, в Nevow. Но я никогда этого не понимал. В современном вебе страница в любом случае имеет дизайн, верстальщик делает шаблоны… Разве что быстро что-то «накидать» и никому никогда не показывать.
html там не главное, я применил этот метод просто для упрощения примера. Это всего лишь одна из побочных, но красивых фич, как и трансляция питона в javascript, например, которая там также присутствует. Если ее оторвать, фреймворк потеряет немного, но эта вещь из тех, что лучше иметь, чем не иметь.
В примере не увидел никаких континуаций. Функция Test1.render() рендерит одну страничку, на получение значения из формы вешается банальный колбэк. Когда форму пришлют — свистнем. Примерно также делается во многих фреймворках. Надо чтобы что-то типа
print 'Введите первое значение'
v1 = input()
print 'Введите второе значение'
v2 = input()
print 'Сумма', v1+v2
в вебе выполнялось. Т.е. я понимаю, что видимо это в фреймворке есть, но пример, по-моему, неудачный. Насчет красоты такого употребления with — спорно, в свое время (правда тогда оператора with не было) было подобное в Twisted.web под названием stan, но по-моему умерло — всем когда-нибудь приходит понимание, что нельзя дизайн в код писать.
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-а и данные кладутся в базу. По сути, да, тут континуации не нужны. Но с тем же успехом я мог бы класть данные не в базу а дописывать их в массив. Правда, тогда сообщения были бы видны только добавившему их пользователю, что для гостевой книги несколько странно :)
Вот как следовало бы написать код в этом случае:
Что касается континуаций. Я слегка сократил код, использовав 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
поправьте пожалуйста, присоединяюсь к выше высказавшимся участникам обсуждения, хотелось бы что-то типа таблички возможностей, которые дают право жить этому фреймворку
поправьте пожалуйста, присоединяюсь к выше высказавшимся участникам обсуждения, хотелось бы что-то типа таблички возможностей, которые дают право жить этому фреймворку
Sign up to leave a comment.
Nagare — пример использования фреймворка