Re[24]: Good practice по алгоритмизации в условиях асинхронн
От: Undying Россия  
Дата: 24.08.10 11:15
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>
G>public static void CopyTo(this Stream source, Stream dest, int bufferSize = 1024)
G>{
G>    var buffer = new byte[bufferSize];
G>    int bytesRead = 0;
G>    while((bytesRead = source.Read(buffer,0,bufferSize)) > 0)
G>    {
G>        dest.Write(buffer,0,bytesRead);
G>    }
G>}
G>


G>Вот такой код, только в асинхронном варианте.


public static IEnumerable<Step>(this Stream source, Stream dest, int bufferSize)
{
   byte[] buffer = new byte[bufferSize];
   int bytesRead = 0;
   while((bytesRead = source.Read(buffer, 0, bufferSize)) > 0)
   {
     dest.Write(buffer, 0, bytesRead);
     yield return new WaitStep(TimeSpan.Zero);
   }
   yield return new FinishStep(true);
}
Re[24]: Good practice по алгоритмизации в условиях асинхронн
От: Undying Россия  
Дата: 24.08.10 11:30
Оценка:
Здравствуйте, gandjustas, Вы писали:

U>>Если автор топика опишет задачу более конкретно, тогда можно будет сказать к чему она сводится.


G>Авто


Ты здесь недописал что-то?

U>>Если ты понял по другому, то напиши какое поведение требуется в таком-то случае и почему такое поведение нельзя реализовать через синхронайзер.
Re[23]: Good practice по алгоритмизации в условиях асинхронн
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.08.10 11:31
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, gandjustas, Вы писали:


U>>>Зачем переписывать код, если он и так работает прекрасно?

G>>Ну это без нагрузки. Ты же рекомендуешь этот способ другим людям, а им может не хватить быстродействия.

U>Во-первых, задача автора топика явно не тот случай.

Явно тот, автотрейдинг работает под охренительными нагрузками.

U>Во-вторых, еще раз повторяю, добавление метода ForceTask позволяющего совмещать пробуждение потока по времени с пробуждением по событию никаких принципиальных переделок не требуется.

Чего? Движка или клиентского кода?
Re[25]: Good practice по алгоритмизации в условиях асинхронн
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.08.10 11:38
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, gandjustas, Вы писали:


G>>
G>>public static void CopyTo(this Stream source, Stream dest, int bufferSize = 1024)
G>>{
G>>    var buffer = new byte[bufferSize];
G>>    int bytesRead = 0;
G>>    while((bytesRead = source.Read(buffer,0,bufferSize)) > 0)
G>>    {
G>>        dest.Write(buffer,0,bytesRead);
G>>    }
G>>}
G>>


G>>Вот такой код, только в асинхронном варианте.


U>
U>public static IEnumerable<Step>(this Stream source, Stream dest, int bufferSize)
U>{
U>   byte[] buffer = new byte[bufferSize];
U>   int bytesRead = 0;
U>   while((bytesRead = source.Read(buffer, 0, bufferSize)) > 0)
U>   {
U>     dest.Write(buffer, 0, bytesRead);
U>     yield return new WaitStep(TimeSpan.Zero);
U>   }
U>   yield return new FinishStep(true);
U>}
U>


А смысл? Read и Write выполняются синхронно. Надо использовать BeginRead\EndRead, BeginWrite\EndWrite.
Re[24]: Good practice по алгоритмизации в условиях асинхронн
От: Undying Россия  
Дата: 24.08.10 11:48
Оценка:
Здравствуйте, 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 Россия  
Дата: 24.08.10 11:52
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>А смысл? Read и Write выполняются синхронно.


Чтения блока естественно выполняется синхронно, а как оно еще может выполняться?

G>Надо использовать BeginRead\EndRead, BeginWrite\EndWrite.


Зачем? В чем будет преимущество?

Или тебе просто нужен пример кода, в котором об окончании операции оповещает callback? Тогда я вроде приводил: http://rsdn.ru/forum/design/3929522.1.aspx
Автор: Undying
Дата: 23.08.10
Re[25]: Good practice по алгоритмизации в условиях асинхронн
От: Undying Россия  
Дата: 24.08.10 11:54
Оценка: 6 (1)
Здравствуйте, 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 по алгоритмизации в условиях асинхронн
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.08.10 12:04
Оценка: 3 (1)
Здравствуйте, 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 по алгоритмизации в условиях асинхронн
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.08.10 12:06
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, gandjustas, Вы писали:


G>>А смысл? Read и Write выполняются синхронно.


U>Чтения блока естественно выполняется синхронно, а как оно еще может выполняться?

Асинхронно.

G>>Надо использовать BeginRead\EndRead, BeginWrite\EndWrite.

U>Зачем? В чем будет преимущество?
В том что поток на время чтения не будет блокироваться.

U>Или тебе просто нужен пример кода, в котором об окончании операции оповещает callback? Тогда я вроде приводил: http://rsdn.ru/forum/design/3929522.1.aspx
Автор: Undying
Дата: 23.08.10

Интересует все вместе.
Re[22]: Good practice по алгоритмизации в условиях асинхронн
От: sergunok  
Дата: 24.08.10 12:44
Оценка:
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 по алгоритмизации в условиях асинхронн
От: cadet354 Россия
Дата: 24.08.10 13:31
Оценка:
Здравствуйте, sergunok, Вы писали:

S>2. Технология реализации (на .NET):

S> 2.1. Способ линейного описания кода, содержащего асинхронные операции
S> Как я понимаю, готового средства в .NET нет (?).
F# с его async, CCR, библиотека от Рихтера
... << RSDN@Home 1.2.0 alpha 4 rev. 1270>>
Re[26]: Все же изящное решение есть
От: Undying Россия  
Дата: 24.08.10 14:05
Оценка:
Здравствуйте, 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 и передает ему ссылку на себя и на таску.

Использование выглядит так:

IEnumerable<Step> TicketChecker(Context context, Ticket ticket)
{
  ServiceStep serviceStep = new ServiceStep();
  yield return serviceStep;

  double currentPrice = ticket.CurrentPrice;
  double newPrice = currentPrice;
  ticket.PriceChanged += delegate(double price)
  {
    newPrice = price;
    serviceStep.ForceTask();
  }

  while(context.IsRunning)
  {
    // Создание, удаление заявок и прочая бизнес-логика

    yield return new WaitStep(TimeSpan.FromMinutes(1), delegate { return newPrice != currentPrice || !context.IsRunning; });
  }
}


Соответственно получаем возможность с легкостью комбинировать событийную и временную модель пробуждения потоков, используя их сильные стороны.
Re[26]: Good practice по алгоритмизации в условиях асинхронн
От: Undying Россия  
Дата: 24.08.10 14:15
Оценка:
Здравствуйте, gandjustas, Вы писали:

U>>Цены на сколько видов товаров надо отслеживать?

G>Самые тупые стратегии работают с одним, продвинутые — гораздо больше.

На нескольких десятков товаров особых проблем еще не будет, даже если их опрашивать с частотой в 10 мс. А вот если товаров будет хотя бы несколько тысяч, цена на них будет меняться относительно редко, но время отклика на изменение цены нужно будет минимальное, тогда да чисто временная модель больно много процессорного времени будет тратить в холостую. Совмещение временной модели с событийной тут будет гораздо лучше.

U>>В клиентском коде нужно добавить в обработчики событий вызовы метода ForceTask, полагаю тоже в полчаса уложиться можно.

G>Ну вот уже больше похоже на async enumerator
G>Вопрос номер два. Как дождаться двух событий?

В смысле двух событий? Продолжать выполнение только тогда, когда произошли оба события или что?
Re[27]: Good practice по алгоритмизации в условиях асинхронн
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.08.10 17:22
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, gandjustas, Вы писали:


U>>>Цены на сколько видов товаров надо отслеживать?

G>>Самые тупые стратегии работают с одним, продвинутые — гораздо больше.

U>На нескольких десятков товаров особых проблем еще не будет, даже если их опрашивать с частотой в 10 мс. А вот если товаров будет хотя бы несколько тысяч, цена на них будет меняться относительно редко, но время отклика на изменение цены нужно будет минимальное, тогда да чисто временная модель больно много процессорного времени будет тратить в холостую. Совмещение временной модели с событийной тут будет гораздо лучше.

Именно это и лучше.
Кстати вообще стоит минимизировать время отклика для любых систем, потому что входящие запросы складываются в очередь (так или иначе) и при большом времени отклика в среднем очередь рано или поздно переполнится.


U>>>В клиентском коде нужно добавить в обработчики событий вызовы метода ForceTask, полагаю тоже в полчаса уложиться можно.

G>>Ну вот уже больше похоже на async enumerator
G>>Вопрос номер два. Как дождаться двух событий?

U>В смысле двух событий? Продолжать выполнение только тогда, когда произошли оба события или что?

Уже бесcмысленно, ты понял где слабое место TaskPull.
Re[23]: Good practice по алгоритмизации в условиях асинхронн
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.08.10 18:01
Оценка:
Здравствуйте, 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 тоже монада (синтаксический сахар для монад), но есть возможность также использовать итераторы.
Пример
Автор: gandjustas
Дата: 24.08.10


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 по алгоритмизации в условиях асинхронно
От: sergunok  
Дата: 24.08.10 18:22
Оценка:
S>>Кстати, а вообще, касаемо Microsoft'овских рекомендаций, т.е. вот примерно такой способ (c RX и LINQ) MS и рекомендует для визуально синхронного описания по сути асинхронного кода?
G>WF

советуешь его поизучать в контексте моих задач?
Re[6]: Good practice по алгоритмизации в условиях асинхронно
От: sergunok  
Дата: 24.08.10 18:23
Оценка:
И аналогичный вопрос по F#.. Смотреть или нет? Или таки копать больше RX?
Re[7]: Good practice по алгоритмизации в условиях асинхронно
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.08.10 18:25
Оценка:
Здравствуйте, sergunok, Вы писали:

S>И аналогичный вопрос по F#.. Смотреть или нет? Или таки копать больше RX?


Смотреть все надо.
RX кстати можно использовать в F#.
Re[24]: Good practice по алгоритмизации в условиях асинхронн
От: sergunok  
Дата: 24.08.10 18:27
Оценка:
G>TPL с Extras (с помощью итераторов), async в F# (монада).
Где зрить про Extras?

G>Абсолютно не вариант писать коллбеки, посмотри Мейера, он там детально про это рассказывает.

В Twisted'е привык Только через некоторое время стал пользоваться его же "сахаром" с yield.

G>Надо мудрствовать, тебе нужна функция IQueryable<T1> -> IQueryable<T2>, где T1 входные события, T2 — выходное состояние, возможно после выполнения некоторых действий. Оставайся в монаде и будет счастье.

Кстати, что есть монада в данном контексте?
Re[24]: Good practice по алгоритмизации в условиях асинхронн
От: sergunok  
Дата: 24.08.10 18:30
Оценка:
S>> Причем реакция может быть "сложной", до своего завершения требовать прихода нескольких различных событий и отсылки ответных воздействий. Пример — реализация большого объема акций. На бирже такая заявка может не реализоваться за раз и будут приходить цепочки ответов, "реализовано N акций". Такая сложные реакция сама может внутри себя содержать свою очередь событий. Однако присутствовать в основной очереди реакций просто как отдельная реакция.
G>Видимо наоборот из нескольких событий "продано N акций" будет получаться событие "продан пакет акций". По факту никаких очередей не будет, буду асинхронные коллекции.
Про асинхронные коллекции — да.

В примере имею в виду, что действие может быть не атомарным, а многошаговым и высокоуровневым. Типа продавать до победного по рыночной цене.. И в основной очереди действий, например, захочется оперировать именно такими действиями. А каждое из них будет декомпозироваться на более мелкие шажки.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.