2009-09-18 10 views
5

Después de haber establecido un ReferenceDataRequest lo envío junto a un EventQueueBloomberg solicitud de API tiempo de espera

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); 

Normalmente me puedo agarrar el mensaje de la cola, pero estoy golpeando la situación ahora que si estoy hacer una serie de peticiones en la misma ejecución de la aplicación (normalmente alrededor de la décima), veo un EventType TIMEOUT

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

Estos se realizan en el mismo hilo, pero estoy asumiendo que hay algo en algún lugar a lo largo de la línea que estoy consumiendo y no liberando.

¿Alguien tiene alguna pista o consejo?

No hay muchas referencias en SO a la API de BLP, pero esperamos poder comenzar a rectificar esa situación.

Respuesta

3

Realmente no llegué a resolver esta pregunta, pero encontramos una solución.

Basándonos en un comentario pequeño, aparentemente desechable, en la documentación de Server API, optamos por crear una segunda sesión. Una sesión es responsable de las solicitudes estáticas, la otra de tiempo real. p.ej.

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

Los medios una sesión opera en modo de suscripción, la otra más sincrónicamente - Creo que fue esta dualidad la que estaba en la raíz de nuestros problemas.

Desde hacer ese cambio, no hemos tenido ningún problema.

+0

Creo que el problema es que ahora está abriendo explícitamente el servicio antes de obtener la referencia. Usamos 'if (session.OpenService (BlpConstants.BLP_REF_DATA)) return session.GetService (BlpConstants.BLP_REF_DATA); else return null; 'mientras que su pregunta inicial no abrió el servicio primero –

0

Es bueno ver a otra persona en stackoverflow disfrutando del dolor de la API de Bloomberg :-)

me da vergüenza decir que utilizo el siguiente patrón (sospecho copiado del código de ejemplo). Parece funcionar de forma razonablemente sólida, pero probablemente ignore algunos mensajes importantes. Pero no entiendo tu problema de tiempo de espera. Es Java, pero todos los idiomas funcionan básicamente de la misma manera.

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; 
    } 
    } 

Esto puede funcionar porque consume todos los mensajes de cada evento.

+0

Gracias. Es una construcción muy similar (y le gusta el código de ejemplo): no hay mensajes no consumidos que pueda ver en llamadas anteriores a través de esta función. Si lo llamo solo una vez, está bien, pero está vomitando después de varias llamadas. Creo que podría estar relacionado con una suscripción concurrente a algunos campos de tiempo real, pero es bastante difícil de precisar ... – Unsliced

+0

¿está compartiendo la misma cola entre ref-data y market-data? Eso podría ser un problema. –

1

Mi lectura de los documentos acuerda que necesita sesiones separadas para los servicios "// blp/mktdata" y "// blp/refdata".

-1

Parece que está haciendo demasiadas solicitudes a la vez. BB solo procesará una cierta cantidad de solicitudes por conexión en un momento dado. Tenga en cuenta que la apertura de más y más conexiones no ayudará porque también hay límites por suscripción. Si realiza una gran cantidad de solicitudes que consumen tiempo al mismo tiempo, algunas pueden agotar el tiempo de espera. Además, debe procesar la solicitud por completo (hasta que reciba el mensaje de RESPUESTA) o cancelarla. Una solicitud parcial que está pendiente es perder un espacio. Debido a que dividirte en dos sesiones parece haber sido útil, parece que también estás haciendo muchas solicitudes de suscripción al mismo tiempo. ¿Estás utilizando suscripciones como una forma de tomar instantáneas? Eso es suscribirse a un instrumento, obtener valores iniciales y anular la suscripción. Si es así, deberías tratar de encontrar un diseño diferente. Esta no es la forma en que las suscripciones están destinadas a ser utilizadas. Una solicitud de suscripción pendiente también utiliza un espacio de solicitud. Es por eso que es mejor agrupar tantas suscripciones como sea posible en una sola lista de suscripción en lugar de realizar muchas solicitudes individuales. Espero que esto ayude con tu uso de la API.

-1

Por cierto, no puedo decirlo por su código de muestra, pero mientras está bloqueado en los mensajes de la cola de eventos, ¿también está leyendo desde la cola del evento principal mientras (en una cola de eventos separada)? Debe procesar todos los mensajes de la cola, especialmente si tiene suscripciones pendientes. Las respuestas pueden hacer cola muy rápido. Si no está procesando mensajes, la sesión puede alcanzar algunos límites de cola, que pueden ser los motivos por los que está expirando. Además, si no lee los mensajes, es posible que se marque como consumidor lento y no reciba más datos hasta que comience a consumir los mensajes pendientes. La API es asincrónica. Las colas de eventos son solo una forma de bloquear solicitudes específicas sin tener que procesar todos los mensajes de la cola principal en un contexto donde el bloqueo es correcto, y de lo contrario sería difícil interrumpir el flujo lógico para procesar partes de forma asíncrona.

0

Un cliente parece tener un problema similar. Lo resolví haciendo cientos de sesiones en lugar de pasar cientos de solicitudes en una sola sesión. Puede que Bloomberg no esté contento con este enfoque BFI (fuerza bruta e ignorancia) ya que estamos enviando las solicitudes de campo para cada sesión, pero funciona.

3

Solo quería compartir algo, gracias al código que incluyó en su publicación inicial.

Si realiza una solicitud de datos intradía históricos de larga duración (que genera muchos eventos generados por la API de Bloomberg), no utilice el patrón especificado en la documentación de la API, ya que puede hacer que su aplicación sea muy lenta para recuperar todos los eventos. Básicamente, no llame a NextEvent() en un objeto Session. Use un EventQueue dedicado en su lugar.

lugar de hacer esto:

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

Haga lo siguiente:

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

Esto puede dar lugar a alguna mejora el rendimiento, aunque el API es conocido por no ser particularmente determinista ...

Cuestiones relacionadas