Pregunta

Después de configurar una ReferenceDataRequest, la envío a 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);

Normalmente, puedo tomar el mensaje de la cola, pero ahora me encuentro con la situación de que si estoy haciendo una serie de solicitudes en la misma ejecución de la aplicación (normalmente alrededor de la décima), veo un código < > TIMEOUT EventType

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

Estos se están haciendo en el mismo hilo, pero supongo que hay algo en algún punto a lo largo de la línea que estoy consumiendo y no lanzando.

¿Alguien tiene alguna pista o consejo?

No hay muchas referencias en SO a la API de BLP, pero es de esperar que podamos comenzar a rectificar esa situación.

¿Fue útil?

Solución 2

Realmente nunca pude resolver esta pregunta, pero sí encontramos una solución.

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

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

Lo que significa que una sesión opera en modo de suscripción, la otra de forma más sincrónica: creo que esta dualidad fue la raíz de nuestros problemas.

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

Otros consejos

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

Si realiza una solicitud de datos históricos diarios durante un período prolongado (que da como resultado 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 recuperar todos los eventos Básicamente, ¡no llame a NextEvent () en un objeto Session! Utilice un EventQueue dedicado en su lugar.

En lugar de hacer esto:

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

Haz esto:

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

Esto puede resultar en una mejora en el rendimiento, aunque se sabe que la API no es particularmente determinista ...

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

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

Me da vergüenza decir que uso el siguiente patrón (sospecho que se copió del código de ejemplo). Parece funcionar razonablemente robusto, pero probablemente ignora algunos mensajes importantes. Pero no entiendo tu problema de tiempo muerto. Es Java, pero todos los idiomas funcionan básicamente igual.

  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.

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

Parece que está haciendo demasiadas solicitudes a la vez. BB solo procesará un cierto número de solicitudes por conexión en un momento dado. Tenga en cuenta que abrir 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 mucho tiempo simultáneamente, algunas pueden agotar el tiempo de espera. Además, debe procesar la solicitud por completo (hasta que reciba el mensaje RESPUESTA) o cancelarla. Una solicitud parcial que está pendiente es desperdiciar un espacio. Dado que dividirse en dos sesiones parece haberle ayudado, parece que también está haciendo muchas solicitudes de suscripción al mismo tiempo. ¿Estás usando suscripciones como una forma de tomar instantáneas? Es decir, suscribirse a un instrumento, obtener valores iniciales y cancelar la suscripción. Si es así, debe intentar 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 suscripciones en lugar de hacer muchas solicitudes individuales. Espero que esto ayude con el uso de la API.

Por cierto, no puedo distinguir su código de muestra, pero mientras está bloqueado en los mensajes de la cola de eventos, ¿también está leyendo desde la cola de eventos principal mientras está (en una cola de eventos separada)? Debe procesar todos los mensajes fuera 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, por lo que puede estar agotando el tiempo de espera. Además, si no lee los mensajes, puede ser marcado como un consumidor lento y no recibir más datos hasta que comience a consumir los mensajes pendientes. La API es asíncrona. 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 está bien, y de lo contrario sería difícil interrumpir el flujo lógico para procesar partes de forma asincrónica.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top