Ich arbeite an einem Projekt, das in zwei Varianten mit und ohne Mandantenfähigkeit funktioniert.
Das Projekt macht einen REST-Service verfügbar, den ich gerne asynchron nutzen würde. So sieht mein Basisservice aus wie
%Vor%Das funktioniert ohne Mehrmandanten und ich bekomme die Vorteile des internen Jersey Executor Service kostenlos. Siehe @ManagedAsync
Wenn ich in die Mandantenfähigkeit umschalte, füge ich einen Filter zu der Anfrage hinzu, der die Mandanten-ID auflöst und sie auf den lokalen Thread setzt (in unserem Fall den HTTP-Thread).
Wenn die Verarbeitungskette die "add ()" -Methode übertrifft, ist der aktuelle Thread derjenige, der vom Jersey-Executor-Service bereitgestellt wird. Daher enthält er nicht meine Mandanten-ID. Ich könnte nur über die folgenden Optionen nachdenken, um dieses Problem zu umgehen.
Erweitern Sie den ResouceEndpoint zu MutliTenantResouceEndpoint, und legen Sie den @ManagedAsync ab Mit meinem eigenen Thread-Executor
%Vor%Aber auf diese Weise muss ich meinen eigenen Thread-Executor verwalten und es fühlt sich an, als würde mir hier etwas fehlen. Irgendwelche Vorschläge zu einem anderen Ansatz?
Hier sind einige Empfehlungen in der Reihenfolge.
Für den Kontext verwende ich Jersey seit 2 Jahren, und konfrontiert mit genau diesem Problem vor 18 Monaten.
@ManagedAsync
Wenn Sie die Kontrolle über den http-Server haben, auf dem Jersey läuft, würde ich Ihnen empfehlen, @ManagedAsync
nicht mehr zu benutzen.
Statt Jersey so einzurichten, dass es den HTTP-Thread sofort zurückgibt, und echte Anfragen an einen verwalteten Executor-Service-Thread auszulagern, verwenden Sie so etwas wie Grizzly für Ihren http-Server und konfigurieren Sie ihn für einen größeren Worker-Thread-Pool. Dies führt die gleiche Sache durch, aber schiebt die asynchrone Verantwortung in eine Ebene unterhalb von Jersey.
Wenn Sie @ManagedAsync
für ein Medium-zu-Large-Projekt verwenden, werden Sie im Laufe eines Jahres mit vielen Schwachstellen konfrontiert. Hier sind einige von ihnen von meinem Kopf:
return
Statements @Context
und ContainerRequest
Eigenschaften Dies würde bedeuten, dass requestContext.setProperty("tenant_id", tenantId)
in Ihrem Filter aufgerufen wird und dann der Aufruf von requestContext.getProperty("tenant_id")
in Ihrer Ressource mit einer @Context
injected request aufgerufen wird.
Dies würde das Einrichten einer HK2-Bindung von InterceptionService
mit einem MethodInterceptor
beinhalten, das nach verwalteten asynchronen Ressourcenmethoden sucht und alle RequestScoped
bound ContainerRequestFilter
s manuell ausführt. Anstatt dass Ihre Filter bei Jersey registriert werden, würden Sie sie bei HK2 registrieren, damit sie vom Methodenabfangprogramm ausgeführt werden.
Ich kann den Optionen 2/3 weitere Details und Codebeispiele hinzufügen, wenn Sie möchten, oder zusätzliche Vorschläge machen, aber es wäre zunächst hilfreich, mehr von Ihrem Filtercode zu sehen, und ich schlage, wenn möglich, erneut Option 1 vor.
Tags und Links java multithreading rest jersey servlet-3.0