Datenbankabfrage mit reaktiven Erweiterungen

8

Ich muss eine Datenbank zeitnah abfragen, um den Status eines Altsystems zu kennen. Ich habe daran gedacht, die Abfrage um ein Observable zu wickeln, aber ich weiß nicht, wie ich das richtig machen soll.

Im Grunde wird es alle fünf Sekunden dieselbe Abfrage sein. Aber ich fürchte, ich muss mich diesen Problemen stellen:

  • Was passiert, wenn die Ausführung der Abfrage 10 Sekunden dauert? Ich will nicht Führe eine neue Abfrage aus, wenn die vorherige noch verarbeitet wird.
  • Außerdem sollte es eine Zeitüberschreitung geben. Wenn die aktuelle Abfrage nicht ausgeführt wird Nach beispielsweise 20 Sekunden sollte eine informative Nachricht sein protokolliert und ein neuer Versuch (die gleiche Abfrage) sollte gesendet werden.

Zusätzliche Details:

  • Die Abfrage ist nur ein SELECT , das ein Dataset mit einer Liste von Statuscodes ( working , faulted ) zurückgibt.
  • Die Observable-Sequenz nimmt immer die neuesten Daten, die von der Abfrage empfangen werden, ähnlich wie die Switch-Erweiterungsmethode.
  • Ich möchte die Datenbankabfrage (lange Operation) in eine Aufgabe einfügen, aber ich bin mir nicht sicher, ob es die beste Option ist.

Ich bin mir fast sicher, dass die Abfrage in einem anderen Thread ausgeführt werden sollte, aber ich habe keine Ahnung, wie das Observable aussehen sollte, nachdem ich Einleitung gelesen habe zu Rx von Lee Campbell .

    
SuperJMN 14.11.2015, 23:02
quelle

2 Antworten

14

Dies ist ein ziemlich klassischer Fall der Verwendung von Rx, um ein anderes System abzufragen. Die meisten Leute benutzen Observable.Interval als ihren Go-to-Operator, und für die meisten wird es in Ordnung sein.

Sie haben jedoch bestimmte Anforderungen an Timeouts und Wiederholungsversuche. In diesem Fall denke ich, dass es besser ist, eine Kombination von Operatoren zu verwenden:

  • Observable.Timer , damit Sie Ihre Abfrage in einer bestimmten Zeit ausführen können
  • Timeout zum Identifizieren und Abfragen von Datenbanken, die überschrieben wurden
  • ToObservable() , um Ihre Task Ergebnisse einer beobachtbaren Sequenz zuzuordnen.
  • Retry , damit Sie nach Timeouts wiederhergestellt werden können
  • Repeat , damit Sie nach erfolgreichen Datenbankabfragen fortfahren können. Dadurch wird auch die anfängliche Zeitspanne / Lücke zwischen dem Abschluss der vorherigen Datenbankabfrage und dem Beginn der nächsten Datenbankabfrage beibehalten.

Dieses funktionierende LINQPad -Snippet sollte Ihnen zeigen, dass die Abfrage richtig funktioniert:

%Vor%

Die Ergebnisse sehen folgendermaßen aus:

%Vor%

Der Schlüssel des Samples ist ....

%Vor%

BEARBEITEN: Hier ist eine weitere Erklärung, wie man zu dieser Lösung gelangt. Ссылка

    
Lee Campbell 16.11.2015, 16:04
quelle
1

Ich denke, das sollten Sie tun:

%Vor%

Dies löst eine neue Abfrage mit einem Intervall zwischen Ausführungen von 5 Sekunden aus. Es sind keine 5 Sekunden seit dem letzten Start vergangen, es sind 5 Sekunden seit dem letzten Ende.

Dann versuchst du deine Abfrage, aber du .Amb it mit einem Timer, der nach 10 Sekunden eine spezielle DataSet zurückgibt. Wenn Ihre Abfrage endet, bevor 10 Sekunden abgelaufen sind, gewinnt sie, aber ansonsten wird das spezielle DataSet zurückgegeben. Der Operator .Amb ist im Grunde ein "race" -Operator - die erste beobachtbare Eigenschaft, die einen Wert erzeugt, gewinnt.

    
Enigmativity 15.11.2015 11:25
quelle