Время ожидания запроса API Bloomberg - PullRequest
5 голосов
/ 18 сентября 2009

Установив ReferenceDataRequest, я отправляю его в EventQueue

Service refdata = _session.GetService("//blp/refdata");
Request request = refdata.CreateRequest("ReferenceDataRequest");
// append the appropriate symbol and field data to the request
EventQueue eventQueue = new EventQueue();
Guid guid = Guid.NewGuid();
CorrelationID id = new CorrelationID(guid);
_session.SendRequest(request, eventQueue, id);
long _eventWaitTimeout = 60000;
myEvent = eventQueue.NextEvent(_eventWaitTimeout);

Обычно я могу получить сообщение из очереди, но теперь я попадаю в ситуацию, когда при выполнении одного и того же запуска приложения (обычно около десятого) я делаю несколько запросов, я вижу TIMEOUT EventType

if (myEvent.Type == Event.EventType.TIMEOUT)
    throw new Exception("Timed Out - need to rethink this strategy");
else
    msg = myEvent.GetMessages().First();

Они сделаны в одном и том же потоке, но я предполагаю, что где-то на линии есть что-то, что я потребляю и не выпускаю.

У кого-нибудь есть подсказки или совет?

В SO мало ссылок на API BLP, но, надеюсь, мы сможем исправить эту ситуацию.

Ответы [ 7 ]

4 голосов
/ 25 мая 2011

Я просто хотел поделиться чем-то, благодаря коду, который вы включили в свой первоначальный пост.

Если вы делаете запрос на исторические внутридневные данные в течение длительного периода времени (что приводит ко многим событиям, генерируемым Bloomberg API), не используйте шаблон, указанный в документации API, поскольку это может привести к тому, что ваше приложение будет очень медленным получить все события. По сути, не вызывайте NextEvent () для объекта Session! Вместо этого используйте выделенный EventQueue.

Вместо этого:

var cID = new CorrelationID(1);
session.SendRequest(request, cID);
do {
   Event eventObj = session.NextEvent();
   ...
}

Сделайте это:

var cID = new CorrelationID(1);
var eventQueue = new EventQueue();
session.SendRequest(request, eventQueue, cID);
do {
   Event eventObj = eventQueue.NextEvent();
   ...
}

Это может привести к некоторому улучшению производительности, хотя известно, что API не является особенно детерминированным ...

3 голосов
/ 24 ноября 2009

Я действительно не удосужился решить этот вопрос, но мы нашли обходной путь.

Исходя из небольшого, очевидно, однозначного комментария в документации по API сервера, мы решили создать второй сеанс. Один сеанс отвечает за статические запросы, другой - в режиме реального времени. например

_marketDataSession.OpenService("//blp/mktdata"); 
_staticSession.OpenService("//blp/refdata");

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

После внесения этого изменения у нас не было никаких проблем.

1 голос
/ 02 декабря 2009

Мое чтение документов подтверждает, что вам нужны отдельные сессии для служб "// blp / mktdata" и "// blp / refdata".

0 голосов
/ 01 августа 2010

У клиента возникла похожая проблема. Я решил эту проблему, создав сотни сеансов, а не передавая сотни запросов за один сеанс. Bloomberg может быть не в восторге от этого подхода BFI (грубая сила и невежество), поскольку мы отправляем полевые запросы для каждой сессии, но он работает.

0 голосов
/ 15 декабря 2009

Кстати, я не могу сказать по вашему примеру кода, но, хотя вы заблокированы сообщениями из очереди событий, вы также читаете из основной очереди событий в то время (в отдельной очереди событий)? Вы должны обработать все сообщения из очереди, особенно если у вас есть неподтвержденные подписки. Ответы могут стоять в очереди очень быстро. Если вы не обрабатываете сообщения, сеанс может превысить некоторые ограничения очереди, из-за чего вы можете получить тайм-ауты. Кроме того, если вы не читаете сообщения, вы можете быть помечены как медленный потребитель и не будете получать больше данных, пока не начнете использовать ожидающие сообщения. API является асинхронным. Очереди событий - это просто способ блокировать определенные запросы без необходимости обрабатывать все сообщения из главной очереди в контексте, где блокировка нормальная, и в противном случае было бы трудно прерывать логический поток для асинхронной обработки деталей.

0 голосов
/ 14 декабря 2009

Похоже, вы делаете слишком много запросов одновременно. BB будет обрабатывать только определенное количество запросов на соединение в любой момент времени. Обратите внимание, что открытие новых и новых подключений не поможет, так как существуют ограничения для каждой подписки. Если вы выполняете большое количество требующих много времени запросов одновременно, некоторые могут прерваться. Кроме того, вы должны полностью обработать запрос (до получения сообщения RESPONSE) или отменить его. Частичный запрос, который является невыполненным, тратит впустую слот. Поскольку разделение на две сессии, похоже, помогло вам, похоже, вы одновременно делаете много запросов на подписку. Используете ли вы подписки как способ сделать снимки? То есть подписаться на инструмент, получить начальные значения и отменить подписку. Если это так, вы должны попытаться найти другой дизайн. Это не способ, которым подписки предназначены для использования. В невыполненном запросе на подписку также используется слот запроса. Вот почему лучше всего группировать как можно больше подписок в одном списке подписок, а не делать много отдельных запросов. Надеюсь, это поможет вам использовать API.

0 голосов
/ 18 сентября 2009

Приятно видеть другого человека на stackoverflow, наслаждающегося болью API Bloomberg: -)

Мне стыдно сказать, что я использую следующий шаблон (подозреваю, что скопирован из примера кода). Кажется, он работает достаточно надежно, но, вероятно, игнорирует некоторые важные сообщения. Но у меня нет твоей проблемы с тайм-аутом. Это Java, но все языки работают в основном одинаково.

  cid = session.sendRequest(request, null);
  while (true) {
    Event event = session.nextEvent();
    MessageIterator msgIter = event.messageIterator();
    while (msgIter.hasNext()) {
      Message msg = msgIter.next();
      if (msg.correlationID() == cid) {
        processMessage(msg, fieldStrings, result);
      }
    }
    if (event.eventType() == Event.EventType.RESPONSE) {
      break;
    }
  }

Это может сработать, поскольку оно потребляет все сообщения от каждого события.

...