Ищу паттерн (+)

Все, что вы хотели знать о программизме, но боялись спросить.
Ответить
Аватара пользователя
aldep
Маньяк
Сообщения: 1593
Зарегистрирован: 18 фев 2003, 08:06
Откуда: Toronto
Контактная информация:

Ищу паттерн (+)

Сообщение aldep »

Условие:
Центральный компьютер посылает запросы на компьютеры в локальной сетке, получает ответы и заносит их в БД. Библиотека, ответственная за обмен сообщениями не поддерживает асинхронные вызововы.
Запросы на каждый компьютер должны посылаться в точно заданное время (примерно с частотой раз в минуту) ответ должен приходить за доли секунды.
Это в идеале. На практике большинство компьютеров обычно действительно отвечают быстро, но часть тянет с ответом по многу секунд (в особо кривых случаях вплоть до часа). Причем в редких случаях доля западывающих компьютеров может достигать 90%.
Приложение будет написано под .НЕТ, а библиотека в native code, поэтому если она сама не возвращает по таймауту, то прервать ее нет никакой возможности.
Задача - сделать систему работающую в вышеописанных условиях и маштабируемую в пределах 10-3000 компьтеров. Т.е. до 50 запросов в секунду. Временная точность должна определятся параметрами соединения с компьютером т.е. если компьютер отвечает за доли секунды, то и точность посылки/принятия запроса должна быть 1-2 секунды в большинстве случаев.

Пока никаких идей, кроме thread pool с большим числом потоков в голову не приходит. Недостаток - в пиковом случае приходится создавать для приемлемой точности 1000 потоков.
Есть ли какие другие шаблоны для решения подобных проблем.
Вроде подобные условия применимы ко многим областям.
Аватара пользователя
Marmot
Графоман
Сообщения: 39279
Зарегистрирован: 17 фев 2003, 17:58
Откуда: Caulfeild
Контактная информация:

Сообщение Marmot »

Non-blocking IO (select etc) в native code с последующими callback-ами в .NET code...

ЗЫ

Не прямые callback-и а через queue конечно, тогда в идеале надо будет три(а то всего два) потока.
Один(.NET) ставит запрoсы в изходящую очередь, второй (native code) их посылает и ждёт ответов, когда ответ пришёл ставит их в входящую очередь, третий, снова .NET, обрабатывает ответы...
Аватара пользователя
ajkj3em
Маньяк
Сообщения: 2063
Зарегистрирован: 12 ноя 2006, 06:53

Re: Ищу паттерн (+)

Сообщение ajkj3em »

aldep писал(а): Есть ли какие другие шаблоны для решения подобных проблем.
Вроде подобные условия применимы ко многим областям.
то есть по сути - как навесить async wrapper на existing blocking code ?

"шаблонов" - два. первый ты назвал, это a thread per blocking call.

второй - coopeative / custom-scheduled multithreading. идеа в том, что стандартные имплементации blocking API вызовов заменяютcя кастом версиями, которые делают (фактически) context switch в местах блокировки, возврашают управление в центральный dispatch loop, который окучивает все waiting conditions разом через non-blocking API. по сути это вариация co-routines.

на *nix делаетcя достаточно тривиально (через ucontext), на виндах тоже должно быть несложно. основная жопа в твоем случае - это необходимость to hook system calls, которые вызывает вта библиотека. тоже не сложно, но надо возит'cя с VirtaulLock/Unlock, JMP shims вставлять и все такое.
Аватара пользователя
Marmot
Графоман
Сообщения: 39279
Зарегистрирован: 17 фев 2003, 17:58
Откуда: Caulfeild
Контактная информация:

Re: Ищу паттерн (+)

Сообщение Marmot »

ajkj3em писал(а):второй - coopeative / custom-scheduled multithreading. идеа в том, что стандартные имплементации blocking API вызовов заменяютcя кастом версиями, которые делают (фактически) context switch в местах блокировки, возврашают управление в центральный dispatch loop, который окучивает все waiting conditions разом через non-blocking API. по сути это вариация co-routines.

на *nix делаетcя достаточно тривиально (через ucontext), на виндах тоже должно быть несложно. основная жопа в твоем случае - это необходимость to hook system calls, которые вызывает вта библиотека. тоже не сложно, но надо возит'cя с VirtaulLock/Unlock, JMP shims вставлять и все такое.
Ндаа, месье знает толк в извращениях...
ИМО легче сделать реверсинжениринг протоколу и имплементировать его самому...
vg
Маньяк
Сообщения: 2803
Зарегистрирован: 29 май 2003, 22:29
Откуда: Магадан - Миссиссага

Сообщение vg »

aldep,

Та архитектура, что описал вкратце Marmot, классическая и проверена многими.
Marmot писал(а):Non-blocking IO (select etc) в native code с последующими callback-ами в .NET code...

ЗЫ

Не прямые callback-и а через queue конечно, тогда в идеале надо будет три(а то всего два) потока.
Один(.NET) ставит запрoсы в изходящую очередь, второй (native code) их посылает и ждёт ответов, когда ответ пришёл ставит их в входящую очередь, третий, снова .NET, обрабатывает ответы...
Что-то типа этого работает и в задачах критичных по скорости и точности синхронизации по времени (точность около 100 ms). Типа близко к реал тайм.

ПС. По умолчанию winda выделяет 1 метр памяти под стек потока, поэтому попытка создать 100 вторичных потоков сразуже откусит больше 100 мегабайт памяти. Даже если ты (рядом у тебя пост про стек) укажешь, что стек потока, cкажем 64K, то это не поможет, посколькй при таком числе потоков и одном процессоре, всё будет в лучшем случае медленно делать вид, что, умирая, работает. В худшем случае, при плохом дизайне и синхронизации потоков, контекст некоторых потоков может не переключаться вовсе(винда переключается всегда на тот поток, что готов к выполнению); в итоге поток никогда не получит управление.
Для NET всё работает неколько иначе, но думаю, близко в части "1000 потоков".

ППС. OleDbCommand имеет проперти CommandTimeout.
Аватара пользователя
aldep
Маньяк
Сообщения: 1593
Зарегистрирован: 18 фев 2003, 08:06
Откуда: Toronto
Контактная информация:

Сообщение aldep »

Marmot писал(а):Non-blocking IO (select etc) в native code с последующими callback-ами в .NET code...

ЗЫ

Не прямые callback-и а через queue конечно, тогда в идеале надо будет три(а то всего два) потока.
Один(.NET) ставит запрoсы в изходящую очередь, второй (native code) их посылает и ждёт ответов, когда ответ пришёл ставит их в входящую очередь, третий, снова .NET, обрабатывает ответы...
То ли я недопонял, то ли вы. :)
Есть API функция типа GetData(computer) (на самом деле эта функция из Windows Performance Library). Эта функция возвращает значение только когда получены данные, либо когда она решила (по одной ей ведомому алгоритму), что наступил timeout.
Без разницы, вызываю я ее из managed или native code, я все равно не могу сделать асинхронный вызов с callback'ом не создавая потока.
Библиотека не предоставляет callback'ов.
Аватара пользователя
aldep
Маньяк
Сообщения: 1593
Зарегистрирован: 18 фев 2003, 08:06
Откуда: Toronto
Контактная информация:

Re: Ищу паттерн (+)

Сообщение aldep »

ajkj3em писал(а): необходимость to hook system calls, которые вызывает вта библиотека. тоже не сложно, но надо возит'cя с VirtaulLock/Unlock, JMP shims вставлять и все такое.
Идея конечно интересная, но черезчур смелая. :-)
Аватара пользователя
aldep
Маньяк
Сообщения: 1593
Зарегистрирован: 18 фев 2003, 08:06
Откуда: Toronto
Контактная информация:

Сообщение aldep »

vg писал(а): Что-то типа этого работает и в задачах критичных по скорости и точности синхронизации по времени (точность около 100 ms). Типа близко к реал тайм.

ПС. По умолчанию winda выделяет 1 метр памяти под стек потока, поэтому попытка создать 100 вторичных потоков сразуже откусит больше 100 мегабайт памяти. Даже если ты (рядом у тебя пост про стек) укажешь, что стек потока, cкажем 64K, то это не поможет, посколькй при таком числе потоков и одном процессоре, всё будет в лучшем случае медленно делать вид, что, умирая, работает. В худшем случае, при плохом дизайне и синхронизации потоков, контекст некоторых потоков может не переключаться вовсе(винда переключается всегда на тот поток, что готов к выполнению); в итоге поток никогда не получит управление.
Для NET всё работает неколько иначе, но думаю, близко в части "1000 потоков".

ППС. OleDbCommand имеет проперти CommandTimeout.
При аккуратно написанном планировщике запросов, минимуме синхронизации и паре трюков 400 потоков работают, в меру нагружают процессор и аккуратно собирают данные. Работают с количеством компьютеров до 1000.
Но вот думаю, может можно как-то красивее сделать. :roll:

ПС Виндовый планировщик не допускает старвации потоков и повышает приоритет потока который долго не вызывался. Для линуксовый теоретически (я не спец в линуксе) такое может случится.

ППС Это не OleDB а PerfMon
Аватара пользователя
Leo Gan
Маньяк
Сообщения: 1764
Зарегистрирован: 29 апр 2005, 16:55
Откуда: где-то рядом с жёлтым карликом
Контактная информация:

Сообщение Leo Gan »

В некоторых случаях ответ на запрос откладывается и его приходится ждать долго, правильно я понял?

Стоит ли задача сделать процесс ожидания надежным? Если да...
то можно использовать Message Queue Server, есть такой у Майкрософт http://www.windowsitlibrary.com/Content/405/21/toc.html или, если есть возможность использовать WCF, то http://msdn2.microsoft.com/en-us/library/ms731089.aspx

Т.е.если ответа нет долго, то состояние запроса сбрасывается в Message Queue, где благополучано будет ждать ответа.

Можно пойти еще дальше и воспользоваться для этой ветви (работа с отложенными ответами) готовым решением: Microsoft BizTalk Server
Аватара пользователя
Marmot
Графоман
Сообщения: 39279
Зарегистрирован: 17 фев 2003, 17:58
Откуда: Caulfeild
Контактная информация:

Сообщение Marmot »

aldep писал(а):То ли я недопонял, то ли вы. :)
Оба тормозим
Я нарпример увидел эти фразу "Приложение будет написано под .НЕТ, а библиотека в native code, " и решил что библиотека только будет написана...
Аватара пользователя
aldep
Маньяк
Сообщения: 1593
Зарегистрирован: 18 фев 2003, 08:06
Откуда: Toronto
Контактная информация:

Сообщение aldep »

Leo Gan писал(а):В некоторых случаях ответ на запрос откладывается и его приходится ждать долго, правильно я понял?
Стоит ли задача сделать процесс ожидания надежным?
Нет. Если запрос ответ с опазаднием более 5 минут его вообще можно отбрасывать. Единственная причина почему это не делается по истечении 5 минут ожидания, это то что нельзя прервать unmanaged поток из managed кода.
то можно использовать Message Queue Server, есть такой у Майкрософт http://www.windowsitlibrary.com/Content/405/21/toc.html или, если есть возможность использовать WCF, то http://msdn2.microsoft.com/en-us/library/ms731089.aspx

Т.е.если ответа нет долго, то состояние запроса сбрасывается в Message Queue, где благополучано будет ждать ответа.

Можно пойти еще дальше и воспользоваться для этой ветви (работа с отложенными ответами) готовым решением: Microsoft BizTalk Server
У нас скорее задача, чтобы опращивать компьютеры в точный момент времени, надежность не так важна. Так что MSMQ тут не прокатит :-(
[/quote]
highlander
Зритель
Сообщения: 6
Зарегистрирован: 15 май 2006, 00:26

Re: Ищу паттерн (+)

Сообщение highlander »

aldep писал(а):Условие:
Центральный компьютер посылает запросы на компьютеры в локальной сетке, получает ответы и заносит их в БД. Библиотека, ответственная за обмен сообщениями не поддерживает асинхронные вызововы.
Запросы на каждый компьютер должны посылаться в точно заданное время (примерно с частотой раз в минуту) ответ должен приходить за доли секунды.
Это в идеале. На практике большинство компьютеров обычно действительно отвечают быстро, но часть тянет с ответом по многу секунд (в особо кривых случаях вплоть до часа). Причем в редких случаях доля западывающих компьютеров может достигать 90%.
Приложение будет написано под .НЕТ, а библиотека в native code, поэтому если она сама не возвращает по таймауту, то прервать ее нет никакой возможности.
Задача - сделать систему работающую в вышеописанных условиях и маштабируемую в пределах 10-3000 компьтеров. Т.е. до 50 запросов в секунду. Временная точность должна определятся параметрами соединения с компьютером т.е. если компьютер отвечает за доли секунды, то и точность посылки/принятия запроса должна быть 1-2 секунды в большинстве случаев.

Пока никаких идей, кроме thread pool с большим числом потоков в голову не приходит. Недостаток - в пиковом случае приходится создавать для приемлемой точности 1000 потоков.
Есть ли какие другие шаблоны для решения подобных проблем.
Вроде подобные условия применимы ко многим областям.



just send as much request as you want and poll/select on sockets. Try non-blocking read on all connections. The idea here is to have dynamic creating/destroying of TX-threads. At the last you can't guarantee RT behavior in non-rt environment (what if your network congested what you gonna do ,how will ensure 1-2s response/request). Quite frnakly your task definition is not accurate (IMHO) cheers
Аватара пользователя
aldep
Маньяк
Сообщения: 1593
Зарегистрирован: 18 фев 2003, 08:06
Откуда: Toronto
Контактная информация:

Сообщение aldep »

Try non-blocking read on all connections. The idea here is to have dynamic creating/destroying of TX-threads.
Я уже объяснял, что у меня нету возможности делать асинхронные вызовы. API не позволяет.


At the last you can't guarantee RT behavior in non-rt environment (what if your network congested what you gonna do ,how will ensure 1-2s response/request)
Еще раз. Естественно, задержки в сети совершенно не конторолируемы (это и есть проблема) и никто не собирается гарантировать время отклика. Что надо гарантировать, так это что запрос на компьютер уходит с точностью до пары секунд и пришедший ответ обрабатывается с такой же скоростью для числа запросов до 30 в секунду.
Quite frnakly your task definition is not accurate (IMHO) cheers
Да нет, все четко. Но спасибо за помощь.
highlander
Зритель
Сообщения: 6
Зарегистрирован: 15 май 2006, 00:26

Сообщение highlander »

aldep писал(а):
Try non-blocking read on all connections. The idea here is to have dynamic creating/destroying of TX-threads.
Я уже объяснял, что у меня нету возможности делать асинхронные вызовы. API не позволяет.


At the last you can't guarantee RT behavior in non-rt environment (what if your network congested what you gonna do ,how will ensure 1-2s response/request)
Еще раз. Естественно, задержки в сети совершенно не конторолируемы (это и есть проблема) и никто не собирается гарантировать время отклика. Что надо гарантировать, так это что запрос на компьютер уходит с точностью до пары секунд и пришедший ответ обрабатывается с такой же скоростью для числа запросов до 30 в секунду.
Quite frnakly your task definition is not accurate (IMHO) cheers
Да нет, все четко. Но спасибо за помощь.
You're very welcome

не то что бы не четко просто описание задачи не точно.

1. Характеристики сети (было упомянуто ) routers/switches средняя/пиковая нагрузка, bandwidth on congestion, congestion likelihood etc
2. Харктеристики сервера (scalable to schedule 1000+ requests, memory consumption and etc)


Согласно тому что я прочел думаю multicast / broadcast был бы идеальным решением.
(I'm not sure how much (how different from client to client) information you have to forward to clients)

I understand that in the given style of forum it is impossible to be precise and not to bore others but unfortunatelly the output function (e.g. solution)
has an as an argument which is input information.
cheers
Ответить