Время ожидания запроса API Bloomberg
Установив 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
Тип события
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 ответов
Я действительно не удосужился решить этот вопрос, но мы нашли обходной путь.
Основываясь на небольшом, очевидно, однозначном комментарии в документации по API сервера, мы решили создать второй сеанс. Один сеанс отвечает за статические запросы, другой - в режиме реального времени. например
_marketDataSession.OpenService("//blp/mktdata");
_staticSession.OpenService("//blp/refdata");
Это означает, что один сеанс работает в режиме подписки, а другой - более синхронно - я думаю, что именно эта двойственность была в корне наших проблем.
С момента внесения этого изменения у нас не было никаких проблем.
Я просто хотел поделиться чем-то, благодаря коду, который вы включили в свой первый пост.
Если вы делаете запрос на исторические внутридневные данные в течение длительного периода времени (что приводит ко многим событиям, генерируемым 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 не является особенно детерминированным...
У клиента появилась похожая проблема. Я решил это путем создания сотен сеансов, а не передачи сотен запросов за один сеанс. Bloomberg может быть не в восторге от этого подхода BFI (грубая сила и невежество), поскольку мы отправляем полевые запросы для каждого сеанса, но он работает.
Мое чтение документации подтверждает, что вам нужны отдельные сессии для служб "//blp/mktdata" и "//blp/refdata".
Приятно видеть другого человека на stackru, наслаждающегося болью 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;
}
}
Это может работать, потому что он потребляет все сообщения от каждого события.
Кстати, я не могу сказать по вашему примеру кода, но хотя вы заблокированы сообщениями из очереди событий, вы тоже читаете из основной очереди событий в то время (в отдельной очереди событий)? Вы должны обработать все сообщения из очереди, особенно если у вас есть неподтвержденные подписки. Ответы могут стоять в очереди очень быстро. Если вы не обрабатываете сообщения, сеанс может превысить некоторые ограничения очереди, из-за чего вы можете получить тайм-ауты. Кроме того, если вы не читаете сообщения, вы можете быть помечены как медленный потребитель и не будете получать больше данных, пока не начнете использовать ожидающие сообщения. API является асинхронным. Очереди событий - это просто способ блокировать определенные запросы без необходимости обрабатывать все сообщения из основной очереди в контексте, где блокировка нормальная, и в противном случае было бы трудно прерывать логический поток для асинхронной обработки деталей.
Похоже, вы делаете слишком много запросов одновременно. BB будет обрабатывать только определенное количество запросов на соединение в любой момент времени. Обратите внимание, что открытие новых и новых подключений не поможет, так как существуют ограничения для каждой подписки. Если вы выполняете большое количество требующих много времени запросов одновременно, некоторые могут прерваться. Кроме того, вы должны полностью обработать запрос (до получения сообщения RESPONSE) или отменить его. Частичное требование, которое является невыполненным, - тратить слот. Поскольку разделение на две сессии, похоже, помогло вам, похоже, вы одновременно делаете много запросов на подписку. Используете ли вы подписки как способ сделать снимки? То есть подписаться на инструмент, получить начальные значения и отменить подписку. Если это так, вы должны попытаться найти другой дизайн. Это не способ, которым подписки предназначены для использования. Необработанный запрос на подписку также использует слот запроса. Вот почему лучше всего группировать как можно больше подписок в одном списке подписок, а не делать много отдельных запросов. Надеюсь, это поможет вам использовать API.