Struttura di codice adeguata per un servlet che utilizza la cache e asincrona

1

Sto usando un Servlet Java (con Jetty incorporato, senza Spring, senza framework) e sto aggiungendo l'elaborazione asincrona e la memorizzazione nella cache. L'esatta implementazione è irrilevante a questa domanda e non è molto specifica per Java. Il mio problema è la struttura generale del codice, che prima delle aggiunte sembra questo pseudocodice

void service1() {
    addFixedHeaders();

    try {
        service2();
    } catch (MyException e) {
       ...
    } catch (AnotherException e) {
      ...
    }

    addMoreHeadersUnlessAlreadySet();
    writeResponse();
}

void service2() {
   addCorsIfNeeded();
   if (needsForwarding())  {
       doForwarding();
   } else {
       service3();
   }
}

void service3() {
    if (hasEtag() && isStillValid()) {
       serveMotModified();
    } else {
        service4();
    }
}

Fondamentalmente, è una sequenza di chiamate service1 -> service2 -> service3 -> ... con alcuni pre e postprocessing (tipo di inline FilterChain ), dove alcune chiamate sono condizionali. Ero soddisfatto di ciò.

Tuttavia, aggiungendo il caching (intendo servire 200 risposte dalla cache del server piuttosto che servire 304, che si adatta bene) richiede cambiamenti in più metodi. Ciò viene complicato memorizzando nella cache il contenuto statico e dinamico in modo diverso e utilizzando la stessa cache anche per evitare la compressione. Questo rende il codice piuttosto brutto, mentre preferirei uno stile funzionale come

return cache.getOrCompute(key, key -> someComputation(key))

Indipendentemente, come esperimento, ho anche aggiunto l'elaborazione asincrona (che è necessaria solo per alcune richieste). Ciò ha richiesto una grande riscrittura e ha portato a qualcosa di eccezionalmente terribile (e peggiorerebbe ulteriormente con l'aggiunta del caching). Sto pensando a qualcosa come questa catena

void service1() {
    process1();
    if (isSimple1()) {
       shortcut1();
    } else if (wantsAsync1()) {
        callAsync(service2); 
    } else {
        service2(); 
    }
}

quando la maggior parte dei metodi avrà solo alcune parti. Quello che non mi piace qui è che non c'è possibilità di gestire le eccezioni in un singolo posto (come il mio in service1 .) Inoltre mi costringe a spostare la postelaborazione in un% di% di co_de che non è ovvio, che succede sempre .

Mi chiedo, se c'è uno schema adatto, qualcosa come la promessa di concatenare o qualsiasi altra cosa (non sto cercando una biblioteca anche se non insisto a reinventare la ruota). Qualcosa di semplice, ma flessibile, in modo che ulteriori aggiunte si adattino bene al modello.

    
posta maaartinus 05.07.2017 - 09:48
fonte

0 risposte

Leggi altre domande sui tag