Магазин с доставкой

Разговоры на любые темы: вы можете обсудить здесь какой-либо сайт, найти единомышленников или просто пообщаться...
Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Магазин с доставкой

Сообщение Debugger » 02.10.2013 (Ср) 21:47

Давно не писал тут и не создавал темы, но, похоже, настал момент :)

Мне сверху спустили задачу - сделать некий сервис. Задача - строго секретная, и до момента полной реализации никто не должен узнать, в чем заключается идея. Поэтому тут подберу аналогию - пускай надо сделать интернет-магазин с несколькими складами.

Пользовательские "концы" сервиса:
  • Клиентская часть сайта, где человек может заказать себе товар
  • Сервисная мобильная (особенность проекта) часть сайта, где водители и заведующие складом могут отмечать данные о поступлении и перемещении товаров
  • (особенность проекта)Некий софт, который будет поставлен у заведующих складом и позволит им также заносить данные в БД
Соответственно, должен быть сервер, который будет хранить данные и выдавать веб-странички/данные для программы.
Есть большой соблазн написать скрипты на сервер, которые будут принимать запросы и выдавать XML-ки. Их будут использовать пользовательские скрипты сайта и софт на компьютере. Получается, весь сайт, в том числе и мобильная часть, будет построена на AJAX.
Первый вопрос: насколько это адекватно/неадекватно/какие есть альтернативы?

Сервис подразумевает не только хранение данных с формочек, но также и сложную бизнес-логику, в случае этого магазина - координацию логистики. В варианте, до которого я дошел, вся эта логика будет представлена в виде этих самых PHP-скриптов, которые при получении данных будут менять содержимое БД и тем самым всё координировать. Второй вопрос - насколько адекватно это решение и где кроется вся бизнес-логика в серьезных сервисах (спрятана в какой-нибудь 1С?)?

Мои коллеги настаивают на использовании какой-либо CMS. Третий вопрос: надо ли оно, если да - надо ли пытаться адаптировать готовую, или делать самопальную?

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 02.10.2013 (Ср) 22:59

Единственное, что не понравилось - это php... Правда я на нём не писал никогда, но отношусь с подозрением.

Поместить всю логику в веб-сервис - абсолютно естественно, ей там самое место. А вот по поводу xml стоит подумать, для веба естественнее json, но надо просто выбрать то что удобнее, особенно в случае наличия декстопных приложений - они же используют тот же сервис.

Если все действия доступны через сервис, то надо сразу продумывать защиту от несанкционированного доступа к данным. А раз это требуется в любом случае, то возникает вопрос, а нужно ли вообще десктопное приложение - возможно стоит всё сделать через сайт?

По поводу CMS. Не вижу в ней смысла, если всё будет работать через сервисы. А вот применить какой-нибудь джаваскиптовый фреймвёрк было бы хорошо. Из наиболее известных AngularJS, KnockoutJS, ExtJS. Я работал с Ангуляром - мне понравился.

PS: Погугли rich internet application и single page application.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Магазин с доставкой

Сообщение Debugger » 04.10.2013 (Пт) 18:12

Я и сам склоняюсь в сторону Python. Хотя бы потому что количество криворучек, пишущих на Python куда меньше, чем на PHP. Если сервис будет существовать в том виде, в котором я его описал - то Питон хорошо сюда ляжет.
Десктопная программа обязательна. Причем она должно уметь долго работать без доступа к интернету.
Насчет безопасности уже подумал. С одной стороны, путем разделения источника данных и приложения, которое с ним работает (сайт или программа) посторонний может легко понять, откуда берутся данные, и начать лапать ручками сервер с данными. Вплоть до того, что он может отследить запросы и написать альтернативное приложение. С другой стороны, отловить возможные дырки в безопасности в трех-четырех скриптах, которые принимают в себя какие-то значения и что-то выплевывают в ответ - не так уж и сложно.
Изначально в качестве интерфейса использовался JSON, но из-за десктопного приложения выбор поменялся в сторону XML.
Спасибо за совет, в общем :)
P.S. Чего-то VBStreets падает.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Магазин с доставкой

Сообщение Хакер » 04.10.2013 (Пт) 18:29

Debugger писал(а):Хотя бы потому что количество криворучек, пишущих на Python куда меньше, чем на PHP.

Ну и аргументация, офигеть...
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Магазин с доставкой

Сообщение Debugger » 04.10.2013 (Пт) 20:10

Хакер писал(а):Debugger писал(а):
Хотя бы потому что количество криворучек, пишущих на Python куда меньше, чем на PHP.

Ну и аргументация, офигеть...

Ура, ты обратил внимание на этот тред :)
Расскажи, что делать?

По поводу PHP: он преподается в почти всех технических вузов, и студент/выпускник искренне считает, что владеет им в совершенстве, хотя это далеко не всегда так. Следствие - при размещении вакансии на PHP большинство откликнувшихся - учащиеся.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Магазин с доставкой

Сообщение Хакер » 05.10.2013 (Сб) 2:10

Я просто не понимаю твоей логики. Слишком много расплодилось идиотов, которые знают PHP — значит нужно отказаться от использования языка в пользу Python-а? Ну так почему бы просто не указать в списке требования и PHP, и Python? Или не Python, а что-нибудь ещё такое, чтобы отсеять нежелательный контингент.

Причём я даже не воюю за использование PHP, я воюю против странной логики.

Вот я уже долго работаю в проекте. Проекту чуть больше года. И как раз Single Page Application.

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

За время работы разочаровался в MySQL. Что касается PHP, то есть два основных раздражающих фактора:
  • Я люблю PHP, но я не люблю языки без строгой типизации. Вот эта моя картинка
    Изображение
    хорошо показывает, о каких вещах я говорю. И не надо говорить про E_STRICT, я прекрасно знаю про него, но есть ещё куча подобных моментов. Я придерживаюсь идеологии, которая гласит, что «я тупая и ненадёжная туша, сделанная из мяса, которая постоянно склонна делать тупые ошибки, а бездушный неумный, но не страдающий от невнимательности компилятор должен постоянно меня контролировать».

  • Второй момент в том, что изначально я написал большущую штуку X, а второй программист должен был написать Y, использующий мой X. Я мог написать большущую штуку X на чём угодно, но мне пришлось писать её на PHP, потому что второй программист знает и пишет только на PHP. Я написал её на PHP. Но как-только второй программист начал делать Y, стало ясно, что у него не хватает мозгов адекватно работать с X. Поэтому было решено, что Y напишу тоже я. Причём тот второй программист не мог нормально реализовать 1/20 той части работы, которую должна была делать Y. Подумав, как сделать это не просто так, чтобы работало, а ещё и так, чтобы это работало невероятно быстро и вообще настолько быстро, насколько это возможно, я понял, что Y надо делать в виде Unix-демона.

    Есть люди, уверяющие, что писать демон на PHP — это очень страшно и вообще не будет работать. Дескать, PHP дико течёт и ни разу не рассчитан на демонизированную работу, а ему оставлена только участь работы короткоживущих скриптов, которые порождаются, загружают кучу кода, кучу классов и функций, достают кучу данных их БД, кучу всего генерируют и умирают сразу же (модель работы, которую я не переношу по понятным причинам).

    Так вот, мне пришлось написать Y в виде демона на PHP.
    — Почему пришлось?
    — Потому что Y основан на X. Он базируется на X, надстраивается над ним, использует API, предоставляемые X. Ну а X уже написан на PHP.
    Надо сказать, что это было проблематичным. Но совершенно не по причинам, описанным в вышеуказанной статье. Демон работает уже месяцами, и знаете, что-то я не вижу, чтобы он тёк и падал от достижения критического объёма используемой памяти. Что я делаю не так? Причём он работает на базе PHP 5.2, а той статье все пишут «в PHP 5.3 стало хоть чуть-чуть лучше, потому что улучшили сборщик мусора».

    Да, он жрёт дико много памяти, но он начинает жрать её сразу после старта, и расход не растёт с течением времени, а колеблется на одном и том же уровне. Он жрёт дико много, потому что... ох, я уже кажется писал, что в PHP массив из 4 значений (просто true) в PHP отжирает 700 байтов. Это кстати важный момент. Память ядром PHP используется самым нелепым и неэффективным образом. На 64-битных системах ситуация в 1.5-раза хуже. Это важный камень, каждый раз, когда я вспоминаю и думаю об этом, я сижу с мыслью: «блин, может быть хватит использовать это

    Ну так вот, я немного отклонился от темы. Помимо того, что он дико жрёт и окружён антуражем «не пишите на нём демонов, иначе пожалеете» (хотя в моих руках он не тёк), были и другие проблемы. Писать X на PHP было не лучшей идеей, но пришлось писать X на PHP, чтобы Х-ом потом мог пользоваться разработчик Y-ка. Но мне потом самому пришлось писать Y на PHP, а писать и X, и Y на PHP — это уж была точно не самая лучшая идея. Во-первых, я потратил кучу времени на отладку ошибок, которые появлялись из-за отсутствия строгого контроля. Опечатался за секунду в имени свойства — и потратил кучу времени на отлов.

    Во-вторых, мне повезло нарваться на кучу багов в PHP (из последних, которые помню: #39992 и #58863).

    В третьих мне пришлось застрять на PHP 5.2, потому что в версии 5.3 глупые разработчики убили одну фишку языка. Есть в PHP аналог VB-шного ByVal/ByRef. На самом деле, устроен PHP так, что по сути там всегда ByRef. Любые значения в PHP, если говорить с позиции С/С++, представлены структурой ZVAL. Строки, числа, булевы значения, ссылки на объекты — всё это ZVAL-ы. Так вот при вызове функций всегда передаётся указать на ZVAL. Но при вызове функции может быть передан указатель либо на оригинальный ZVAL (тогда это будет соответствовать VB-шному ByRef-у, называясь передачей «по ссылке»), либо на копию оригинального ZVAL-а (будет соответствовать VB-шному ByVal-у, называясь передачей «по значению»). С точки зрения PHP, выбор между тем, будет ли передача по значению или по ссылке, осуществлялся с помощью символа &. Причём выбрать это можно было как при объявлении функции (её аргументов), так и непосредственно в момент вызова функции. Что не удивительно, ибо изнутри вопрос стоит только в одном: передать указатель на ZVAL и сделать копию и передать указатель на копию. Вопрос только в том: делать или не делать копию. Долгое время было так, но в один прекрасный момент разработчики PHP решили запретить выбирать между ByVal/ByRef во время вызова функции, заставив явно совершать этот выбор в момент объявления. Сделано это было, естественно, не по техническим причинам, а исключительно в угоду того, чтобы сделать язык более строгим (нашли где делать...).
    При этом в PHP было другие две фишки: функции с переменным числом аргументов и магические методы __call, __get, __set, которые позволяли сделать некий аналог dispatchable-интерфейсов (грубо говоря — нечто похожее на IDispatch), когда обращения к свойствам и методам стекаются к неким обработчикам, которые решают, что делать.

    Естественно, что глупейшим решением убить возможность настоять на ByRef-передачи в момент вызова функци/метода, разработчики убили возможность передавать что-то by ref при вызове функций с переменным числом аргументов или методов классов, которые реализованы через __call хендлер. Можете почитать мой давний топик на sources.ru.

    У меня была куча наработок, которые полагались на все эти три вещи (так или иначе, обычно по две в каждом конкретном случае). Например... кстати, о да! В PHP нет такого механизма событий, как в COM и в VB в частности. Механизма, эксплуатирующего паттерны observer и publisher-subscriber, позволяющего множественную подписку одних объектов на события других. Так вот я его сделал, и давно использовал во многих проектах, и вот я упёрся в PHP 5.3, где вдруг он не работает. Он позволял делать все вещи, какие можно делать с событием в COM/VB, плюс даже больше: обработчиком события может быть просто функция (не мембер какого-то объекта какого-то класса), плюс штатной вещью стал объект-посредник EventMultiplexer (помните эти бесконечные вопросы на форуме в стиле «как обрабатывать события массива объекта / коллекции объектов» или «как объявить WithEvents-массив» — вот, это как раз к этому делу).

    И наконец, мои любимые дырявые абстракции, о которых писал Джоель. Прекрасный пример. Мой PHP-демон должен был был многопоточным. В PHP нет многопоточности. (На самом деле — не правда. Ситуация с многопоточностью в PHP напоминает ситуацию с нею в VB. Сама по себе многопоточность поддерживается (см. TSRM), но преднамеренно не дали способа создавать новый поток. Не дали хотя бы потому, что сам PHP потокобезопасен, но куча экстеншонов к нему — нет.) Что делать? Хорошо, если нельзя сделать многопоточным, то будем форкаться каждый раз, когда нам нужен новый поток. pcntl_fork() есть, какая проблема? На самом деле, многопроцессный демон с кучей однопоточным процессов, порождённых форком достаточно выгоден: при форке новый процесс имеет АП (адресное пространство), являющееся точной копией родительского АП, но копирования огромного адресного пространства не происходит: все страницы имеют флаг copy-on-write, поэтому (само собой, не говоря о файл-маппингах), если процесс форкнет себя 100 раз, то потребление памяти не возрастёт стократно. Данные в дочерних процессах начнут копироваться только тогда, когда кто-то потянется модифицировать соответствующие страницы.

    Ну так вот, форкаем мы дочерние процессы с помощью pcntl_fork. Всё просто прекрасно. До некоторых пор. Во-первых, PHP не имеет никаких pre-fork- и post-fork-callback-ов, где можно было бы написать какую-то обработку на соответствующие моменты. Если процесс имел открытый сокет и форкнулся, данные могут придти любому процессу. Вернее обоим. Вернее так: оба могут увидеть, что данные пришли. Любой может достать данные. Если дочерний процесс вдруг сделает это раньше, то родительский обломается и не получит их. Но на самом деле, я опять отхожу от темы. Я хотел не об этом. Я хотел просто сказать, что ресурсы реально делятся между родительским процессом и дочерним.

    И вот если мы в родительском процессе установили соединение с MySQL-сервером, то если мы форкнемся после этого, то дочерний процесс тоже обладает этим connection-ом. Что при этом происходит? Может ли процесс подключиться к MySQL, потом форкнуться 10 раз так, чтобы все 10 дочерних процессов затем могли пользоваться единожды установленным соединением? И да, и нет. На самом деле, происходит нечто интересное. Всё работает в совершенно нештатном режиме, но, тем не менее, чудом не падает.


    Если вы подключились к MySQL и затем форкнулись 10 раз, то есть 11 процессов, у каждого из которых есть connection. Но с точки зрения процесса MySQL есть только одно подключение. MySQL думает, что клиент всего-лишь один. Внутри процесса MySQL есть только один сокет-объект. И действительно, и родитель, и все дети обладают одним и тем же сокетом. Что происходит, если несколько процессов, используя это «общее» соединение, одновременно пытаются совершить некий SQL-запрос? Происходит вот что: в один и тот же сокет высылается 11 запрос-пакетов. С точки зрения MySQL это всё выглядит так, как будто один клиент взял и не дожидаясь ответа послал сразу запрос на выполнение одиннадцати SQL-запросов. MySQL начинает выполнять SQL-запросы по очереди и высылать ответы тоже по очереди. При этом все процессы блокируются, пока не получат соответствующий ответ. То есть если 11 процессов попытаются совершить простой SQL-запрос SELECT SLEEP(1), то самый везучий получит получит ответ через 1 секунду, а самый невезучий будет спать 11 секунд. То есть, да, запросы ото всех процессов, использующих MySQL-соединение, унаследованное от общего предка в результате форка, просто становятся в очередь и выполняются по очереди одним единственным MySQL-потоком (штатно MySQL для каждого подключения имеет свой поток).

    Естественно, это не может устраивать. Это чудом работает, но это неправильно. Хотя бы потому, что если один процесс начнёт транзакцию, то запросы от других процессов совершенно неожиданно для последних попадут в рамки этой фактически чужой транзакции. И могут быть откачен. Плюс все процессы имеют общие сессионные переменные (на всякий случай речь о сессионных переменных MySQL, а не PHP) и общие временные таблицы (temporary tables). И в конце концов это может привести к дедлоку.

    Итак: «подключиться один раз к БД, форкнуться много раз и использовать унаследованное от родителя соединение» — звучит красиво, но на практике не работает. Хотя перспектива была прекрасная: опять же, из-за моей помешанности на принципе лени, я в 99 % случаев использую prepared statements — предподготовленные SQL-запросы, которые единожды парсятся, разбираются, анализируются силами MySQL и для которых MySQL единожды генерирует план выплнения запроса (execution plan) и затем тысячу раз в дальнейшем использует, не делая каждый раз лишний работы, и было бы красиво и привлекательно один раз заготовить prepared statements в процессе-родителя, а потом форкаться, чтобы куча детей использовала ранее прекомпилированные запросы.

    Казалось бы, вывод из этого сделает первоклассник: если вы форкнулись, не используйте старое соединение (доставшееся вам от родителя), а установите своё новое. Вот тут то мы и подходим, к дырявой абстракции.

    Итак, мы форкнулись. Старое соединение есть, им можно пользоваться, «но лучше нельзя» (с). Надо установить новое соединение с БД. Что делать со старым? Закрыть, уничтожить старый объект-соединение (connection). Вот тут то и облом. Деструктор класса PDO, являющегося абстракцией над С-шными API-функциями MySQL, содержит код, отправляющий MySQL команду навроде GOODBYE. MySQL, получив эту команду, сам закрывает соединение и терминирует поток, ассоциированный с соединением. Если вы ещё не поняли, то это означает, то когда ребёнок закрывает доставшееся ему от родителя ненужное соединение к БД, ребёнок не может как-либо закрыть его так, чтобы не испортить жизнь родителю, которому это соединение по прежнему нужно.

    Если посмотреть изнутри, то можно отключиться от БД двумя способами: просто закрыть соединение или закрыть соединение, предварительно попрощавшись. Второй способ выглядит красивее. Именно его засунули в деструктор класса PDO, который мы используем для работы с БД (один экземпляр такого класса отождествляется одно подключение к БД). Это всем казалось хорошим, пока мы не коснулись форкинга. В случае форкинга старое соединение мы должны уничтожать ничего не отправляя в MySQL, которая даже не догадывается, что два разных процесса делят один и тот же сокет между собой. Просто закрыли этот сокет и всё, и MySQL даже не узнает, что в течение какого-то времени одним логическим соединением владело два процесса. Но нет. Вся работа с соединениями инкапсулирована в абстрацию под названием PDO, и мы никак не можем повлиять на то, что PDO шлёт в сокет перед закрытием.

    Таким образом, если любой из детей, получившихся в результате форка, закрывает доставшееся от родителя соединение, то во всех остальных процессах, в которых это соединение было живым, оно становится недействительным. Причём в каждом случае это выяснится только когда тот или иной процесс попытается совершить какой-то запрос. Он получит ошибку «MySQL server has gone away». Который действительно has gone, ибо ему послали «ну всё, пока, я собираюсь отключиться» и он сам закрыл сокет, через который ранее общался с отключающимся клиентом.

    Это сильно отравляет жизнь, и вы можете сказать: ну хорошо, чтобы не портить родителю жизнь, дети не должны закрывать соединение, доставшееся им от процесса-родителя.

    Это конечно плохо, потому что в памяти процессов-детей накапливается ненужный мусор: ненужные объекты, которые не мешало бы уничтожить; но хотя бы так...

    Не тут то было! Всё ещё хуже!

    Дело в том, что в PHP при завершении скрипта, если какие-то объекты были живы на момент завершения, то их дескрипторы вызываются. Это значит, что дескриптор класса PDO всё равно рано или поздно выполниться и закроет соединение, которым должен полноправно пользоваться процесс-родитель.

    Для нас это означает: если процесс-ребёнок завершился раньше процесса-родителя (не важно: штатно ли или в резульате ошибки/исключения), то соединение с БД, которым владеет родитель, будет испорчено.

    То есть мы не только должны после форка сохранять родительский connection object, но и когда нам (дочернему процессы) больше нечего делать, мы не имеем права завершаться, мы должны дождаться, когда умрёт наш родитель, и только после этого мы тоже можем умереть, иначе мы испортим родителю жизнь. Дикость! Понятное дело, что в случае демона в идеальном случае родительский процесс не завершается вообще никогда. Это значит, что процессы-дочки, порождённые для выполнения какой-то асинхронной работы, обязаны жить вечно. Не годится.

    Но даже если бы сделали так: смерть любого из, скажем, двадцати дочерних процессов, которым досталось от родителя соединение, приводит к тому, что соединение становится порванным в родительском процесс. То есть какой-то крах child-процесса убивает parent-process.

    Итак, PDO — хорошая штука. pcntl_fork — хорошая штука.
    Но PDO и pcntl_fork несовместимы между собой. Они не уживаются в одной программе.

    Есть бесполезный и безобидный код:
    Код: Выделить всё
    $x = pcntl_fork();
    if(
    $x == 0)
    {
        echo "I am child process and I am going to die...\n";
        exit;
    }

    Он не делает в принципе ничего: он форком порождает копию текущего процесса, которая тут же умирает. Но если вставить это в скрипт, где у вас было одно или несколько открытых соединений с БД, то после выполнения этого фрагмента можете попрощаться со всеми соединениями — они все станут недействительными.

    У меня, по сути, было три варианта:
    • Отказаться от использования pcntl_fork, а просто, когда нам нужен дополнительный поток, порождать полностью новый процесс с нуля.
      Минусов много: необходимость переписывать много кода, в первую очередь, IPC между родителем и детьми (в случае fork-а использовалась специально ради этого сценария созданная socket_create_pair, перерасход памяти (вся кодовая база компилируется в байт-код каждый раз, если только не заюзать какой-нибудь акселератор, кеширующий байт-код), при котором больше нет copy-on-write-подхода для страниц памяти и весьма коварный пункт — возможность того, что код демона обновят, забыв его выключить, в случае чего родитель будет иметь старый код, а дети будут иметь уже новый код, что может привести к непредсказуемым результатам.
    • Отказаться от PDO (которая является универсальной основанной на драйверах абстракционным слоем для работы с разными СУБД, примерно как ADO) в пользу ООП-вариации MySQLi, либо процедурной вариации MySQLi, либо (боже упаси) процедурной вариации MySQL без постфикса «i». Но это ещё не факт, что оные в своих реализациях десктрутора класса Connection или в реализации своих mysql_close/mysqli_close не имеют такого же «плохого» кода, который есть в деструкторе PDO, а именно — отправки сообщения «goodbye».
    • Каждый раз, когда нам нужен новый дочерний процесс — полностью переподключаться к БД и в родительском процессе и в дочернем. То есть форкнулись, и в обоих процессах закрываем оригинальное соединение и взамен его в обоих процессах устанавливаем новое.

    Я выбрал третье, потому что в этом случае мне пришлось меньше всего переписывать (фактически только дописать код переподключения и код, который бы заново перепредподготовливал (sic!) теряемые при переподключении prepared statements). Это имело ключевую роль, потому что он требовал меньше всего времени на переписывании и позволял не отставать от графика (хе-хе). Но стратегические потери велики:
    • Мой код не использовал сессионные переменные MySQL, но у меня было в планах их использовать, теперь же я отрезал себе эту возможность: каждый раз, когда мы порождаем новый поток (а на самом деле новый процесс через форк), мы переподключаемся к БД в родителе, а значит сессионные переменные родителя теряются.
    • Нельзя порорждать новый процесс, когда мы находимся в транзакции. Транзакции можно использовать только с осторожностью, пребывая в полной уверенности, что во время транзакции не сработает какой-нибудь таймер, обработчик события которого вызовет что-то, что в конечном итоге породить новый процесс.
    • Нельзя использовать временные таблицы (temporary tables). Или можно, но только в те промежутки времени, когда мы точно будем уверены, что пока мы используем временную таблицу, никто не вызовет fork.
    • Как я уже говорил, идея использования prepared statement сильно страдает, потому что каждый раз, когда нам нужен новый дочерний процесс, приходится переподключаться и затем пересоздавать все prepared statements (в какой-то степени сразу одни и те же запросы — и в родительском процессе и в только что родившемся дочернем).

    Мало того, что я обрезал себе кучу возможностей (или создал подводный камни), так ведь ещё при случае нужно как-то объяснить эти ограничения тому, кто потом придёт поддерживать мой код. А мне совершенно не нравится, когда в моём коде есть какие-то глупые ограничения. То есть я недоволен своим кодом, а это редкий случай и вообще психологически тяжело для меня.

    Вот если бы я писал этот демон на С/С++, я бы мог в контексте дочернего процесса после форкинга просто по-тихому закрыть оставшееся от родителя соединение так, что не нарушил бы жизнь родителю. Всё было бы правильно, без глупых ограничений, и главное, без кучи времени, потраченного на придумывание обходного решения (которое весьма некрасивое) и воплощение его в жизнь. К сожалению, большинству людей если говоришь «я собираюсь написать эту штуку не на PHP, а на Си», то у них становятся круглыми глаза и они говорят: «О боже! Это значит человек будет писать 100 строчек там, где он ограничился бы пятью, решая задачу на высокоуровневом PHP вместо низкоуровневого Си». Увы, но я уверен, что если бы я писал на Си, я бы написал этот демон, потратив существенно меньшее количество времени. И кстати да, я бы и не морочился даже с pcntl_fork и MySQL-соединениями, потому что просто создавал бы новый поток, а не новый процесс.


    Другой пример дырявой абстракции. Или не совсем абстракции. Но опять же из серии «а если бы я писал на С++ и у меня был контроль над более низкоуровневыми вещами...». Мне в PHP не хватает слабых (weak) ссылок. Я не знаю, знаете ли вы, что такое weak-ссылки, и я не знаю, есть ли они в других языках, потому что я сам их выдумал. Попробую объяснить.

    Идея в том, что ссылки на объекты мы разделим на два вида: сильные (strong) и слабые (weak). Слабая от сильной в первую очередь отличается только тем, что не препятствует объекту, на который ссылаются, умереть, когда на него больше не остаётся ни одной нормальной (сильной) ссылки. Во-вторую очередь, есть опциональный приятный момент, который обязательно должен присутствовать там, где weak-ссылки являются частью языка: когда объект, на который ссылается слабая ссылка, уничтожился, потому что на него не осталось ни одной сильной ссылки, слабая ссылка должна автоматически зануляться (иначе куда она продолжает указывать?).

    С низкоуровневой точки зрения, если говорить о парадигмах, где контроль времени жизни объекта реализован за счёт подсчёта ссылок (как, например в COM, PHP и много где ещё), слабая ссылка от сильной отличается тем, что она не участвует в подсчёте ссылок. То есть если говорить о COM, то когда ссылка на объект присваивается слабой ссылочной переменной, не происходит вызова IUnknown::AddRef. Если нам нужен второй момент (автоматическое зануление ссылки при смерти объекта, на который ссылка указывала), то с точки зрения низкого уровня это означает, то каждый объект обязан поддерживать возможность учёта всех слабых ссылок, ссылающихся на него. Когда объект умирает, он должен будет пробежаться по списку всех слабых ссылок, ссылаюзихся на него, и занулить их самостоятельно. То есть, подчёркиваю, если бы мы сейчас только проектировали COM и хотели заложить в него слабые ссылки, мы должны были бы в IUnknown помимо симметричных AddRef и Release добавить ещё два симметричных метода:
    • RegisterWeakRef
    • UnregisterWeakRef
    И по аналогии с тем, как сейчас каждый COM-объект обязан иметь счётчик ссылок, увеличиваемый/уменьшаемый с каждым вызовом AddRef/Release, каждый COM-объект был бы обязан иметь список слабых ссылок, элементы которого добавлялись/удалялись бы методами RegisterWeakRef/UnregisterWeakRef. И перед уничтожении, объект был бы обязан пройтись по списку и занулить все ссылающиеся на него weak-ссылочные-переменные. Опционально, во имя оптимизации можно было бы ещё сделать метод UpdateWeakRef, заменяющий вызов пары Unregister/Register. Вообще, по слабым ссылкам применительно к COM я уже много-много лет хотел написать большую самостоятельную статью, есть многое что сказать, но всё было некогда, а сейчас меня прорвало проболтаться о них.

    Как видите, слабые ссылки оказываются даже более дорогими, чем сильные, потому что вместо счётчика у нас целый список (который может расти и для которого актуальны все проблемы по управлению памяти, связанные с интенсивно меняющими свой размер списками). Но при том, что они дороже, они и чрезвычайно выгодные в тех случаях, когда без них мы рискуем нарваться на проблемы замкнутых ссылок (циркулярных, циклических ссылок).

    Вот сейчас, если говорить и о COM (а значит и VB), и о PHP — вы не можете спокойно сделать двусвязный список из объектов, используя ссылки на объекте для связей между элементами списка. Если у вас первый элемент ссылается на второй, а второй — на первый, то вот и появляются циклические ссылки.

    Другой типичный пример: дерево из объектов. Можно сделать так, что родительские элементы хранят ссылки на все дочерние. А дочерние не хранят ссылки на родителей. Тогда пройтись по дереву можно только от корня к конечному листу. Можно сделать так, что дети хранят ссылку на родителей, а родители ничего не знают о детях. Тогда протрассировать список можно только от конечного узла к корню. Если вам хочется полноценный список, то есть ли у вас дети хранят ссылку на родителя, а родитель на детей — то опять замкнутые ссылки. И если дерево вам больше не нужно и вы загасите все свои ссылки на любые элементы в дереве, то дерево само по себе останется жить в памяти. Это значит, что вы обязаны вручную сделать некий механизм, который разрушает служебные ссылки между элементами дерева, и, не забывая, вручную вызывать этот механизм перед тем, как вы поняли, что вам больше не нужно дерево.

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

    Но мне слабые ссылки потребовались не для деревьев, а для кое-чего другого. Я выше уже упоминал, что в PHP нет механизма событий, подобного тому, что есть в COM (и в VB как следствие). Все подобные механизмы событий основываются следующих двух принципах (и событийный механизм COM и VB не исключение):
    • Подписчики держат ссылку на объект, на который они подписались. Ссылка нужна для того, для чего она нужна программисту, плюс для того, чтобы потом отписаться (при занулении или измении WithEvents-ссылки).
    • Объекты, на которые подписались, хранят ссылки на своих подписчиков. Эти ссылки нужны для того, чтобы при возникновении того или иного события пройтись по списку подписчиков и у каждого вызвать метод-обработчик.

    Получается, источник событий хранит ссылки на подписчиков, подписчики хранят ссылку на источник — вот она и проблема циклических ссылок в событийном механизме. Если источник события никому больше не нужен, и подписчик тоже никому больше не нужен, то оба не умирают, потому что они нужны друг-другу! Эта проблема называется в событийных механизмах называется Lapsed listener problem.

    Но в COM этой проблемы нет. Вот рассмотрим это в VB на примере класса Class1 и формы Form1. У формы Form1 есть событие Click.

    В классе Class1:
    Код: Выделить всё
    Dim WithEvents frm As Form1

    Private Sub frm_Click()
        MsgBox "Кто-то кликнул по окну формы!"
    End Sub


    Если присвоить переменной frm ссылку на экземпляр какой-нибудь формы, то экземпляр класса Class1 подпишется на события этого экземпляра формы. Собственно, экземпляр Class1 будет хранить ссылку на экземпляр формы в переменной frm (и больше нигде, пока что), но и экземпляр формы станет хранить ссылку на своего подписчика изнутри.

    Фишка в том, что вторая ссылка является по факту слабой. Хотя в COM нет такого самостоятельного понятия, но в основанном на IConnectionPoint механизме они используются: источник событий хранит ссылки на всех своих подписчиков, но не увеличивает у них их собственные счётчики ссылок.

    В результате в COM нет Lapsed listener problem: подписка на событие не мешает подписчику умереть, источники событий не держат сильных ссылок, которые мешали бы подписчикам умирать. Вместо этого, подписчики умирают и просто отписываются от источников (уничтожая тем самым слабые ссылки на себя).

    Именно ради этого мне захотелось иметь слабые ссылки в PHP, поскольку я сделал аналогичный COM-овскому механизм событий у себя. Но слабые ссылки в PHP я могу получить только модифицировав самое сердце PHP, что, естественно, неприемлемо. (Тем не менее, у меня есть одна идейка, которая всё-таки позволит мне получить слабые ссылки в PHP, правда я её ещё не проверял).

    Получается, что если какой-нибудь экземпляр CSomething породил внутри себя экземпляр класса Timer и подписался на его событие Tick, то когда мы занулим все ссылки на экземпляр CSomething, он не уничтожится. Они вместе с объектом-таймером продолжат жить друг ради друга до конца времён. Утечка.

    В итоге, с этим геморроем приходится иметь дело вручную: практически все классы, в которых есть withevent-свойства, у меня имеют метод Disengage, который вызывается тогда, когда самому главному потребителю объекта объект становится ненужным. Вызов этого метода как бы говорит объекту: ты должен прекратить всю свою активную деятельность и стать полу-мёртвым. Реализация этого метода практически шаблонная везде: зануление всех WithEvents-ссылок, приводящее к отписке от событий, при которой происходит зануление ссылок на подписчика, без зануление которых оный не может умереть, держась на плаву.

    В итоге, приходится держать в голове все эти подписочные события и не забывать заставлять объекты отписываться от других объектов, когда роль объекта в системе подходит к концу.

    Будь это другим языком, в котором есть механизм событий как в COM, или будь это достаточно низкоуровневым языком, в которых мезанизма нет, но его легко сделать — проблемы бы не было.

Так вот, получается, что половинка X, которая работает на нашем сервере (у X есть половинка, которая работает на чужом сервере) написана на PHP ради Y, который должен был писать другой человека. Но потом пришлось писать Y самому, и опять же на PHP, потому что на нём уже написан X. И архитектура Y была выбрана такой, чтобы с Y можно было бы работать, чтобы с ней работал Z. И вот сейчас речь идёт о том, что Z плох и его перепишет... ну вы поняли кто. И Z должен будет взаимодействовать с демоном Y.

И все эти вещи, знать бы все факторы изначально, я бы не писал на PHP. Да и Y имел бы совершенно другую архитектуру, он был мы интегрирован с Z, а не был бы полностью самостоятельной частью, дико изолированной от Z и вообще напрямую с ним никаких не взаимодействующей.

P.S. Хотел написать текстик на 1 экран, но вышло как обычно. Слишком долго был в read-only-режиме, накопилось :)
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Магазин с доставкой

Сообщение FireFenix » 05.10.2013 (Сб) 4:31

Хакер писал(а):P.S. Хотел написать текстик на 1 экран, но вышло как обычно. Слишком долго был в read-only-режиме, накопилось :)

Как приятно зайти на форум и прочитать интересную и поучительную статью, больше бы таких :oops:



Debugger писал(а):Я и сам склоняюсь в сторону Python.

Я конечно поддерживаю Хакера по выбору языка, но чисто для меня синтаксис Питона отвратителен и я его не перевариваю, поэтому смотрю в сторону php

Debugger писал(а):Хотя бы потому что количество криворучек, пишущих на Python куда меньше, чем на PHP.

Казалось бы, причём тут это, если тебе поставили задание, а не студентам?
Вообще говнокодить ничего не мешает и других языках

Более того, выбор серверного языка это ещё цветочки, а вот танцы-пляски начнутся с кроссбраузерностью/производительностью на мобильниках/JS

Debugger писал(а):Если сервис будет существовать в том виде, в котором я его описал - то Питон хорошо сюда ляжет

По моему разницы вообще нету

Debugger писал(а):Мои коллеги настаивают на использовании какой-либо CMS. Третий вопрос: надо ли оно, если да - надо ли пытаться адаптировать готовую, или делать самопальную?

Моё мнение по этому поводу:
Если ты будешь клепать много "шустрых" проектов, то лучше конечно CMS, ибо повышает скорость разработки.
Если у тебя будут долгосрочные проекты, то лучше написать своё хардкорное со сторонними фремворками
php: composer для пакетов + Laravel/zend/Yii
JS: CoffeeScript/JQuery/KnockoutJS или AngularJS
CSS: scss + compass

Debugger писал(а):а нужно ли вообще десктопное приложение - возможно стоит всё сделать через сайт?

Не вижу смысла в десктопном приложении, если 75% будет сделано в виде сайта/веб-сервера, то почему бы на нём и не сделать клиента или что там? По крайней мере у нас в Приват Банке всё сделано в виде сайта

Debugger писал(а):Изначально в качестве интерфейса использовался JSON, но из-за десктопного приложения выбор поменялся в сторону XML.

Это тоже не совсем понятно, если есть триллион различных библиотек для работы с JSON
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

сэр Афим
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 11
Зарегистрирован: 13.10.2010 (Ср) 21:40

Re: Магазин с доставкой

Сообщение сэр Афим » 05.10.2013 (Сб) 4:54

Честно, больше 1\3 "ниасилил".
Во-первых, если не в курсе - php 5.2 уже давно не поддерживается, более того - 5.3 тоже, советую переходить на 5.4 или даже лучше на текущую 5.5.4 версию, ну это и так очевидно =)))
Во-вторых, все указанные баги в самом начале статьи никто фиксить не будет, т.к. повторюсь - 5.2 давно умер, расширения mysql больше не существует и его никто не поддерживает (ну если только на магии пофиксится)
В-третьих, если 8 метров на 500 клиентов много для CLI веб-сокет сервера (написанного между прочим полностью на PHP, без всяких libevent и форков - пруф: https://packagist.org/packages/cboden/ratchet), то советую для начала попробовать поднять великий и могучий RoR и удивиться, как же так он сжирает пол гига на пустоте, я был, честно, в шоке :D
В-четвёртых, советую не забывать, что null, это не указатель в ничего, а просто ничего, с таким же успехом можно присвоить переменной 0 - разница только в том, что сборщик мусора обращает внимание на null (к слову, для сборки мусора лучше использовать null, вместо unset, он лучше работает)
В-четвёртых, в PHP есть сам COM (+ поддержка .NET), пишите на здоровье, а если не нравится - можно спокойно использовать встроенный SPL класс обсервера, в чём проблемы с ссылками - не понимаю. Если и это не катит - есть такой язык (сейчас в бете, но успешно компилится и не бажит + на нём фалкон версии 2 написан), называется зефир (zephir).
В-пятых, в PHP есть многопоточность: http://php.net/manual/ru/class.thread.php треды, мутексы и воркеры с блекджеком и прочим - в комплекте =)

Дальше не смог. Не, ну я согласен, что отсутствие передачи по ссылке отстой, но это не повод сидеть на языке, где динозавры скоро родятся =)))
Дада, это именно тот я, о котором ты возможно подумал, просто мой ник уже занят(((

сэр Афим
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 11
Зарегистрирован: 13.10.2010 (Ср) 21:40

Re: Магазин с доставкой

Сообщение сэр Афим » 05.10.2013 (Сб) 5:36

FireFenix писал(а):Не вижу смысла в десктопном приложении, если 75% будет сделано в виде сайта/веб-сервера, то почему бы на нём и не сделать клиента или что там? По крайней мере у нас в Приват Банке всё сделано в виде сайта
о, могу пропиарить свою поделку же? https://github.com/SerafimArts/Xphp :D
FireFenix писал(а):Моё мнение по этому поводу:
Если ты будешь клепать много "шустрых" проектов, то лучше конечно CMS, ибо повышает скорость разработки.
Если у тебя будут долгосрочные проекты, то лучше написать своё хардкорное со сторонними фремворками
php: composer для пакетов + Laravel/zend/Yii
JS: CoffeeScript/JQuery/KnockoutJS или AngularJS
CSS: scss + compass

+1
Дополню от себя -
Css: в сторону Less смотреть не советую, слаб как DSL
JS: ещё как вариант можно MVC Ember.js, в качестве альтернативы Coffee (хотя я его безмерно обожаю) - TypeScript, Dart или LiveScript
PHP: Если важна скорость, то Phalcon однозначно, если качество кода, то Symfony 2. Указанные выше димой фреймы - что-то между, но я ратую за Laravel 4 =) Composer однозначно нужен, без него разрабатывать что-то серьёзное - очень сложно. Это как бандлер с гемами в Ruby или NPM в node.js
Дада, это именно тот я, о котором ты возможно подумал, просто мой ник уже занят(((

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Магазин с доставкой

Сообщение Хакер » 05.10.2013 (Сб) 5:46

Я так понял этот набор наспех написанных мыслей адресован мне.

сэр Афим писал(а):Во-первых, если не в курсе - php 5.2 уже давно не поддерживается, более того - 5.3 тоже, советую переходить на 5.4 или даже лучше на текущую 5.5.4 версию, ну это и так очевидно =)))

Поддержка 5.3 заканчивается только летом 2014 года. http://php.net/eol.php

сэр Афим писал(а):Во-вторых, все указанные баги в самом начале статьи никто фиксить не будет, т.к. повторюсь - 5.2 давно умер, расширения mysql больше не существует и его никто не поддерживает (ну если только на магии пофиксится)

Какая связь этих багов с версией 5.2? Они пофикшены в 5.3? Нет. Равно как и нет связи между этими багами и расширением mysql. И я знаю, что оно не поддерживается и не существует. Комментарий в скобках как бы говорит об этом:
Хакер писал(а):либо (боже упаси) процедурной вариации MySQL без постфикса «i»


сэр Афим писал(а):В-третьих, если 8 метров на 500 клиентов много для CLI веб-сокет сервера (написанного между прочим полностью на PHP, без всяких libevent и форков - пруф: https://packagist.org/packages/cboden/ratchet), то советую для начала попробовать поднять великий и могучий RoR и удивиться, как же так он сжирает пол гига на пустоте, я был, честно, в шоке :D

А причём здесь 8 метров на 500 клиентов? И Ruby-on-Rails?

сэр Афим писал(а):-четвёртых, советую не забывать, что null, это не указатель в ничего, а просто ничего, с таким же успехом можно присвоить переменной 0 - разница только в том, что сборщик мусора обращает внимание на null (к слову, для сборки мусора лучше использовать null, вместо unset, он лучше работает)

Не нужно рассказывать мне, что такое null. Если речь про мою картинку, то абсолютная ложь, что с таким же успехом можно присвоить 0. И сборка мусора к той картинки вообще никаким боком не относится. Лучше бы ты почитал, прежде чем писать не относящуюся к теме очевидную информацию.

сэр Афим писал(а):В-четвёртых, в PHP есть сам COM (+ поддержка .NET), пишите на здоровье, а если не нравится - можно спокойно использовать встроенный SPL класс обсервера, в чём проблемы с ссылками - не понимаю. Если и это не катит - есть такой язык (сейчас в бете, но успешно компилится и не бажит + на нём фалкон версии 2 написан), называется зефир (zephir).

В Ауди 100 есть магнитофон. А если не нравится, микроволновка может согреть еду. А если и это не катит — завтра будет концерт Аллы Пугачёвой.

Я знаю, что в PHP есть COM, вернее расширение, дающее очень ограниченную поддержку работы с COM-объектами, падающее, если сделать шаг-влево, шаг-вправо. Я активно использовал это в своё время и работал из PHP с COM-объектами, и даже пытался наоборот. Это расширение существует только для Windows, для *nix его не существует, а мы пишем под nix. Но самая большая загадка: зачем о нём говорится, если я не спрашивался и не жаловался на отсутствие поддержки COM? И почему в альтернативу ему ставится Observer из SPL?

Или предлагается использовать COM вместо сделанного мною механизма событий? Лол, каким образом?

Мне не нужно отлавливать события сторонних COM-объектов. Мне нужна возможность декларировать у одних классов наборы выбрасываемых событий, выбрасывать события, а у других классов — декларировать WithEvents-переменные и указывать обработчики для определённых событий, ассоциированные с соответствующими WithEvents-переменными. И что за встроенный в SPL класс observer-а? В SPL есть только встроенные интерфейсы SplObserver и SplSubject. Причём poorly-designed интерфейсы по сравнению с тем, о чём я говорю.

сэр Афим писал(а):В-пятых, в PHP есть многопоточность: http://php.net/manual/ru/class.thread.php треды, мутексы и воркеры с блекджеком и прочим - в комплекте =)

Во-первых ситуацию с многопоточностью я описал. И я не говорил, что её нет. Во-вторых, это PECL. Хотя признаю, что я об этом расширении не знал.

сэр Афим писал(а):Дальше не смог. Не, ну я согласен, что отсутствие передачи по ссылке отстой, но это не повод сидеть на языке, где динозавры скоро родятся =)))

Это повод, потому что нет идей, как сделать по другому, да и никто не хочет тратить время на переписывание уже работающего кода, который полагается на эти вещи.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

сэр Афим
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 11
Зарегистрирован: 13.10.2010 (Ср) 21:40

Re: Магазин с доставкой

Сообщение сэр Афим » 05.10.2013 (Сб) 6:34

Хакер писал(а):Это повод, потому что нет идей, как сделать по другому, да и никто не хочет тратить время на переписывание уже работающего кода, который полагается на эти вещи.
В этом всегда проблема, иногда стоит потратить рабочий день на знакомство с новыми вещами, вполне возможно они чем помогут. Например в php 5.6 уже утвержден синтаксис распаковки аргументов, выходит он, по плану - через год (аналог func_get_args()), не так уж и много и вполне возможно спасёт от передач по ссылкам (з.ы. вот тут я подробно расписал новые rfc: http://forum.sources.ru/index.php?showtopic=381570)
Дада, это именно тот я, о котором ты возможно подумал, просто мой ник уже занят(((

сэр Афим
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 11
Зарегистрирован: 13.10.2010 (Ср) 21:40

Re: Магазин с доставкой

Сообщение сэр Афим » 05.10.2013 (Сб) 6:43

Это я всё к тому, что в своих задачах - ни разу не сталкивался с багами или неудобствами пыха. Может задачи иные, а может потому, что по вебу больше страдаю, а по VB\C меньше, а у тебя наоборот =)
Дада, это именно тот я, о котором ты возможно подумал, просто мой ник уже занят(((

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 05.10.2013 (Сб) 10:27

Хакер писал(а):P.S. Хотел написать текстик на 1 экран, но вышло как обычно. Слишком долго был в read-only-режиме, накопилось :)

Классно :)
Твои рассуждения всегда интересно почитать :)

FireFenix писал(а):Казалось бы, причём тут это, если тебе поставили задание, а не студентам?

Вероятно при том, что писать это он будет не один ;)

FireFenix писал(а):Если ты будешь клепать много "шустрых" проектов, то лучше конечно CMS, ибо повышает скорость разработки.
Если у тебя будут долгосрочные проекты, то лучше написать своё хардкорное со сторонними фремворками

Чем способна CMS помочь в разраьботке RIA?
А вот js-фреймвёрк стоит использовать в любом случае.
jQuery - это всего лишь кроссбраузерность плюс удобство написания кода, без него вообще мало что делается.
А фреймвёрки типа Ангуляра как раз заточены на создание RIA.

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Магазин с доставкой

Сообщение FireFenix » 05.10.2013 (Сб) 15:52

Qwertiy писал(а):Чем способна CMS помочь в разраьботке RIA?

Тем, что на мобилках нормально не поддерживается и уже давно протухло, т.к. html5 заменяет многие вещи. А если учесть как это дело любит крашиться или виснуть, то вообще удаляй.
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Магазин с доставкой

Сообщение Debugger » 05.10.2013 (Сб) 23:05

Долго медитировал над статьей :) Как и всегда, на высоте.
Дело в том, что в PHP при завершении скрипта, если какие-то объекты были живы на момент завершения, то их дескрипторы вызываются.

Деструкторы, то есть?

Раз хочешь более внятной аргументации: объясню свой выбор.
Во-первых, как уже можно было догадаться, уже приходилось искать PHP-программиста. И тут была ситуация, схожая с возникшей у Хакера.
Во-вторых, я опирался на рейтинг языков. PHP теряет позиции, Python - набирает. У большинства известных мне стартующих проектов серверная часть сделана на нём.
Есть ещё набор внешних причин а-ля "человек, который стоит выше меня, говорит, что PHP - плохо".
Вот такие дела.

сэр Афим писал(а):FireFenix писал(а):
Моё мнение по этому поводу:
Если ты будешь клепать много "шустрых" проектов, то лучше конечно CMS, ибо повышает скорость разработки.
Если у тебя будут долгосрочные проекты, то лучше написать своё хардкорное со сторонними фремворками
php: composer для пакетов + Laravel/zend/Yii
JS: CoffeeScript/JQuery/KnockoutJS или AngularJS
CSS: scss + compass

+1
Дополню от себя -
Css: в сторону Less смотреть не советую, слаб как DSL
JS: ещё как вариант можно MVC Ember.js, в качестве альтернативы Coffee (хотя я его безмерно обожаю) - TypeScript, Dart или LiveScript
PHP: Если важна скорость, то Phalcon однозначно, если качество кода, то Symfony 2. Указанные выше димой фреймы - что-то между, но я ратую за Laravel 4 =) Composer однозначно нужен, без него разрабатывать что-то серьёзное - очень сложно. Это как бандлер с гемами в Ruby или NPM в node.js

Спасибо, гляну.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 05.10.2013 (Сб) 23:16

FireFenix писал(а):Тем, что на мобилках нормально не поддерживается и уже давно протухло, т.к. html5 заменяет многие вещи. А если учесть как это дело любит крашиться или виснуть, то вообще удаляй.

Ничего не понял.
0. CMS - это нечто на сервере, что может предоставлять шаблоны и всякие плюшки для серверной генерации контента. Чем она может помочь в разработке сайта, в котором всё делается на клиенте при помощи джаваскрипта?
1. Что не поддерживается на мобилах и давно протухло? У html5 как раз наоборот там наиболее хорошая поддержка.
2. Что любит крашиться и виснуть? Точно не html5.

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Магазин с доставкой

Сообщение FireFenix » 06.10.2013 (Вс) 2:16

Qwertiy писал(а):2. Что любит крашиться и виснуть? Точно не html5.

Что такое RIA? RIA это сервелат, флеш и аплеты и ещё какая-нить чушь. Вот оно то и протухло

Qwertiy писал(а):0. CMS - это нечто на сервере, что может предоставлять шаблоны и всякие плюшки для серверной генерации контента.

CMS имеет продуманную уже архитектуру для создание своих страниц, а не выдумывание различных велосипедов, для генерации/заполнения/отдачи шаблонов и собсно регистрации

Qwertiy писал(а):Чем она может помочь в разработке сайта, в котором всё делается на клиенте при помощи джаваскрипта?

Что всё?
На одном JS всё не сделаешь. Более того разработчиков JS нужно казнить.

По мимо самой бизнес-логики, на сервере должна быть регистрация. По мимо регистрации ещё должен быть маршрутизатор редиректа к модулю/программе, шаблонизатор, кешер, логгер и ещё кучу всего...
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

сэр Афим
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 11
Зарегистрирован: 13.10.2010 (Ср) 21:40

Re: Магазин с доставкой

Сообщение сэр Афим » 06.10.2013 (Вс) 2:17

Qwertiy писал(а): Что не поддерживается на мобилах и давно протухло? У html5 как раз наоборот там наиболее хорошая поддержка.
2. Что любит крашиться и виснуть? Точно не html5.

это всё говорит о том, что не приходилось разрабатывать под мобилки =) Если что-то разрабатывается под них html5 использовать ни в коем случае нельзя, особенно: box-shadow, gradient (linear, radial, etc), border-radius, rgba(*), transition, transform, opacity и прочее. Один раз забудешь - и пипец мобилке, тормоза просто неимоверные. Что бы тот же айфон не лагал - приходится по старинке, картинками всё это делать - производительность повышается значительно. Конечно, платформы типа appcelerator и phonegap чуть повышают её, но всё равно в итоге получается лагодром из 2х кадров в секунду. Именно из-за этого сейчас приходится писать проект на канвасах, может побыстрее будет, если же нет, то unity\haxe, других альтернатив нет.
Дада, это именно тот я, о котором ты возможно подумал, просто мой ник уже занят(((

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Магазин с доставкой

Сообщение Хакер » 06.10.2013 (Вс) 2:17

Qwertiy писал(а):jQuery - это всего лишь кроссбраузерность плюс удобство написания кода, без него вообще мало что делается.

Вот я смотрю на то, что написали наши, и понимаю, что либо jQuery — это концентрированное зло, либо они используют его категорически неправильно.

Но то, что я сейчас вижу, это то, что когда им, предположим, нужно создать какой-то DOM-элемент, который потом нужно будет убрать, вместо того, чтобы завести переменную и сохранить в ней ссылку на созданный элемент, они предпочитают не сохранять ссылку, а когда понадобится вновь что-то сделать с этим элементом — они его ищут в DOM-дереве по какому-то признаку. И по-моему возможность поиска — это ключевая фишка этого вашего jQuery.

Вместо того, чтобы завести какую-то переменну-флаг или множество флагов, они предпочитают наделить DOM-элементы каким-нибудь фиктивными (не меняющими отображения) CSS-классами, а потом, когда им нужно найти элементы, помеченные флагами, они опять ищут в DOM-дереве элементы обладающие стилями.

Я просто дурею от того, насколько у них код, определяющий логику перемешан с кодом, определяющим отображение.


И вообще, по-моему глубокому убеждению развитие веба и HTML пошло не туда. Причём у меня была большая надежда на HTML5, что они поверут вектор в правильную сторону, но вместо этого они наоборот возвели в квадрат все те дурацкие моменты, которые были до этого.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

сэр Афим
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 11
Зарегистрирован: 13.10.2010 (Ср) 21:40

Re: Магазин с доставкой

Сообщение сэр Афим » 06.10.2013 (Вс) 2:26

Хакер писал(а):И вообще, по-моему глубокому убеждению развитие веба и HTML пошло не туда. Причём у меня была большая надежда на HTML5, что они поверут вектор в правильную сторону, но вместо этого они наоборот возвели в квадрат все те дурацкие моменты, которые были до этого.
Выше уже было сказано про Knockout, Angular, Ember и так далее. Они предоставляют сразу удобную MVC\MVVM архитектуру. А JQuery лишь предоставляет удобную выборку по селекторам и всякие анимашки, но никак не архитектурное решение, по этому не удивительно, что с ним творят что хотят.
Дада, это именно тот я, о котором ты возможно подумал, просто мой ник уже занят(((

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Магазин с доставкой

Сообщение Хакер » 06.10.2013 (Вс) 2:40

сэр Афим, а как, опять же, отцитированное относится к написанному?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

сэр Афим
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 11
Зарегистрирован: 13.10.2010 (Ср) 21:40

Re: Магазин с доставкой

Сообщение сэр Афим » 06.10.2013 (Вс) 3:02

Хакер писал(а):сэр Афим, а как, опять же, отцитированное относится к написанному?
промахнулся ненароком =) прошу прощения
Дада, это именно тот я, о котором ты возможно подумал, просто мой ник уже занят(((

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 06.10.2013 (Вс) 13:07

FireFenix писал(а):Что такое RIA? RIA это сервелат, флеш и аплеты и ещё какая-нить чушь. Вот оно то и протухло

C чего бы вдруг? RIA = Rich internet application, часто одностраничное, постороенное на ajax-запросах для получения данных.
Сейчас для этого обычно используется как раз html5.

FireFenix писал(а):CMS имеет продуманную уже архитектуру для создание своих страниц, а не выдумывание различных велосипедов, для генерации/заполнения/отдачи шаблонов и собсно регистрации

Но серверной части. А если страница одна и всё на скриптах, то зачем сдалась CMS на сервере?

FireFenix писал(а):На одном JS всё не сделаешь.

Сайт - сделаешь. Более того, сейчас всё чаще так поступают.

FireFenix писал(а):По мимо самой бизнес-логики, на сервере должна быть регистрация.

Регистрация и все данные через сервис.

FireFenix писал(а):По мимо регистрации ещё должен быть маршрутизатор редиректа к модулю/программе, шаблонизатор, кешер, логгер и ещё кучу всего...

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

сэр Афим писал(а):Если что-то разрабатывается под них html5 использовать ни в коем случае нельзя

Везде пишут что наоборот. И вроде всё замечательно разрабатывают. Может, дело просто в кривости рук соответствующих разработчиков?
А вот загнать на мобильный сайт флеш - уж точно извращение...

сэр Афим писал(а):Именно из-за этого сейчас приходится писать проект на канвасах

Ничего, что canvas тоже html5? ;)

Хакер писал(а):Я просто дурею от того, насколько у них код, определяющий логику перемешан с кодом, определяющим отображение.

Да, есть такой недостаток у jQuery... Если добавить фреймвёрк типа Ангуляра, то станет лучше.
По поводу классов. В браузерах нативно поддерживается получение всех элементов по классу, причём весьма эффективное. Так что тут ничего плохого нет.

Хакер писал(а):И вообще, по-моему глубокому убеждению развитие веба и HTML пошло не туда. Причём у меня была большая надежда на HTML5, что они поверут вектор в правильную сторону, но вместо этого они наоборот возвели в квадрат все те дурацкие моменты, которые были до этого.

Где-то тут ты писал про html...
History api уже появилось, ещё куча всего. Оно постепенно начинает вытеснять флеш (в Firefox, например, пытаются прикрутить флеш-плеер, написанный на js с использованием html5).
Да и вообще, вроде html стал намного лучше. Я вот сейчас делаю форму под IE Quirks 5 (т. е. режим эмуляции IE 5.5) - такая дрянь изо всех дыр лезет :(

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Магазин с доставкой

Сообщение Хакер » 06.10.2013 (Вс) 13:16

Qwertiy писал(а):В браузерах нативно поддерживается получение всех элементов по классу, причём весьма эффективное. Так что тут ничего плохого нет.

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

Фронтендная логика и фронтендный presentation — это должно быть два разных изолированных друг от друга слоя.

А тут получается куча проблем. Начиная от проблемы вроде «что если когда-нибудь какой-нибудь верстальщик заведёт CSS-класс, который глупый программист использовал как флаг», и заканчивая тем, что разные программисты могут для флагов воспользоваться конфликтующими стилями.

В принципе под флаг достаточно 1 бита. В один байт можно засунуть 8 флагов, флаги, основанные на наделении DOM-элементов фиктивными CSS-классами требуют для своего функционирования десятки байтов на хотя бы сам имена классов и килобайты на внутрении структуры, такие как деревья и словари, которые движок браузера обязан поддерживать для эффективной работы всего этого добра.

Не удивительно, почему мне приходится рисовать такие картинки:
Изображение
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 06.10.2013 (Вс) 14:07

Хакер писал(а):Вопрос не в эффективности, а в идеологической правильности.

Это идёт из глубин разработки веб-сайтов. Без jQuery всё делалось так же. Так что сваливать вину за это на jQuery - нелогично.
Часто эти классы всё-же что-то значат. Например, выбранный элемент как-то подсвечивается. Кстати, плюс классов ещё и в удобной отладке.
А для данных в html5 введены data-атрибуты. Но вот делать по ним поиск будет весьма неэффективно.
Вообще, сам по себе jQuery - это в первую очередь возможность писать код, не задумываясь о том, в каком браузере потом откроют страницу. Написал $smth.text() и получил текст, не думая, что везде это реализуется через innerText, а в Firefox - через textContent. Написал $.ajax и не разбираешься, что использовать - какую-то из 4 (или сколько их там) майкросовтовских реализаций ajax'а или же объект, оапределённый стандартом html; добавил параметр json и не разбираешься с тем, что в старых IE нет встроенного парсинга json'а. И ещё уйма таких вещей.

Хакер писал(а):Фронтендная логика и фронтендный presentation — это должно быть два разных изолированных друг от друга слоя.

Добавляем джаваскриптовый MVC-фреймвёк и получаем два разных слоя. А у jQuery немного другое назначение.

Хакер писал(а):Закрыл дико виснущий Firefox...

Хорошо что не Хром...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Магазин с доставкой

Сообщение Хакер » 07.10.2013 (Пн) 2:59

Qwertiy писал(а):Это идёт из глубин разработки веб-сайтов. Без jQuery всё делалось так же.

Нет, это идёт от криворукости и отсутствия мозгов. Какой-то глупенький новоявленный веб-разработчик так сделал, и потом тысячи хомячков взяли это за правило.

Это против «принципа лени». Если у вас сейчас есть ссылка на элемент, с которым вы хотите что-то делать, то ссылку надо сохранять в переменную, а не использовать поиск каждый раз, когда вам надо вновь получить ссылку на этот элемент.

Qwertiy писал(а):А для данных в html5 введены data-атрибуты. Но вот делать по ним поиск будет весьма неэффективно.

Ох. А что мешало до этого снабдить любой DOM-элемент любым нужным тебе свойством? Когда я спросил наших, почему они так не делают, оказалось, что они просто не знают, что так можно делать.

Правда, в чём причина? Я могу предположить, что мне могут ответить что-то типа «это опасно, а что если в будущем появится такое штатное свойство?». Но мне как-то не особо это видится как аргумент, потому что вся клиентская веб-разработка это история о хаках и workaround-ах.

Qwertiy писал(а):Вообще, сам по себе jQuery - это в первую очередь возможность писать код, не задумываясь о том, в каком браузере потом откроют страницу. Написал $smth.text() и получил текст, не думая, что везде это реализуется через innerText, а в Firefox - через textContent. Написал $.ajax и не разбираешься, что использовать - какую-то из 4 (или сколько их там) майкросовтовских реализаций ajax'а или же объект, оапределённый стандартом html; добавил параметр json и не разбираешься с тем, что в старых IE нет встроенного парсинга json'а.

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

Кстати, то, как там сделаны XHR-запросы, меня не устраивает. Вплоть до названия. И вообще, я аналогичное могу сказать о всех остальных фреймворках. Читаю код, и у меня фейспалм и мысль: «ну какого чёрта они сделали эту штуку так примитивно, негибко и недавльновидно и неэффективно».
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 07.10.2013 (Пн) 9:01

Хакер писал(а):Это против «принципа лени». Если у вас сейчас есть ссылка на элемент, с которым вы хотите что-то делать, то ссылку надо сохранять в переменную, а не использовать поиск каждый раз, когда вам надо вновь получить ссылку на этот элемент.

Не так. Если была сформирована строка с html-разметкой, то никаких dom-объектов ещё нет. Потом, когда эта строка будет помещена в innerHTML чего-либо, браузер сам её распарсит, но никаких ссылок опять же не вернёт. Добавленные таким способом элементы всё равно придётся искать. Так зачем же их искать сразу, может быть пользователь даже не нажмёт ту кнопку, для обработчика которой это потребуется?
Ещё, если код передаётся с сервера, от опять же, никаких ссылок нет, всё что хочется использовать надо найти.
Дальше, если вызвать копирование некоторого куска, или даже просто переприсвоить содержимое, то все ссылки слетят.
К тому же, в старых браузерах (естественно, IE в первую очередь), обращение к переменным, находящимся в замыкании замедляет работу в разы. Так что получается, что если мы сохранили ссылку, а потом к ней обращаемся, то это выйдет медленнее, чем если мы найдём элементы, поместим ссылку в локальную переменную и будем работать с ней.
А ещё, если насохранять где-то ссылок на dom-объекты, то эти dom-объекты не могут быть уничтожены, т. е. получаем ещё и утечки памяти в добавок ко всему остальному.
В общем, получается проще, понятнее и безопаснее находить элементы по мере необходимости, чем запастись огромным запасом ссылок на все случаи жизни и мучаться, что половина поломалась, когда по мере работы кто-то что-то перезаписал. К тому же, вполне возможно, что со ссылками потребление памяти будет больше, чем без них.
Вот искать одно и то же в одной функции несколько раз - это плохой стиль, а искать какие-то элементы один раз на обработчик события - вполне нормально.

Хакер писал(а):Ох. А что мешало до этого снабдить любой DOM-элемент любым нужным тебе свойством?

Имеешь в виду myDiv.asdfgh = { a: 10, b: "abc" };? Опять же, если потом сделать container.innerHTML += "<p>Smth new</p>", то все эти свойства полетят нафиг, вместе со всеми сохранёнными ссылками на dom-объекты. А data-атрибуты и классы никуда не денутся. Ну и присвоить свойство можно только из скрипта. С сервера переслать dom-объект с заданным свойством тоже не выйдет, а с data-атрибутом (как и с любым другим) - без проблем.

Хакер писал(а):Вплоть до названия.

Ну не знаю. Мне jQuery'вские названия вполне нравятся - они короткие и относительно понятные. К тому же, в jQuery принято возвращать объект, с которым производятся действия, что (лично мне) очень удобно.

Хакер писал(а):Читаю код, и у меня фейспалм и мысль: «ну какого чёрта они сделали эту штуку так примитивно, негибко и недавльновидно и неэффективно».

Во-первых, а зачем там гибкость? Во-вторых, ты думаешь, что если каждый разработчик начнёт писать нечто подобное в каждом месте, где ему понадобилось использовать ajax, то код станет красивым и понятным? :lol:
Или какую негибкость ты имеешь в виду? Вроде метод ajax как раз весьма гибкий в плане использования...

PS: Вот интересный кусок кода (валидная html5-страница):
Код: Выделить всё
<!doctype html>

<title>Magic</title>

<style>p+table{color:blue;}p>table{color:red;}</style>

<p><table><tr><td>1<td>2<tr><td>3<td>4</table>
<p data-inner-table="<tr><td>1<td>2<tr><td>3<td>4">

<p>
<script>Array.prototype.forEach.call(document.querySelectorAll("p[data-inner-table]"),function(p,t){p.appendChild(t=document.createElement("table"));t.innerHTML=p.attributes["data-inner-table"].value})</script>
<button onclick="document.body.innerHTML=document.body.innerHTML">Rehtml</button>
Что будет если нажать кнопочку?


Вернуться в Народный треп

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 10

    TopList