Ищу паттерн (+)
Правила форума
Пожалуйста, ознакомьтесь с правилами данного форума
Пожалуйста, ознакомьтесь с правилами данного форума
- aldep
- Маньяк
- Сообщения: 1593
- Зарегистрирован: 18 фев 2003, 08:06
- Откуда: Toronto
- Контактная информация:
Ищу паттерн (+)
Условие:
Центральный компьютер посылает запросы на компьютеры в локальной сетке, получает ответы и заносит их в БД. Библиотека, ответственная за обмен сообщениями не поддерживает асинхронные вызововы.
Запросы на каждый компьютер должны посылаться в точно заданное время (примерно с частотой раз в минуту) ответ должен приходить за доли секунды.
Это в идеале. На практике большинство компьютеров обычно действительно отвечают быстро, но часть тянет с ответом по многу секунд (в особо кривых случаях вплоть до часа). Причем в редких случаях доля западывающих компьютеров может достигать 90%.
Приложение будет написано под .НЕТ, а библиотека в native code, поэтому если она сама не возвращает по таймауту, то прервать ее нет никакой возможности.
Задача - сделать систему работающую в вышеописанных условиях и маштабируемую в пределах 10-3000 компьтеров. Т.е. до 50 запросов в секунду. Временная точность должна определятся параметрами соединения с компьютером т.е. если компьютер отвечает за доли секунды, то и точность посылки/принятия запроса должна быть 1-2 секунды в большинстве случаев.
Пока никаких идей, кроме thread pool с большим числом потоков в голову не приходит. Недостаток - в пиковом случае приходится создавать для приемлемой точности 1000 потоков.
Есть ли какие другие шаблоны для решения подобных проблем.
Вроде подобные условия применимы ко многим областям.
Центральный компьютер посылает запросы на компьютеры в локальной сетке, получает ответы и заносит их в БД. Библиотека, ответственная за обмен сообщениями не поддерживает асинхронные вызововы.
Запросы на каждый компьютер должны посылаться в точно заданное время (примерно с частотой раз в минуту) ответ должен приходить за доли секунды.
Это в идеале. На практике большинство компьютеров обычно действительно отвечают быстро, но часть тянет с ответом по многу секунд (в особо кривых случаях вплоть до часа). Причем в редких случаях доля западывающих компьютеров может достигать 90%.
Приложение будет написано под .НЕТ, а библиотека в native code, поэтому если она сама не возвращает по таймауту, то прервать ее нет никакой возможности.
Задача - сделать систему работающую в вышеописанных условиях и маштабируемую в пределах 10-3000 компьтеров. Т.е. до 50 запросов в секунду. Временная точность должна определятся параметрами соединения с компьютером т.е. если компьютер отвечает за доли секунды, то и точность посылки/принятия запроса должна быть 1-2 секунды в большинстве случаев.
Пока никаких идей, кроме thread pool с большим числом потоков в голову не приходит. Недостаток - в пиковом случае приходится создавать для приемлемой точности 1000 потоков.
Есть ли какие другие шаблоны для решения подобных проблем.
Вроде подобные условия применимы ко многим областям.
- Marmot
- Графоман
- Сообщения: 39279
- Зарегистрирован: 17 фев 2003, 17:58
- Откуда: Caulfeild
- Контактная информация:
Non-blocking IO (select etc) в native code с последующими callback-ами в .NET code...
ЗЫ
Не прямые callback-и а через queue конечно, тогда в идеале надо будет три(а то всего два) потока.
Один(.NET) ставит запрoсы в изходящую очередь, второй (native code) их посылает и ждёт ответов, когда ответ пришёл ставит их в входящую очередь, третий, снова .NET, обрабатывает ответы...
ЗЫ
Не прямые callback-и а через queue конечно, тогда в идеале надо будет три(а то всего два) потока.
Один(.NET) ставит запрoсы в изходящую очередь, второй (native code) их посылает и ждёт ответов, когда ответ пришёл ставит их в входящую очередь, третий, снова .NET, обрабатывает ответы...
- ajkj3em
- Маньяк
- Сообщения: 2063
- Зарегистрирован: 12 ноя 2006, 06:53
Re: Ищу паттерн (+)
то есть по сути - как навесить async wrapper на existing blocking code ?aldep писал(а): Есть ли какие другие шаблоны для решения подобных проблем.
Вроде подобные условия применимы ко многим областям.
"шаблонов" - два. первый ты назвал, это 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: Ищу паттерн (+)
Ндаа, месье знает толк в извращениях...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 вставлять и все такое.
ИМО легче сделать реверсинжениринг протоколу и имплементировать его самому...
-
- Маньяк
- Сообщения: 2803
- Зарегистрирован: 29 май 2003, 22:29
- Откуда: Магадан - Миссиссага
aldep,
Та архитектура, что описал вкратце Marmot, классическая и проверена многими.
ПС. По умолчанию winda выделяет 1 метр памяти под стек потока, поэтому попытка создать 100 вторичных потоков сразуже откусит больше 100 мегабайт памяти. Даже если ты (рядом у тебя пост про стек) укажешь, что стек потока, cкажем 64K, то это не поможет, посколькй при таком числе потоков и одном процессоре, всё будет в лучшем случае медленно делать вид, что, умирая, работает. В худшем случае, при плохом дизайне и синхронизации потоков, контекст некоторых потоков может не переключаться вовсе(винда переключается всегда на тот поток, что готов к выполнению); в итоге поток никогда не получит управление.
Для NET всё работает неколько иначе, но думаю, близко в части "1000 потоков".
ППС. OleDbCommand имеет проперти CommandTimeout.
Та архитектура, что описал вкратце Marmot, классическая и проверена многими.
Что-то типа этого работает и в задачах критичных по скорости и точности синхронизации по времени (точность около 100 ms). Типа близко к реал тайм.Marmot писал(а):Non-blocking IO (select etc) в native code с последующими callback-ами в .NET code...
ЗЫ
Не прямые callback-и а через queue конечно, тогда в идеале надо будет три(а то всего два) потока.
Один(.NET) ставит запрoсы в изходящую очередь, второй (native code) их посылает и ждёт ответов, когда ответ пришёл ставит их в входящую очередь, третий, снова .NET, обрабатывает ответы...
ПС. По умолчанию winda выделяет 1 метр памяти под стек потока, поэтому попытка создать 100 вторичных потоков сразуже откусит больше 100 мегабайт памяти. Даже если ты (рядом у тебя пост про стек) укажешь, что стек потока, cкажем 64K, то это не поможет, посколькй при таком числе потоков и одном процессоре, всё будет в лучшем случае медленно делать вид, что, умирая, работает. В худшем случае, при плохом дизайне и синхронизации потоков, контекст некоторых потоков может не переключаться вовсе(винда переключается всегда на тот поток, что готов к выполнению); в итоге поток никогда не получит управление.
Для NET всё работает неколько иначе, но думаю, близко в части "1000 потоков".
ППС. OleDbCommand имеет проперти CommandTimeout.
- aldep
- Маньяк
- Сообщения: 1593
- Зарегистрирован: 18 фев 2003, 08:06
- Откуда: Toronto
- Контактная информация:
То ли я недопонял, то ли вы.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: Ищу паттерн (+)
Идея конечно интересная, но черезчур смелая.ajkj3em писал(а): необходимость to hook system calls, которые вызывает вта библиотека. тоже не сложно, но надо возит'cя с VirtaulLock/Unlock, JMP shims вставлять и все такое.

- aldep
- Маньяк
- Сообщения: 1593
- Зарегистрирован: 18 фев 2003, 08:06
- Откуда: Toronto
- Контактная информация:
При аккуратно написанном планировщике запросов, минимуме синхронизации и паре трюков 400 потоков работают, в меру нагружают процессор и аккуратно собирают данные. Работают с количеством компьютеров до 1000.vg писал(а): Что-то типа этого работает и в задачах критичных по скорости и точности синхронизации по времени (точность около 100 ms). Типа близко к реал тайм.
ПС. По умолчанию winda выделяет 1 метр памяти под стек потока, поэтому попытка создать 100 вторичных потоков сразуже откусит больше 100 мегабайт памяти. Даже если ты (рядом у тебя пост про стек) укажешь, что стек потока, cкажем 64K, то это не поможет, посколькй при таком числе потоков и одном процессоре, всё будет в лучшем случае медленно делать вид, что, умирая, работает. В худшем случае, при плохом дизайне и синхронизации потоков, контекст некоторых потоков может не переключаться вовсе(винда переключается всегда на тот поток, что готов к выполнению); в итоге поток никогда не получит управление.
Для NET всё работает неколько иначе, но думаю, близко в части "1000 потоков".
ППС. OleDbCommand имеет проперти CommandTimeout.
Но вот думаю, может можно как-то красивее сделать.

ПС Виндовый планировщик не допускает старвации потоков и повышает приоритет потока который долго не вызывался. Для линуксовый теоретически (я не спец в линуксе) такое может случится.
ППС Это не OleDB а PerfMon
- Leo Gan
- Маньяк
- Сообщения: 1764
- Зарегистрирован: 29 апр 2005, 16:55
- Откуда: где-то рядом с жёлтым карликом
- Контактная информация:
В некоторых случаях ответ на запрос откладывается и его приходится ждать долго, правильно я понял?
Стоит ли задача сделать процесс ожидания надежным? Если да...
то можно использовать 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
Стоит ли задача сделать процесс ожидания надежным? Если да...
то можно использовать 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
- Контактная информация:
- aldep
- Маньяк
- Сообщения: 1593
- Зарегистрирован: 18 фев 2003, 08:06
- Откуда: Toronto
- Контактная информация:
Leo Gan писал(а):В некоторых случаях ответ на запрос откладывается и его приходится ждать долго, правильно я понял?
Нет. Если запрос ответ с опазаднием более 5 минут его вообще можно отбрасывать. Единственная причина почему это не делается по истечении 5 минут ожидания, это то что нельзя прервать unmanaged поток из managed кода.Стоит ли задача сделать процесс ожидания надежным?
У нас скорее задача, чтобы опращивать компьютеры в точный момент времени, надежность не так важна. Так что MSMQ тут не прокатитто можно использовать 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

[/quote]
-
- Зритель
- Сообщения: 6
- Зарегистрирован: 15 май 2006, 00:26
Re: Ищу паттерн (+)
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
- Контактная информация:
Я уже объяснял, что у меня нету возможности делать асинхронные вызовы. API не позволяет.Try non-blocking read on all connections. The idea here is to have dynamic creating/destroying of TX-threads.
Еще раз. Естественно, задержки в сети совершенно не конторолируемы (это и есть проблема) и никто не собирается гарантировать время отклика. Что надо гарантировать, так это что запрос на компьютер уходит с точностью до пары секунд и пришедший ответ обрабатывается с такой же скоростью для числа запросов до 30 в секунду.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
-
- Зритель
- Сообщения: 6
- Зарегистрирован: 15 май 2006, 00:26
You're very welcomealdep писал(а):Я уже объяснял, что у меня нету возможности делать асинхронные вызовы. API не позволяет.Try non-blocking read on all connections. The idea here is to have dynamic creating/destroying of TX-threads.
Еще раз. Естественно, задержки в сети совершенно не конторолируемы (это и есть проблема) и никто не собирается гарантировать время отклика. Что надо гарантировать, так это что запрос на компьютер уходит с точностью до пары секунд и пришедший ответ обрабатывается с такой же скоростью для числа запросов до 30 в секунду.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
не то что бы не четко просто описание задачи не точно.
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