InputStream / OutputStream / PipedOutputStream und managedExecutorService

Diskutiere InputStream / OutputStream / PipedOutputStream und managedExecutorService im Java Basics - Anfänger-Themen Bereich.
B

beta20

Hallo,

ich möchte gerne folgendes realisieren:
1) Email aus GUI senden
+ Dokument generieren (als Anhang)

Es geht mir hier nicht wie ich die Email versende, sondern ich habe ein Verständnisproblem mit
  • InputStream
  • Outputstream
  • PipedOutputstream
  • ManagedExecutorService managedExecutorService

a) Wann muss eine Methode / Aktion innerhalb laufen?

Java:
 managedExecutorService.submit(() -> {
            try {
                doSomething();
            }
        catch (Exception e) {}
            return null;
        });
b) Wann verwende ich einen PipedOutputStream und was bringt mir dieser gegenüber einem OutputStream?

Mein Ablauf sieht wie folgt aus:

JSF - Controller Bean:
// Es wird ein Objekt "Offer" übergeben und daraus wird dann eine PDF erstellt
Code:
public void doSendEmail() {
    myEjbean.sendOffer(offer);
}
EJB - Bean:
- In der EJB Bean habe ich dann folgende Dinge zu tun:

1) Erstellung der PDF
Code:
PipedOutputStream createPdfWithAttachments(DocumentDesigner documentDesigner, String fileName,
            boolean preview) {

 List<InputStream> inputStreamList = new ArrayList<InputStream>();

// 1) Alle vor der PDF Dateien laden (Es werden PDF Dateien geladen, die vor dem eigentlichen Angebot sein sollen in der PDF)
// // Diese hinzufügen bei: inputStreamList.add(inputStream);

// 2) Dokument erstellen (Angebot erstellen)
PipedOutputStream createPdf(PipedOutputStream os, DocumentDesigner documentDesigner, boolean preview)
inputStreamList.add(isDocument);

// 3) Alle nach der PDF Dateien laden  (Es werden PDF Dateien geladen, die nach dem eigentlichen Angebot sein sollen in der PDF)
// Diese hinzufügen bei: inputStreamList.add(inputStream);


// 4) Merge PDF 
PipedOutputStream is = pdfGenerationHelperService.mergePdf(inputStreamList, fileName);
return is;

}

Anschließend übergebe ich den Stream (die PDF) meinem Objekt "EmailAttachment":
Java:
                 PipedOutputStream os = new PipedOutputStream();
                 PipedInputStream is = new PipedInputStream(os);
                 os = pdfDocumentGenerationService.createPdfWithAttachments(offer.getDocumentDesigner(),
                        fileName, false);

                EmailAttachment emailAttachment = new EmailAttachment();
                emailAttachment.setInputStream(is);
                emailAttachment.setFilename(fileName);
                emailAttachment.setMimeType("application/pdf");
Was ich nun nicht verstehe, wann:
a) Welche der Methoden 1-4 muss innerhalb 1) Erstellung der PDF in einem managedExecutorService.submit(() laufen? Wenn ich es richtig sehe und PipedOutputStream createPdf NICHT innerhalb managedExecutorService.submit(() laufen würde, wird diese Methode gar nicht ausgeführt?

b) Können diese managedExecutorService.submit(() auch verschachtelt sein (nested) ?

c) Macht es Sinn die EJB - Methode bereits in einem managedExecutorService.submit(() innerhalb der JSF Bean aufzurufen?
Also sowas wie:

Java:
            managedExecutorService.submit(() -> {

                try {
                    // Versenden
                    offerProcessService.sendOffer(offer)
                }

                catch (Exception e) {
                    LOGGER.error(ExceptionUtils.getFullStackTrace(e));
                }

                return;
            });
Danke für die Hilfe
 
mihe7

mihe7

Ein ExecutorService dient einfach dazu, Dinge im Hintergrund zu erledigen. Der ManagedExecutorService ist ein ExecutorService, der vom Application-Server zur Verfügung gestellt wird.

InputStream und OutputStream sind einfach zwei Interfaces, die das Lesen und Schreiben von bzw. in "Datenströme" regeln.

PipedInputStream und PipedOutputStream sind Implementierungen dieser Interfaces und machen nur in Kombination Sinn: was in einen PipedOutputStream geschrieben wird, kann von einem PipedInputStream gelesen werden. Das muss allerdings parallel ablaufen, weswegen Du z. B. das Schreiben in einen separaten Thread auslagerst (managedExecutorService.submit()) und im aktuellen Thread liest.
 
B

beta20

Danke für die Antwort.
D.h. der ManagedExecutorService gibt es nur 1x, also eine Instanz?

Mir ist nicht ganz klar, wann ich im oben genannten Beispiel managedExecutorService.submit(() -> { .... } verwenden soll.
Macht das schon Sinn beim Aufruf vom WebController, also JSF Bean?
-> Wenn ich das richtig verstehe, dann wird der Thread einfach in eine Queue gespeichert?

Würde ich den Prozess nicht in die Queue speichern, dann würde der User in der Web - GUI solange warten müssen (Sand - Uhr), bis die Aktion durchgeführt wurde? Der Emailversand / Angebotsgenerierung kann ja schon ein paar Sekunden dauern? Die Frage ist dann nur, wie bekommt der User bei dieser Anfrage mit, wenn ein Fehler aufgetreten ist? Alternativ kann man dann eben eine Notification senden.

Können die managedExecutorService.submit(() - Aufrufe auch verschachtelt sein?

Also:
Java:
managedExecutorService.submit(()  {
    ....
    managedExecutorService.submit(() {....}
}
Generell auch die Frage, wie erfolgt die Abarbeitung...
Passiert das von oben nach unten?

Wird die rote Methode schon ausgeführt, wenn der die grüne Methode in einem Thread läuft, aber noch nicht fertig ist?
1598300887915.png

Hier der Methodenkopf und der Aufruf im Thread:
1598300932052.png
 
mihe7

mihe7

D.h. der ManagedExecutorService gibt es nur 1x, also eine Instanz?
Das ist nicht gesagt. Es geht einfach darum, dass dieser vom Application Server bereitgestellt (und dort konfiguriert) wird.

Mir ist nicht ganz klar, wann ich im oben genannten Beispiel managedExecutorService.submit(() -> { .... } verwenden soll.
Immer, wenn Du etwas ausführen willst, das den aktuellen Thread nicht blockieren soll.

Macht das schon Sinn beim Aufruf vom WebController, also JSF Bean?
Wenn Du an der Stelle etwas im Hintergrund ausführen willst, macht es Sinn.

Können die managedExecutorService.submit(() - Aufrufe auch verschachtelt sein?
Klar.

Würde ich den Prozess nicht in die Queue speichern, dann würde der User in der Web - GUI solange warten müssen (Sand - Uhr), bis die Aktion durchgeführt wurde? Der Emailversand / Angebotsgenerierung kann ja schon ein paar Sekunden dauern? Die Frage ist dann nur, wie bekommt der User bei dieser Anfrage mit, wenn ein Fehler aufgetreten ist? Alternativ kann man dann eben eine Notification senden.
1. Frage: klar. Du hast einen Request, der wird verarbeitet, was dann zu einer entsprechenden Antwort führt. So lange die Verarbeitung läuft, kann es keine Antwort geben. Mittels asynchroner Verarbeitung kannst Du also die Reaktionszeit der Anwendung senken.
2. Frage: das ist ein Grundsatzproblem asynchroner Verarbeitung, worauf es keine pauschale Antwort gibt. Oft muss fachlich eine passende Strategie gefunden werden. Wenn die Verarbeitung nur Sekunden dauern soll, kannst Du z. B. eine Push Notification senden. Oder Du speicherst "Jobs" und der Benutzer kann nachschauen, ob der Job erledigt wurde oder ...

Wird die rote Methode schon ausgeführt, wenn der die grüne Methode in einem Thread läuft, aber noch nicht fertig ist?
Du meinst wahrscheinlich das richtige. Die grüne Zeile wird vor der roten Zeile ausgeführt. Die Methode stellt aber per submit() Code zur Ausführung im Hintergrund in die Queue des Executor Services und kehrt sofort zurück. Es ist daher auch nicht gesagt, dass dieser Code bereits läuft, wenn die rote Zeile erreicht wird, z. B. könnten alle Threads des ExecutorServices gerade belegt sein. Sollte hier aber kein Problem darstellen, weil das Lesen aus dem InputStream ein blockierender Aufruf ist.
 
Thema: 

InputStream / OutputStream / PipedOutputStream und managedExecutorService

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben