Здравствуйте, коллеги!
"Рисуется" 3-х звенное приложение с кэшем (у app-сервера). DataService будут использовать ORM (сейчас всё вертится на BLToolkit-е). Встал вопрос каким образом реализовать кэширование, и (по возможности) отложенную загрузку на клиенте. Пришли вот в какому варианту:
public abstract class ParentEntity : BizEntity
{
public abstract Guid ID { get; set; }
public abstract Guid ChildID { get; set; }
[MapIgnore]
public ChildEntity Child
{
get { return _dataService.GetObject<ChildEntity>(ChildID); }
protected set { ... }
}
}
Мои сомнения по поводу одновременного хранения ID и самого объекта.
Есть ли более кошерные способы?
P.S. хотим услышать как можно больше вариантов, их "+" и "-", потому что сами уже обессилили в бесконечных спорах о них...
>Мои сомнения по поводу одновременного хранения ID и самого объекта > Есть ли более кошерные способы?
Приведите цитату из Торы, из которой следует, что наличие ID нарушает
кашрут.
Если нужен, почему не приделать?
Posted via RSDN NNTP Server 2.1 beta
Данное сообщение является художественным произведением и освещает вымышленные события в вымышленном мире. Все совпадения с реальностью являются случайными. Не является инвестиционной рекомендацией.
Здравствуйте, Аноним, Вы писали:
А>"Рисуется" 3-х звенное приложение с кэшем (у app-сервера). DataService будут использовать ORM (сейчас всё вертится на BLToolkit-е). Встал вопрос каким образом реализовать кэширование, и (по возможности) отложенную загрузку на клиенте. Пришли вот в какому варианту:
А> get { return _dataService.GetObject<ChildEntity>(ChildID); }
А внутри каждой энтити хранить ссылку на сервис разве кузяво?
А>P.S. хотим услышать как можно больше вариантов, их "+" и "-", потому что сами уже обессилили в бесконечных спорах о них...
А сбрасывать кеши когда либо планируется? Синхронизировать кеши будете?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, Аноним, Вы писали:
_FR>
А>> get { return _dataService.GetObject<ChildEntity>(ChildID); }
_FR>
_FR>А внутри каждой энтити хранить ссылку на сервис разве кузяво?
нет. конечно же _dataService — не мембер Entity (он синглетон)
_FR>А сбрасывать кеши когда либо планируется?
да: пока, практически в каждой таблице в БД храниться TimeStamp
_FR>Синхронизировать кеши будете?
планируем, с помощью "арбитра" (как правильно, по научному — не знаю.)
А>>> get { return _dataService.GetObject<ChildEntity>(ChildID); }
_FR>>А внутри каждой энтити хранить ссылку на сервис разве кузяво? B>нет. конечно же _dataService — не мембер Entity (он синглетон)
Ну по сравнению с этим уже ничего не страшно
От сабжевой проблемы тогда можно уйти очень просто: объявить методы-расширения:
public abstract class ParentEntity : BizEntity
{
public abstract Guid ID { get; set; }
public abstract Guid ChildID { get; set; }
}
static class DataMethods
{
public static ChildEntity Child(this XDataService /* тип _dataService у вас */ dataService, ParentEntity entity) {
if(dataService == null) {
throw new ArgumentNullException("dataService");
} else if(entity == null) {
throw new ArgumentNullException("entity");
}//ifreturn dataService.GetObject<ChildEntity>(entity.ChildID);
}
// Или даже так, если синглетон не режет глазpublic static ChildEntity Child(this ParentEntity entity) {
if(entity == null) {
throw new ArgumentNullException("entity");
}//ifreturn _dataService.GetObject<ChildEntity>(entity.ChildID);
}
}
_FR>>А сбрасывать кеши когда либо планируется? B>да: пока, практически в каждой таблице в БД храниться TimeStamp _FR>>Синхронизировать кеши будете? B>планируем, с помощью "арбитра" (как правильно, по научному — не знаю.)
"_dataService" — это тулкитный объект? Он эти два пункта сумеет выполнить?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Ну по сравнению с этим уже ничего не страшно
Извините, но не совсем понял, что Вы имели ввиду...
Окромя шуток. Почитал Ваши посты... ответы, на мой взгляд, адекватны и в тему.
Вот и подумал, может всё-таки действительно что-то страшное уже намутили, но сами не видим
Спасибо!
Здравствуйте, bin64, Вы писали:
_FR>>Ну по сравнению с этим уже ничего не страшно
B>Извините, но не совсем понял, что Вы имели ввиду... B>Окромя шуток. Почитал Ваши посты... ответы, на мой взгляд, адекватны и в тему. B>Вот и подумал, может всё-таки действительно что-то страшное уже намутили, но сами не видим B>Спасибо!
Данная ремарка посвящена использованию синглетона, ибо в некоторых кругах, к коим имею честь принадлежать и я, использование изменяемых глобальных объектов считается за не комильфо. Подробнее о синглетонах можно вычитать здесь.
Хорошим примером синглетона может служить DBNull.Value. Плохим — глобальный кеш объектов.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Аноним, Вы писали:
А>>Есть ли более кошерные способы?
L>Кошерный способ — не использовать отложенную загрузку на клиенте. За подробностями — в гугль с запросом "n+1 problem".
Видимо, я не так объяснил.
"Отложенная загрузка" — это возможность клиентской программе считывать данные по мере необходимости (и тем самым не захламлять память, возможно, лишними данными). Это совершенно не означает, что данные берутся прямо из БД. Просто-напросто, вовсе нет такой необходимости грузить все связанные объекты.
[off]есть ли способ редактирования ошибочно отправленного сообщения на RSDN?[/off]
Здравствуйте, _FRED_, Вы писали:
_FR>Данная ремарка посвящена использованию синглетона, ибо в некоторых кругах, к коим имею честь принадлежать и я, использование изменяемых глобальных объектов считается за не комильфо. Подробнее о синглетонах можно вычитать здесь.
Синглетон -- это когда нужен ровно один экземпляр. Вопрос контроля самого создания не ставится.
_dataService — именно этот случай. Кэш, как таковой, находится между БД и _dataService.
_FR>Хорошим примером синглетона может служить DBNull.Value. Плохим — глобальный кеш объектов.
Вот тут, видимо, тонкая грань и прорисовывается. Т.к. апп-серверов будет несколько (аля кластер), то решено было выделить Головного Арбитра. Он распределяет не только нагрузку по запросам, но и по кэшу (на самом деле их два: апп-арбитр и кэш-арбитр, для удобства, во время своих переговоров с коллегами мы объединяем их, для краткости). На каждом aпп-сервере есть свой арбитр, который в момент запуска определяется кто он: ведомый или ведущий...
Теперь вопрос. Такая модель, тоже является "плохим примером"?
Здравствуйте, bin64, Вы писали:
L>>Кошерный способ — не использовать отложенную загрузку на клиенте. За подробностями — в гугль с запросом "n+1 problem".
B>Видимо, я не так объяснил.
Вы все правильно объяснили.
B>"Отложенная загрузка" — это возможность клиентской программе считывать данные по мере необходимости (и тем самым не захламлять память, возможно, лишними данными). Это совершенно не означает, что данные берутся прямо из БД. Просто-напросто, вовсе нет такой необходимости грузить все связанные объекты.
Это не важно, берутся данные из базы или подкачиваются с апп-сервера. Проблема остается та же.
Здравствуйте, _FRED_, Вы писали:
B>>Вот и подумал, может всё-таки действительно что-то страшное уже намутили, но сами не видим B>>Спасибо!
_FR>Данная ремарка посвящена использованию синглетона, ибо в некоторых кругах, к коим имею честь принадлежать и я, использование изменяемых глобальных объектов считается за не комильфо.
Т.е. если синглтон сделать неизменяемым, то он сразу станет комильфо? Имхо, вы неправильно понимаете, почему синглтон — не комильфо.
_FR>Подробнее о синглетонах можно вычитать здесь.
_FR>Хорошим примером синглетона может служить DBNull.Value.
DBNull.Value — вообще ни разу ни синглтон. Ты бы еще null в этот отряд записал.
_FR>Плохим — глобальный кеш объектов.
А если он загружается при старте приложения и никогда более не меняется?
Здравствуйте, bin64, Вы писали:
B>Здравствуйте, Lloyd, Вы писали:
L>>Это не важно, берутся данные из базы или подкачиваются с апп-сервера. Проблема остается та же. B>Например?
погуглите по "n+1 problem". я вряд ли смогу лучше объяснить, чем гугл, у меня объяснялка плохо работает.
Здравствуйте, bin64, Вы писали:
_FR>>Данная ремарка посвящена использованию синглетона, ибо в некоторых кругах, к коим имею честь принадлежать и я, использование изменяемых глобальных объектов считается за не комильфо. Подробнее о синглетонах можно вычитать здесь. B>
B>Синглетон -- это когда нужен ровно один экземпляр. Вопрос контроля самого создания не ставится.
B>_dataService — именно этот случай. Кэш, как таковой, находится между БД и _dataService.
Именно про этот случай принято в нашей секте всячески порицать. Впрочем, никто вас не агитирует: если сказанно в статье не навело вас на "правильные" размышления, можете на мои слова внимания не обращать.
Разница в том, что "_dataService" у вас содержит некое состояние, которое требует настройки (это видно из протокола вызова — не сказано откуда брать данные, значит _dataService это знает, не сказано, как кешировать, значит _dataService это знает и прочее). Это очень печально видеть в, тем более, больших приложениях.
_FR>>Хорошим примером синглетона может служить DBNull.Value. Плохим — глобальный кеш объектов. B>Вот тут, видимо, тонкая грань и прорисовывается. Т.к. апп-серверов будет несколько (аля кластер), то решено было выделить Головного Арбитра. Он распределяет не только нагрузку по запросам, но и по кэшу (на самом деле их два: апп-арбитр и кэш-арбитр, для удобства, во время своих переговоров с коллегами мы объединяем их, для краткости). На каждом aпп-сервере есть свой арбитр, который в момент запуска определяется кто он: ведомый или ведущий... B>Теперь вопрос. Такая модель, тоже является "плохим примером"?
Понятия не имею, на самом деле вы сказали очень мало. Кстати, под "глобальный кеш объектов" я на самом деле подразумевал ("Плохим") не сам по-себе кеш, а реализацию его (доступа к нему) в виде синглетона.
Вообще я не очень понимаю идею распределения нагрузки "по кэшу" — это что же, распределятор должен знать, какой у кого кеш? Или по каким критериям он будет распределять? А то ведь и "по запросам" можно "распределять" в порядке живой очереди или даже рандомайзером
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, bin64, Вы писали:
_FR>Именно про этот случай принято в нашей секте всячески порицать. Впрочем, никто вас не агитирует: если сказанно в статье не навело вас на "правильные" размышления, можете на мои слова внимания не обращать.
Как говорится, дьявол кроется в мелочах... Высказывания мне не очень понравились, своей категоричностью. К сожалению, пока нет возможности её здесь обсуждать. Но в комментариях "несогласных" к статье, есть многое из-того с чем согласен. Всё-таки "мухи — отдельно, котлеты — отдельно"
_FR>Разница в том, что "_dataService" у вас содержит некое состояние, которое требует настройки (это видно из протокола вызова — не сказано откуда брать данные, значит _dataService это знает, не сказано, как кешировать, значит _dataService это знает и прочее). Это очень печально видеть в, тем более, больших приложениях.
Ок. Тогда по выделеному. Т.е., по вашему, в каждом обращении к данным из БД/кэша необходимо явно указыать/регулировать не только вызовы, но и откуда брать данные? ИМХО -- анархия... или я вообще не о том?
_FR>Понятия не имею, на самом деле вы сказали очень мало. Кстати, под "глобальный кеш объектов" я на самом деле подразумевал ("Плохим") не сам по-себе кеш, а реализацию его (доступа к нему) в виде синглетона.
А как тогда? Хотя бы примерно ткните пальцем на реализаию или тут в двух словах.
_FR>Вообще я не очень понимаю идею распределения нагрузки "по кэшу" — это что же, распределятор должен знать, какой у кого кеш? _FR>Или по каким критериям он будет распределять? А то ведь и "по запросам" можно "распределять" в порядке живой очереди или даже рандомайзером
Да, с кэшем (определение попадания/нахождения) есть некоторые проблемы, хотя и ID есть у каждого объекта. Однако, проблем с распределением как раз-таки — нет. Каждый арбитр (кэша) вычисляет условную нагрузку, объём данных и пр., а при опросе её возвращает, головному арбитру, который и решает что делать.
Признаться, в начаеле, мне самому не очень понравилась такая модель, да и исходники мы толком не видели в начале. Но человек, который это реализовал, продемострировал скорость работы на другом проекте, и мы пока приняли его . По ходу. Где можно посмотреть/почитать хорошую сатью о кластеризации/кэше (желательно, (но не обязательно) на русском -- у нас не все владеют английским на столько чтобы свободно читать)?
Здравствуйте, bin64, Вы писали:
_FR>>Разница в том, что "_dataService" у вас содержит некое состояние, которое требует настройки (это видно из протокола вызова — не сказано откуда брать данные, значит _dataService это знает, не сказано, как кешировать, значит _dataService это знает и прочее). Это очень печально видеть в, тем более, больших приложениях. B>Ок. Тогда по выделеному. Т.е., по вашему, в каждом обращении к данным из БД/кэша необходимо явно указыать/регулировать не только вызовы, но и откуда брать данные? ИМХО -- анархия... или я вообще не о том?
Нет конечно.
_FR>>Понятия не имею, на самом деле вы сказали очень мало. Кстати, под "глобальный кеш объектов" я на самом деле подразумевал ("Плохим") не сам по-себе кеш, а реализацию его (доступа к нему) в виде синглетона. B>А как тогда? Хотя бы примерно ткните пальцем на реализаию или тут в двух словах.
Не делать синглетон. Например, иметь DI-контейнер и передавать ссылку на него в различные куски программы.
_FR>>Вообще я не очень понимаю идею распределения нагрузки "по кэшу" — это что же, распределятор должен знать, какой у кого кеш? _FR>>Или по каким критериям он будет распределять? А то ведь и "по запросам" можно "распределять" в порядке живой очереди или даже рандомайзером B>Да, с кэшем (определение попадания/нахождения) есть некоторые проблемы, хотя и ID есть у каждого объекта. Однако, проблем с распределением как раз-таки — нет. Каждый арбитр (кэша) вычисляет условную нагрузку, объём данных и пр., а при опросе её возвращает, головному арбитру, который и решает что делать. B>Признаться, в начаеле, мне самому не очень понравилась такая модель, да и исходники мы толком не видели в начале. Но человек, который это реализовал, продемострировал скорость работы на другом проекте, и мы пока приняли его .
Без знания того, как именно и что конкретно при этом делается сложно давать советы.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, bin64, Вы писали:
_FR>>>Разница в том, что "_dataService" у вас содержит некое состояние, которое требует настройки (это видно из протокола вызова — не сказано откуда брать данные, значит _dataService это знает, не сказано, как кешировать, значит _dataService это знает и прочее). Это очень печально видеть в, тем более, больших приложениях. B>>Ок. Тогда по выделеному. Т.е., по вашему, в каждом обращении к данным из БД/кэша необходимо явно указыать/регулировать не только вызовы, но и откуда брать данные? ИМХО -- анархия... или я вообще не о том?
_FR>Нет конечно.
Если не затруднит, можно конкретнее и подробнее? Хотя бы на примере, того как надо. Мне вообще кажеться, что мы идём "не туда". Понятно, что идеальной архитектуры системы (тем более с самого начала) нет, но к идеалу стремиться всё-таки надо.
Здравствуйте, bin64, Вы писали:
_FR>>>>Разница в том, что "_dataService" у вас содержит некое состояние, которое требует настройки (это видно из протокола вызова — не сказано откуда брать данные, значит _dataService это знает, не сказано, как кешировать, значит _dataService это знает и прочее). Это очень печально видеть в, тем более, больших приложениях. B>>>Ок. Тогда по выделеному. Т.е., по вашему, в каждом обращении к данным из БД/кэша необходимо явно указыать/регулировать не только вызовы, но и откуда брать данные? ИМХО -- анархия... или я вообще не о том?
_FR>>Нет конечно. B>Если не затруднит, можно конкретнее и подробнее? Хотя бы на примере, того как надо. Мне вообще кажеться, что мы идём "не туда". Понятно, что идеальной архитектуры системы (тем более с самого начала) нет, но к идеалу стремиться всё-таки надо.
Ниже же и было сказано: передавать контейнер ("Не делать синглетон. Например, иметь DI-контейнер и передавать ссылку на него в различные куски программы."). Контейнер уже не будет синглетоном и при конструировании объектов сможет "честно" использоваться различные настройки.
Почитайте про IoC, DI и прочее и попробуйте написать программу со всем этим и без синглетонов.
Help will always be given at Hogwarts to those who ask for it.