6 Stimmen

Zeitüberschreitung bei Bloomberg API-Anfrage

Nachdem ich eine ReferenceDataRequest eingerichtet habe, sende ich sie an eine EventQueue weiter

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

Normalerweise kann ich die Nachricht aus der Warteschlange abrufen, aber ich stoße jetzt auf die Situation, dass ich, wenn ich eine Reihe von Anfragen im selben Durchlauf der App mache (normalerweise um den zehnten), eine TIMEOUT EreignisTyp

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

Diese werden im selben Thread gemacht, aber ich nehme an, dass ich irgendwo etwas verbrauche und nicht freigebe.

Hat jemand irgendwelche Hinweise oder Ratschläge?

Auf SO gibt es nicht viele Verweise auf die BLP-API, aber wir hoffen, dass wir diese Situation langsam ändern können.

6voto

Erwin Mayer Punkte 16992

Ich wollte Ihnen nur etwas mitteilen, dank des Codes, den Sie in Ihrem ersten Posting angegeben haben.

Wenn Sie historische Intraday-Daten für eine lange Zeitspanne abfragen (was dazu führt, dass viele Ereignisse von der Bloomberg-API generiert werden), sollten Sie nicht das in der API-Dokumentation angegebene Muster verwenden, da dies dazu führen kann, dass Ihre Anwendung beim Abrufen aller Ereignisse sehr langsam wird. Grundsätzlich sollten Sie NextEvent() nicht auf einem Session-Objekt aufrufen! Verwenden Sie stattdessen eine eigene EventQueue.

Anstatt dies zu tun:

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

Tun Sie dies:

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

Dies kann zu einer gewissen Leistungssteigerung führen, obwohl die API bekanntermaßen nicht besonders deterministisch ist...

4voto

Unsliced Punkte 10135

Ich bin nicht wirklich dazu gekommen, diese Frage zu lösen, aber wir haben einen Ausweg gefunden.

Aufgrund eines kleinen, scheinbar unbedeutenden Kommentars in der Server-API-Dokumentation haben wir uns dafür entschieden, eine zweite Sitzung zu erstellen. Eine Sitzung ist für statische Anfragen zuständig, die andere für Echtzeitanfragen, z.B.

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

Das bedeutet, dass die eine Sitzung im Abonnementmodus arbeitet, die andere eher synchron - ich denke, dass diese Dualität die Ursache für unsere Probleme war.

Seitdem wir diese Änderung vorgenommen haben, hatten wir keine Probleme mehr.

1voto

Phil Smyth Punkte 91

Nach meiner Lektüre der Dokumentation benötigen Sie separate Sitzungen für die Dienste "//blp/mktdata" und "//blp/refdata".

1voto

Tony Toews Punkte 7760

Ein Kunde schien ein ähnliches Problem zu haben. Ich löste es, indem ich Hunderte von Sitzungen durchführte, anstatt Hunderte von Anfragen in einer Sitzung zu übermitteln. Bloomberg mag mit diesem BFI-Ansatz (Brute Force and Ignorance) nicht zufrieden sein, da wir die Feldanforderungen für jede Sitzung senden, aber es funktioniert.

0voto

Nick Fortescue Punkte 41671

Schön zu sehen, dass eine weitere Person auf Stackoverflow die Schmerzen der Bloomberg API genießt :-)

Ich schäme mich zu sagen, dass ich das folgende Muster verwende (ich vermute, ich habe es aus dem Beispielcode kopiert). Es scheint einigermaßen stabil zu funktionieren, ignoriert aber wahrscheinlich einige wichtige Meldungen. Aber ich verstehe Ihr Timeout-Problem nicht. Es ist Java, aber alle Sprachen funktionieren im Grunde gleich.

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

Dies kann funktionieren, weil es alle Nachrichten von jedem Ereignis verbraucht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X