Задачка на архитектуру

grigori

( ͡° ͜ʖ ͡°)
Команда форума
ты не понял
коллекция создает в себе объекты юзеров, юзер - это и есть data mapping аналогично AR, и он знает, как себя сохранять, без SQL,
но юзер ничего не знает о том, откуда он взялся
 

MiksIr

miksir@home:~$
Но сохраняет себя сам юзер? Т.е. код, вызывающий post у коннектора - где? В классе юзера?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
> @grigori не захотел это делать
здрасти. я сказал, что не хочу обсуждать код фиксера - он и так очевиден
Обработка всяческих failover занимает это 80% объема кода, и от того, как именно нужна синхронизация, целиком зависит архитектура реализации.
У нас была синхронизация заказов с двусторонним обновлением состояний, и это была песня.
DNS сбоит, роутеры между датацентрами ложатся, сервера уходят в downtime и у слейвов есть latency. Все это надо обрабатывать, а значит, на все нужен отдельный слой и обработка исключений.
Каждая строка кода фиксера разворачивается во что-то вроде
PHP:
 try{
    $timestamp = now() - App::Db->latency;
    $UserCollectionB = (new UserCollection)->setDatasource($ConnectorB)->setTimestamp($timestamp)->loadAll();
 }catch(DbException $E){
  App::log($E->errorMessage);
  $ConnectorA->disconnectWithInternalFailure();
Если надо - на каждую строку оформляется отдельный метод какого-то сервисного слоя. Или DNS прописан в /etc/hosts и все бегает по локалке и можно не заморачиваться?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Но сохраняет себя сам юзер? Т.е. код, вызывающий post у коннектора - где? В классе юзера?
Юзер - ORM, аналогичный ActiveRecord. Код, вызывающий post у коннектора - в драйвере, который приписан в конфиге у коннектора. Нет, не в классе юзера.
 

MiksIr

miksir@home:~$
Каждая строка кода фиксера разворачивается во что-то вроде
Я это и предполагал. Но согласись, это уже обработка состояний, которая ни коим образом на изначальную архитектуру не влияет. И чем мы ее изначально сделаем более модульной и слабосвязанной, тем легче потом все эти исключения ловить. Но это уже практика, которая никоим образом не ущемляет теорию. Я почему спрашивал, ибо может ты скажешь - "датамапер говно, ибо нельзя словить такой-то случай, что на практике выльется в такие-то проблемы".
Юзер - ORM, аналогичный ActiveRecord. Код, вызывающий post у коннектора - в драйвере, который приписан в конфиге у коннектора. Нет, не в классе юзера.
Ну у AR итоговый код все же в модели, если смотреть вниз по иерархии классов. В таком случае и получение массива юзеров должно быть где-то там же, т.е. User::getAll и т.п.? Ну в общем все все-равно утыкается в AR vs DM, не смешивать же их.
 

fixxxer

К.О.
Партнер клуба
У @fixxxer была - там юзер знал, как себя добавить. Мое первое решение было аналогичное - юзер знает как достать себя и как добавить.
Это знание на уровне интерфейса, а не на уровне конкретного коннектора/стораджа/драйвера. То есть юзер знает, что чтобы добавить себя, надо дернуть грубо говоря $this->Datasource->add($this)
 

cDLEON

Онанист РНРСlub
MiksIr, у тебя модель в ActiveRecord знает, что такое ПДО ? ПДО это - datasource. Если тебе нужно работать сразу с двумя datasource - делай datasourceCluster с тем же интерфейсом, в который инжекть нужные тебе datasource.
Только вот один хрен эта задача решается не с того конца.
 

MiksIr

miksir@home:~$
Это знание на уровне интерфейса, а не на уровне конкретного коннектора/стораджа/драйвера. То есть юзер знает, что чтобы добавить себя, надо дернуть грубо говоря $this->Datasource->add($this)
А, я под коннектором подразумевал более низкий уровень, вот как вышеупомянутое PDO. Т.е. по сути ->get($uri), ->post($uri, $data).
Но в общем в любом случае спасибо, не со всем согласен, но определенный толчок был дан.
Осталось посмотреть, есть ли что-то из паттернов для работы с коллекциями.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
паттернизм detected

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

MiksIr

miksir@home:~$
Грабленаступатель детектед. Ага, предпочитаю узнать, какие есть решения, прежде чем двигаться дальше. Видимо вы работаете иначе.
> да она, обработка состояний, эту архитектуру и определяет чуть менее чем полностью
Может все же будет что-то конкретное, чем гипотезы о том, кто что поддерживал? А то пока видно только торчащее из форма ваше ЧСВ.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
вот уж тролль :)
ну вот простой пример: Ютинет дал свой API, по которому надо передавать способы доставки на товары по регионам. Нормальный API, в принципе.
Мы прикинули: 300 городов, 40 тысяч позиций товаров, по 10 способов доставки в каждом регионе, по 500 байт на запись, итого 50 мегабайт. В POST-запрос не влезет никак.
Результат - Ютинет оставил свой красивый API для мелких партнеров и сам по крону забирает список условий доставки в формате CSV в gzip. Объем данных меняет все.
 

MiksIr

miksir@home:~$
Круто. А какое это отношение имеет к описанной задаче?
Ну да, если в сервисе нужно будет синхронизировать несколько миллионов пользователей, то придется чуток все поменять.
Какие еще проявления больших чисел придет в голову?
Не, вот может про ЧСВ и обидно, но как мне еще определить людей, которые на простую задачу сразу приходят с высокими нагрузками и большими числами? Или на этом форуме из-за некоторых людей каждый раз следует писать "речь не о хайлоаде и не о бигдата"?
 

cDLEON

Онанист РНРСlub
@MiksIr Мусье, вы нормальный вообще ?
Я, конечно, понял, что ваша задача заключается в том, что бы правильно назвать объектики. Но всё же... Описанная вами "задача" воспринимается как более глубокий вопрос про архитектуру, в котором не хватает деталей.
Когда я, невольный раб любопытства, решил полюбопытствовать по поводу этих самых деталей - я был невольно (но культурно) послан на йух.
После этого - вы попросили истинных программистов всея Руси и ближних стран зарубежия привести примеры возможных косяков. Григорий вам любезно привёл пример того, что одна единственная деталь может напрочь поломать вашу "архитектуру" с синхронизацией.
А в ответ вы обозвали его великим и ужасным человеком с завышенным ЧСВ, который навязывает вам хайлоады.
А ведь нужно было всего то в вводном вопросе конкретизировать ЗАДАЧУ, которая стоит перед ВАМи. А вам названия объектиков подавай.....
 

MiksIr

miksir@home:~$
> После этого - вы попросили истинных программистов всея Руси и ближних стран зарубежия привести примеры возможных косяков
А я то пытался понять - кем вы себя тут считаете. Вот оно, оказывается, как.

> Я, конечно, понял, что ваша задача заключается в том, что бы правильно назвать объектики. Но всё же...
Все же что? Решили покрасоваться?

> А ведь нужно было всего то в вводном вопросе конкретизировать ЗАДАЧУ, которая стоит перед ВАМи.
Специально для вас и прочих "истинных" конкретизирую: не highload, не bigdata. Удовлетворены? Какие еще критерии выдумаете?
Еще раз: задача описана полностью. Если бы в задаче стояло требование двусторонней синхронизации, синхронной, асинхронной, консистентной и еще куча других умных слов - это было бы указано в задаче.

Блин, мне страшно подумать, как вы выходите из дома в магазин. Наверно, чуть ли не завещание каждый раз пишете. Что бы "все спрогнозировать".
 
Последнее редактирование:

MiksIr

miksir@home:~$
> Григорий вам любезно привёл пример того, что одна единственная деталь может напрочь поломать вашу "архитектуру" с синхронизацией.
Не в кассу, но да, привел. Совсем не в кассу, но все-равно спасибо, что потратил время. И, к слову, совсем не уверен, что ломает. Ради интереса, после построения такой архитектуры посмотрю - как легко ее можно будет отрефакторить на большое количество данных.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
ну, блин, я уже реально не понимаю твой вопрос, ты требуешь чтоб мы угадывали какой ответ тебя устроит

вот еще "в кассу" из моей жизни: добавим в данные пользователей поле paid bool, и архитектура приложения вырастает из фиксеровского примера на 3 строки в конструкцию с выделением большого слоя REST с реализацией failover и переводом сервера B в специальный режим ограниченного функционала при сбое связи
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
да ТС все что-то не нравятся ответы, таки да, пора забить
 

fixxxer

К.О.
Партнер клуба
MiksIr, мне кажется, тебе мешает то, что ты привык к Yii-подобному AR, где findOne() и findAll() - методы "как бы" одной и той же штуки (хотя на самом деле внутри на уровне фреймворка многое происходит).
Я об ином подходе. Есть User extends ItemEntity, есть UserCollection extends EntitiesCollection<User> (дженерик эмулируем статическим методом getItemClass). Item умеет себя загрузить и сохранить через датасорс, Collection умеет делать запросы к датасорсу на много итемов и создавать их коллекцию. Да, получается связанная пара, но не вижу в этом ничего плохого: Collection это такая загружалка-и-фабрика, но Item можно использовать и отдельно (так же как объект можно создать фабрикой, а можно просто так).
Насчет паттернов не знаю, может и есть такие, я это сам придумал еще давно, вполне удобно.

И, кстати, Collection теоретически может быть один на все - new Collection(User::class), а все необходимое для его работы определять декларативно статически в User (AR-style). Но тут легко погрязнуть в расширении деклараций для хитрых частных случаев. Можно и комбинировать, конечно - где не хватает стандартного Collection, там экстендим.
 
Последнее редактирование:

Тугай

Новичок
Вот видео:
Следуя видео, слишком много не нужных абстракций, достаточно User - value object, UserRestService implements UserService (getAll(), add(), exists(), ...)
Сама задача сравнить два списка и дополнить второй слишком простая, чтоб выдумывать что-то сложное.
Напоминает проект складывающий 1+1.

Про колекции тоже немного перемудрили, колекция - это просто структура данных для роботы со списком элементов, в этой задачке можно и простыми массивами обойтись.
getAll() - может вернуть массив или коллекцию или связный спискок или дерево или объект реализующий паттерн RowDataSet или ...
 
Сверху