Concurrency-Problem für die Annullierung der langen Poll-Schleife

9

Ich habe ein Problem, das ich hoffentlich lösen werde, indem ich diese Frage schreibe, aber wenn nicht, werde ich posten und sehen, ob jemand helfen kann.

Ich verwende eine Client-Bibliothek (die schlecht geschrieben ist, die ich fühle), um mit einem Echtzeit-Chat-Server zu interagieren, der COMET-Stil-Long-Polling über HTTP verwendet. Ich habe Probleme mit der Absage der Long-Poll in bestimmten Situationen und vermute, dass ich etwas Concurrency-Handling-Code hinzufügen muss, aber es fällt mir schwer aus den unten genannten Gründen den besten Weg zu finden.

Der Subskriptionscode (der in der langen Umfrage enthalten ist) wird als eine große Schleife mit dem folgenden

implementiert %Vor%

Der Abmeldungsruf (der einen anderen Thread aufruft)

%Vor%

Ich habe den Problemfall isoliert, bei dem die Operationen verschachtelt sind. Für mich scheint das ein Ergebnis davon zu sein, dass der Code multi-threaded ist und der Client-Code nicht Thread-sicher ist. Auch ein schlechtes Management und die Nichtwiederverwendung von httpClient hilft nicht.

Eines der Probleme, die ich habe, ist unten, wo der Abmeldungs-Aufruf die nächste getRequest nicht stoppt.

%Vor%

Ich würde gerne wissen, was die Leute für die beste Herangehensweise an dieses Problem halten (die Zeit ist auch begrenzt, so dass ich nicht zu viel Code schreiben kann!)

Um dies zu beheben, dachte ich, ich könnte einen syncronization block von der ersten Abmeldeprüfung in Thread 1 bis zu dem Punkt verwenden, an dem die httpClient gespeichert wird, bevor die eigentliche get-Anfrage ausgeführt und synchronisiert wird die Abmeldungsmethode mit der gleichen Sperre. Dies ist im Moment nicht praktikabel, da der erste erwähnte Sync-Block in einem Methodenaufruf beginnen und weiter unten in der Methodenaufrufkette enden würde (aufgrund der Art, wie die Lib geschrieben wird) - was sich sehr falsch anfühlt, so dass ein Refactoring notwendig wäre. p>

ODER Ich könnte einfach eine einzelne httpClient pro Kanal anstatt pro Anfrage erstellen, und dann könnte sie immer heruntergefahren werden und ich könnte möglicherweise die Synchronisation ignorieren (denke ich).

ODER wie unten vorgeschlagen Ich könnte Interrupts für den gleichen Zweck verwenden

Irgendwelche Vorschläge wären willkommen - ich werde bearbeiten, wenn ich Fortschritte habe!

Danke

    
Dori 08.01.2013, 12:11
quelle

2 Antworten

3

Ich kaufte Java Concurrency in Practice als Ergebnis davon Problem und festgestellt, dass sie ein Problem sehr ähnlich wie dieses in Kapitel 7: Abbruch und Herunterfahren diskutieren, das durch das Zitat

zusammengefasst werden kann
  

Unterbrechung ist normalerweise der erfolgreichste Weg zur Implementierung   Stornierung

Da der HttpClient Socket-IO blockiert, das keine Unterbrechung unterstützt, habe ich einen zweigleisigen Ansatz. Ich reserviere meine httpClient , überprüfe kurz vor dem eigentlichen httpClient.execute() Aufruf auf Unterbrechung und in meiner unsubscribe() Methode unterbrich den Thread und rufe dann httpClient.getConnectionManager().shutdown(); auf. Dies scheint sich um mein Problem zu kümmern und war eine sehr einfache Änderung. Keine Verschachtelungsprobleme mehr!

Ich habe auch das boolesche unsubscribe -Feld auf volatile wie vorgeschlagen eingestellt, was ich vorher tun sollte - dies allein hätte das Problem jedoch nicht gelöst

    
Dori 11.01.2013, 10:23
quelle
2

1) Setzen Sie die Abmeldung als flüchtig ab

2) Um eine größere Sicherheit zu gewährleisten, schützen Sie den Zugriff (Lesen / Schreiben), um sich beispielsweise mit einem Semaphore abzumelden.

    
pringi 08.01.2013 13:40
quelle