Здравствуйте, gandjustas, Вы писали:
U>>Если автор топика опишет задачу более конкретно, тогда можно будет сказать к чему она сводится.
G>Авто
Ты здесь недописал что-то?
U>>Если ты понял по другому, то напиши какое поведение требуется в таком-то случае и почему такое поведение нельзя реализовать через синхронайзер.
Re[23]: Good practice по алгоритмизации в условиях асинхронн
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, gandjustas, Вы писали:
U>>>Зачем переписывать код, если он и так работает прекрасно? G>>Ну это без нагрузки. Ты же рекомендуешь этот способ другим людям, а им может не хватить быстродействия.
U>Во-первых, задача автора топика явно не тот случай.
Явно тот, автотрейдинг работает под охренительными нагрузками.
U>Во-вторых, еще раз повторяю, добавление метода ForceTask позволяющего совмещать пробуждение потока по времени с пробуждением по событию никаких принципиальных переделок не требуется.
Чего? Движка или клиентского кода?
Re[25]: Good practice по алгоритмизации в условиях асинхронн
Здравствуйте, gandjustas, Вы писали:
U>>Во-первых, задача автора топика явно не тот случай. G>Явно тот, автотрейдинг работает под охренительными нагрузками.
Цены на сколько видов товаров надо отслеживать? Как часто изменяется цена на товар? Сколько занимает постановка и удаление заявки?
U>>Во-вторых, еще раз повторяю, добавление метода ForceTask позволяющего совмещать пробуждение потока по времени с пробуждением по событию никаких принципиальных переделок не требуется. G>Чего? Движка или клиентского кода?
В общем-то ни того, ни того. В движок надо добавить флажок IsForce в TaskWithTicks, метод ForceTask(Task task) в LabeledThread, метод ForceTask(Task task, string threadLabel) в TaskPull, проверку на IsCompleted перед вызовом taskWithTicks.Task.Execute в ThreadHandler и проверку на IsForce перед InsertTask там же. Работа на полчаса.
В клиентском коде нужно добавить в обработчики событий вызовы метода ForceTask, полагаю тоже в полчаса уложиться можно.
Re[26]: Good practice по алгоритмизации в условиях асинхронн
Здравствуйте, Undying, Вы писали:
U>В общем-то ни того, ни того. В движок надо добавить флажок IsForce в TaskWithTicks, метод ForceTask(Task task) в LabeledThread, метод ForceTask(Task task, string threadLabel) в TaskPull, проверку на IsCompleted перед вызовом taskWithTicks.Task.Execute в ThreadHandler и проверку на IsForce перед InsertTask там же. Работа на полчаса.
Хотя нет, я не прав, проблема, что у меня внутри асинхронного метода не будет ссылки на Task. Т.е. если пошаманить работать будет, а вот красивого решения пока что не вижу.
Re[25]: Good practice по алгоритмизации в условиях асинхронн
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, gandjustas, Вы писали:
U>>>Во-первых, задача автора топика явно не тот случай. G>>Явно тот, автотрейдинг работает под охренительными нагрузками.
U>Цены на сколько видов товаров надо отслеживать?
Самые тупые стратегии работают с одним, продвинутые — гораздо больше.
U>Как часто изменяется цена на товар?
Несколько раз в секунду — спокойно.
U>Сколько занимает постановка и удаление заявки?
Самая быстра покупка после выставления заявки была за 0.15 сек.
Иногда раунд-трип до сервера больше
U>>>Во-вторых, еще раз повторяю, добавление метода ForceTask позволяющего совмещать пробуждение потока по времени с пробуждением по событию никаких принципиальных переделок не требуется. G>>Чего? Движка или клиентского кода?
U>В общем-то ни того, ни того. В движок надо добавить флажок IsForce в TaskWithTicks, метод ForceTask(Task task) в LabeledThread, метод ForceTask(Task task, string threadLabel) в TaskPull, проверку на IsCompleted перед вызовом taskWithTicks.Task.Execute в ThreadHandler и проверку на IsForce перед InsertTask там же. Работа на полчаса.
U>В клиентском коде нужно добавить в обработчики событий вызовы метода ForceTask, полагаю тоже в полчаса уложиться можно.
Ну вот уже больше похоже на async enumerator
Вопрос номер два. Как дождаться двух событий?
Re[27]: Good practice по алгоритмизации в условиях асинхронн
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, gandjustas, Вы писали:
G>>А смысл? Read и Write выполняются синхронно.
U>Чтения блока естественно выполняется синхронно, а как оно еще может выполняться?
Асинхронно.
G>>Надо использовать BeginRead\EndRead, BeginWrite\EndWrite. U>Зачем? В чем будет преимущество?
В том что поток на время чтения не будет блокироваться.
U>Или тебе просто нужен пример кода, в котором об окончании операции оповещает callback? Тогда я вроде приводил: http://rsdn.ru/forum/design/3929522.1.aspx
G>Ну если строго определить последовательность событий и order одного типа может быть только один, то тогда задача вырождается в КА. Но реальные торговые системы (насколько я знаю) чуть посложнее и оперируют именно событиями на входе и действиями на выходе. Их тоже можно свести к КА, но состояний у него будет дофига и он точно не будет описываться линейным кодом.
Присоединяюсь к утверждению.
Мой пример всего лишь упрощение, чтобы не постить сюда горы кода.
В реальных стратегиях все сложнее и хочется освоить модель их описания и технологию реализации этой модели (в данном случае в .NET).
По поводу многопоточности, пока такой потребности нет. На данном этапе хочу работать с одной ниткой. Но в будущем скорее всего понадобится.
По поводу скоростей — действительно это запросто десятки событий в секунду.
Текущий итог по подпроблемам и возможным решениям:
1. Модель обработки.
Пока мне ближе всего модель "входные события" + "очередь реакций".
Причем реакция может быть "сложной", до своего завершения требовать прихода нескольких различных событий и отсылки ответных воздействий. Пример — реализация большого объема акций. На бирже такая заявка может не реализоваться за раз и будут приходить цепочки ответов, "реализовано N акций". Такая сложные реакция сама может внутри себя содержать свою очередь событий. Однако присутствовать в основной очереди реакций просто как отдельная реакция.
2. Технология реализации (на .NET):
2.1. Способ линейного описания кода, содержащего асинхронные операции
Как я понимаю, готового средства в .NET нет (?). Есть возможность использования IObservable возвращаемых значений в качестве возвращаемых значений асинхронных функций и описания того самого линейного (!) кода с помощью LINQ выражения. Тут есть сомнения в наглядности и читаемости. gandjustas, как считаешь? Другой вариант — библиотека, предлагаемая Undying. Еще есть что-то полезное в .NET 4. Еще враианты? Забить на линейность кода, оперировать цепочками callback'ов.
В общем-то вопрос по большей части открыт. В частности я не до конца уверен, что RX хорош именно как средство для 2.1, скорее для 2.2. Возможно не прав.
2.2. Способ задания логики "реакций".
Как вариант "реакции" подписываются на входные события и в обработчиках анализируют очередь (например, с помощью RX) и что-то творят с очередью. Выкидывают себя оттуда, например.
2.3. Возможность сериализации текущего состояния модели для восстановления работы после прерывания.
Вопрос пока совсем открыт.
Re[23]: Good practice по алгоритмизации в условиях асинхронн
Здравствуйте, sergunok, Вы писали:
S>2. Технология реализации (на .NET): S> 2.1. Способ линейного описания кода, содержащего асинхронные операции S> Как я понимаю, готового средства в .NET нет (?).
F# с его async, CCR, библиотека от Рихтера
Здравствуйте, Undying, Вы писали:
U>Хотя нет, я не прав, проблема, что у меня внутри асинхронного метода не будет ссылки на Task. Т.е. если пошаманить работать будет, а вот красивого решения пока что не вижу.
Изящное решение все же есть. Добавляем еще один вид Step:
class ServiceStep : WaitStep
{
public ServiceStep() : base(TimeSpan.Zero) {}
public void SetServiceInfo(LabeledThread thread, Task task);
public void ForceTask()
{
thread.ForceTask(task);
}
}
Т.е. получив в качестве результата такой Step, LabeledThread вызывает у него SetServiceInfo и передает ему ссылку на себя и на таску.
Здравствуйте, gandjustas, Вы писали:
U>>Цены на сколько видов товаров надо отслеживать? G>Самые тупые стратегии работают с одним, продвинутые — гораздо больше.
На нескольких десятков товаров особых проблем еще не будет, даже если их опрашивать с частотой в 10 мс. А вот если товаров будет хотя бы несколько тысяч, цена на них будет меняться относительно редко, но время отклика на изменение цены нужно будет минимальное, тогда да чисто временная модель больно много процессорного времени будет тратить в холостую. Совмещение временной модели с событийной тут будет гораздо лучше.
U>>В клиентском коде нужно добавить в обработчики событий вызовы метода ForceTask, полагаю тоже в полчаса уложиться можно. G>Ну вот уже больше похоже на async enumerator G>Вопрос номер два. Как дождаться двух событий?
В смысле двух событий? Продолжать выполнение только тогда, когда произошли оба события или что?
Re[27]: Good practice по алгоритмизации в условиях асинхронн
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, gandjustas, Вы писали:
U>>>Цены на сколько видов товаров надо отслеживать? G>>Самые тупые стратегии работают с одним, продвинутые — гораздо больше.
U>На нескольких десятков товаров особых проблем еще не будет, даже если их опрашивать с частотой в 10 мс. А вот если товаров будет хотя бы несколько тысяч, цена на них будет меняться относительно редко, но время отклика на изменение цены нужно будет минимальное, тогда да чисто временная модель больно много процессорного времени будет тратить в холостую. Совмещение временной модели с событийной тут будет гораздо лучше.
Именно это и лучше.
Кстати вообще стоит минимизировать время отклика для любых систем, потому что входящие запросы складываются в очередь (так или иначе) и при большом времени отклика в среднем очередь рано или поздно переполнится.
U>>>В клиентском коде нужно добавить в обработчики событий вызовы метода ForceTask, полагаю тоже в полчаса уложиться можно. G>>Ну вот уже больше похоже на async enumerator G>>Вопрос номер два. Как дождаться двух событий?
U>В смысле двух событий? Продолжать выполнение только тогда, когда произошли оба события или что?
Уже бесcмысленно, ты понял где слабое место TaskPull.
Re[23]: Good practice по алгоритмизации в условиях асинхронн
Здравствуйте, sergunok, Вы писали:
S>Текущий итог по подпроблемам и возможным решениям: S>1. Модель обработки. S> Пока мне ближе всего модель "входные события" + "очередь реакций".
Rx довольно успешно покрывает любую модель. TPL чуть хуже.
S> Причем реакция может быть "сложной", до своего завершения требовать прихода нескольких различных событий и отсылки ответных воздействий. Пример — реализация большого объема акций. На бирже такая заявка может не реализоваться за раз и будут приходить цепочки ответов, "реализовано N акций". Такая сложные реакция сама может внутри себя содержать свою очередь событий. Однако присутствовать в основной очереди реакций просто как отдельная реакция.
Видимо наоборот из нескольких событий "продано N акций" будет получаться событие "продан пакет акций". По факту никаких очередей не будет, буду асинхронные коллекции.
S>2. Технология реализации (на .NET): S> 2.1. Способ линейного описания кода, содержащего асинхронные операции S> Как я понимаю, готового средства в .NET нет (?).
TPL с Extras (с помощью итераторов), async в F# (монада).
S>Есть возможность использования IObservable возвращаемых значений в качестве возвращаемых значений асинхронных функций и описания того самого линейного (!) кода с помощью LINQ выражения.
Потому что LINQ тоже монада (синтаксический сахар для монад), но есть возможность также использовать итераторы. Пример
S>Тут есть сомнения в наглядности и читаемости. gandjustas, как считаешь?
Да, в отличие от F# и его computational expressions (читай async), выразительные способности LINQ гораздо ниже.
S>Другой вариант — библиотека, предлагаемая Undying. Еще есть что-то полезное в .NET 4. Еще враианты? Забить на линейность кода, оперировать цепочками callback'ов.
Абсолютно не вариант писать коллбеки, посмотри Мейера, он там детально про это рассказывает.
S>В общем-то вопрос по большей части открыт. В частности я не до конца уверен, что RX хорош именно как средство для 2.1, скорее для 2.2. Возможно не прав.
Rx одинаково хорош для всего, но надо иметь некоторую сноровку, поначалу мозг рвет.
S> 2.2. Способ задания логики "реакций". S> Как вариант "реакции" подписываются на входные события и в обработчиках анализируют очередь (например, с помощью RX) и что-то творят с очередью. Выкидывают себя оттуда, например.
Надо мудрствовать, тебе нужна функция IQueryable<T1> -> IQueryable<T2>, где T1 входные события, T2 — выходное состояние, возможно после выполнения некоторых действий. Оставайся в монаде и будет счастье.
S> 2.3. Возможность сериализации текущего состояния модели для восстановления работы после прерывания. S> Вопрос пока совсем открыт.
С помощью .Do комбинатора сохраняешь текущее состояние, а при старте приложение подсовываешь последнее сохраненное в качестве начального.
Re[6]: Good practice по алгоритмизации в условиях асинхронно
S>>Кстати, а вообще, касаемо Microsoft'овских рекомендаций, т.е. вот примерно такой способ (c RX и LINQ) MS и рекомендует для визуально синхронного описания по сути асинхронного кода? G>WF
советуешь его поизучать в контексте моих задач?
Re[6]: Good practice по алгоритмизации в условиях асинхронно
G>TPL с Extras (с помощью итераторов), async в F# (монада).
Где зрить про Extras?
G>Абсолютно не вариант писать коллбеки, посмотри Мейера, он там детально про это рассказывает.
В Twisted'е привык Только через некоторое время стал пользоваться его же "сахаром" с yield.
G>Надо мудрствовать, тебе нужна функция IQueryable<T1> -> IQueryable<T2>, где T1 входные события, T2 — выходное состояние, возможно после выполнения некоторых действий. Оставайся в монаде и будет счастье.
Кстати, что есть монада в данном контексте?
Re[24]: Good practice по алгоритмизации в условиях асинхронн
S>> Причем реакция может быть "сложной", до своего завершения требовать прихода нескольких различных событий и отсылки ответных воздействий. Пример — реализация большого объема акций. На бирже такая заявка может не реализоваться за раз и будут приходить цепочки ответов, "реализовано N акций". Такая сложные реакция сама может внутри себя содержать свою очередь событий. Однако присутствовать в основной очереди реакций просто как отдельная реакция. G>Видимо наоборот из нескольких событий "продано N акций" будет получаться событие "продан пакет акций". По факту никаких очередей не будет, буду асинхронные коллекции.
Про асинхронные коллекции — да.
В примере имею в виду, что действие может быть не атомарным, а многошаговым и высокоуровневым. Типа продавать до победного по рыночной цене.. И в основной очереди действий, например, захочется оперировать именно такими действиями. А каждое из них будет декомпозироваться на более мелкие шажки.