den folgenden Code Betrachten wir für ein Update mit lang Polling zu hören:Erhalten Sie JAX-RS AsyncResponse, aber suspendieren später
Map<String, List<AsyncResponse>> tagMap = new ConcurrentGoodStuff();
// This endpoint listens for notifications of the tag
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@GET
@Path("listen/{tag}")
public void listenForUpdates(
@PathParam("tag") final String tag,
@Suspended final AsyncResponse response) {
tagMap.get(tag).add(response);
}
// This endpoint is for push-style notifications
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@PUT
@Path("update/{tag}/{value}")
public Response updateTag(
@PathParam("tag") final String tag,
@PathParam("value") final String value) {
for(AsyncResponse response : tagMap.get(tag)) {
// Resumes all previously suspended responses
response.resume(value);
}
return Response.ok("cool whatever").build();
}
Der Kunde einen Zuhörer mit der normalen Jersey Kunden hinzufügt AsyncInvoker
, ruft die asynchrone Aufgabe, und dann ruft eine andere Task die Update-Methode auf.
Wenn ich das teste, stoße ich in eine Wettlaufsituation. Direkt nachdem ich den Listener asynchron auf listenForUpdates()
hinzugefügt habe, führe ich eine Aktualisierung auf dem Endpunkt mit updateTag()
synchron durch. Das Update wird jedoch ausgeführt, bevor der Listener hinzugefügt wird, und die asynchrone Antwort wird nicht fortgesetzt.
Eine Lösung ist, die suspend()
Methode auf die Antwort nach, die es zu den Listener hinzufügen. Aber es ist nicht klar, wie dies zu tun ist, da @Suspended
ein bereits suspendiertes AsyncResponse
Objekt bereitstellt. Was soll ich tun, damit die asynchrone Antwort unterbrochen wird nur nach Hinzufügen zum Listener? Wird das tatsächlich die Suspend-Methode aufrufen? Wie kann ich dies mit dem Async-Client von Jersey oder mit einem anderen Long-Polling-Client erreichen?
Für Lösungen bin ich offen für verschiedene Bibliotheken, wie Atmosphäre oder Guava. Ich bin nicht offen für das Hinzufügen eines Thread.sleep()
in meinem Test, da dies ein intermittierender Fehler ist, der darauf wartet, zu passieren.
Ich weiß nicht genau, was Sie zu tun versuchen, aber Sie sollten sich einige Beispiele im Jersey-Projekt ansehen. Es gibt eine Reihe verschiedener asynchroner Beispiele. Ich denke, eines der Chat-Beispiele macht das, was du versuchst zu tun. –
Ich denke [dies ist die eine] (https://github.com/jersey/jersey/tree/master/examples/server-async-managed). Nicht sicher, ob das genau das ist, was Sie versuchen, obwohl –
Ich denke, die blockierende Warteschlange ist definitiv der Weg zu gehen, wenn ich sicherstellen will, dass der Verbrauch einer Überprüfung für den Verbrauch vorausgeht. Ich habe derzeit Updates, die immer nicht blockierend sind. Wenn ich ein Flag hinzufüge, um bei einem Listener, der gerade aktualisiert wird, zu blockieren, hilft das definitiv beim Testen. Cool, ich denke ich werde das machen. Vielen Dank. Fügen Sie das als "echte Antwort" hinzu und ich gebe Ihnen einige Internet-Punkte weiter. –