Spring Batch - Tasklets vs Chunks

1. Úvod

Spring Batch poskytuje dva rôzne spôsoby implementácie úlohy: použitie úlohových blokov a blokov.

V tomto článku sa dozvieme, ako nakonfigurovať a implementovať obe metódy na jednoduchom príklade z reálneho života.

2. Závislosti

Začnime tým pridanie požadovaných závislostí:

 org.springframework.batch spring-batch-core 4.2.0.RELEASE org.springframework.batch spring-batch-test 4.2.0.RELEASE test 

Najnovšiu verziu testov jar-dávka-test a test dávky-testu nájdete v Maven Central.

3. Náš prípad použitia

Uvažujme o súbore CSV s nasledujúcim obsahom:

Mae Hodges, 22.10.1972 Gary Potter, 22.02.1953 Betty Wise, 02.2.1968 Wayne Rose, 04.06.1977 Adam Caldwell, 27.09.1995 Lucille Phillips, 14.5.1992

The prvá pozícia každého riadku predstavuje meno osoby a druhá pozícia predstavuje jeho / jej dátum narodenia.

Náš prípad použitia je vygenerujte ďalší súbor CSV, ktorý obsahuje meno a vek každej osoby:

Mae Hodges, 45 Gary Potter, 64 Betty Wise, 49 Wayne Rose, 40 Adam Caldwell, 22 Lucille Phillips, 25

Teraz, keď je naša doména jasná, poďme ďalej a vytvorme riešenie pomocou oboch prístupov. Začneme úlohami.

4. Prístup k pracovným úlohám

4.1. Úvod a dizajn

Úlohy sú určené na vykonanie jednej úlohy v rámci jedného kroku. Naša práca bude pozostávať z niekoľkých krokov, ktoré sa vykonajú jeden po druhom. Každý krok by mal vykonávať iba jednu definovanú úlohu.

Naša práca bude pozostávať z troch krokov:

  1. Prečítajte si riadky zo vstupného súboru CSV.
  2. Vo vstupnom súbore CSV vypočítajte vek pre každú osobu.
  3. Napíšte meno a vek každej osoby do nového výstupného súboru CSV.

Teraz, keď je celkový obraz hotový, vytvorme jednu triedu na krok.

LinesReader bude mať na starosti načítanie údajov zo vstupného súboru:

verejná trieda LinesReader implementuje Tasklet {// ...}

LinesProcesor vypočíta vek pre každú osobu v súbore:

verejná trieda LinesProcessor implementuje Tasklet {// ...}

Nakoniec LinesWriter bude zodpovedný za zápis mien a vekových skupín do výstupného súboru:

verejná trieda LinesWriter implementuje Tasklet {// ...}

V tejto chvíli všetky naše kroky implementovať Tasklet rozhranie. To nás prinúti implementovať jeho vykonať metóda:

@Override public RepeatStatus execute (StepContribution stepContribution, ChunkContext chunkContext) vyvolá výnimku {// ...}

Táto metóda je miesto, kde pridáme logiku pre každý krok. Predtým, ako začneme s týmto kódom, nakonfigurujme si svoju prácu.

4.2. Konfigurácia

Musíme pridať konfiguráciu do kontextu aplikácie Spring. Po pridaní štandardnej deklarácie fazule pre triedy vytvorené v predchádzajúcej časti sme pripravení vytvoriť našu definíciu úlohy:

@Configuration @EnableBatchProcessing verejnej triedy TaskletsConfig {@Autowired súkromné ​​úlohy JobBuilderFactory; @Autowired súkromné ​​kroky StepBuilderFactory; @Bean chránený Step readLines () {návratové kroky .get ("readLines") .tasklet (linesReader ()) .build (); } @Bean chránený Step processLines () {návrat kroky .get ("processLines") .tasklet (linesProcessor ()) .build (); } @Bean chránený Step writeLines () {návrat kroky .get ("writeLines") .tasklet (linesWriter ()) .build (); } @Bean public Job job () {return jobs .get ("taskletsJob") .start (readLines ()) .next (processLines ()) .next (writeLines ()) .build (); } // ...}

To znamená, že náš „TaskletsJob“ bude pozostávať z troch krokov. Prvý (readLines) vykoná tasklet definovaný v fazuli linesReader a prejdite na ďalší krok: processLines. ProcessLines vykoná úlohu definovanú v fazuli linesProcesor a prejdite na posledný krok: writeLines.

Náš priebeh úloh je definovaný a sme pripravení pridať trochu logiky!

4.3. Model a náradie

Keď budeme manipulovať s riadkami v súbore CSV, vytvoríme triedu Riadok:

public class Line implementuje Serializable {private String name; private LocalDate dob; súkromné ​​Dlhý vek; // štandardný konštruktor, getri, nastavovatelia a implementácia toString}

Vezmite prosím na vedomie, že Riadok náradie Serializovateľné. Je to preto Riadok bude fungovať ako DTO na prenos údajov medzi krokmi. Podľa Spring Batch, objekty, ktoré sa prenášajú medzi krokmi, musia byť serializovateľné.

Na druhej strane môžeme začať uvažovať o čítaní a písaní riadkov.

K tomu využijeme OpenCSV:

 com.opencsv opencsv 4.1 

Vyhľadajte najnovšiu verziu OpenCSV v Maven Central.

Akonáhle je zahrnutý OpenCSV, tiež vytvoríme FileUtils trieda. Poskytne metódy na čítanie a zápis riadkov CSV:

public class FileUtils {public Line readLine () throws Exception {if (CSVReader == null) initReader (); Reťazec [] line = CSVReader.readNext (); if (line == null) return null; vrátiť nový riadok (riadok [0], LocalDate.parse (riadok [1], DateTimeFormatter.ofPattern ("MM / dd / rrrr"))); } public void writeLine (riadok) hodí výnimku {if (CSVWriter == null) initWriter (); Reťazec [] lineStr = nový Reťazec [2]; lineStr [0] = line.getName (); lineStr [1] = line .getAge () .toString (); CSVWriter.writeNext (lineStr); } // ...}

Všimni si readLine funguje ako obal cez OpenCSV readNext metóda a vráti a Riadok objekt.

Rovnakým spôsobom, writeLine zabalí OpenCSV writeNext príjem a Riadok objekt. Plnú implementáciu tejto triedy nájdete v projekte GitHub.

V tejto chvíli sme všetci pripravení začať s implementáciou každého kroku.

4.4. LinesReader

Poďme do toho a dokončme svoje LinesReader trieda:

verejná trieda LinesReader implementuje Tasklet, StepExecutionListener {private final Logger logger = LoggerFactory .getLogger (LinesReader.class); súkromné ​​riadky zoznamu; súkromný FileUtils fu; @Override public void beforeStep (StepExecution stepExecution) {lines = new ArrayList (); fu = new FileUtils ("taskletsvschunks / input / tasklets-vs-chunks.csv"); logger.debug ("Lines Reader initialized."); } @Override public RepeatStatus execute (StepContribution stepContribution, ChunkContext chunkContext) vyvolá výnimku {Line line = fu.readLine (); while (line! = null) {lines.add (line); logger.debug ("Čítať riadok:" + line.toString ()); riadok = fu.readLine (); } návrat RepeatStatus.FINISHED; } @Override public ExitStatus afterStep (StepExecution stepExecution) {fu.closeReader (); stepExecution .getJobExecution () .getExecutionContext () .put ("riadky", this.lines); logger.debug („Aplikácia Lines Reader skončila.“); vrátiť ExitStatus.COMPLETED; }}

Spustenie programu LinesReader metóda vytvára a FileUtils inštancia nad cestou vstupného súboru. Potom, pridáva riadky do zoznamu, kým už nebudú ďalšie riadky na čítanie.

Naša trieda tiež realizuje StepExecutionListener ktorá poskytuje dve ďalšie metódy: predKrok a afterStep. Tieto metódy použijeme na inicializáciu a uzavretie vecí pred a po vykonať beží.

Ak sa pozrieme na afterStep kódu, všimneme si riadok, kde je zoznam výsledkov (riadky) je vložený do kontextu úlohy, aby bola k dispozícii pre ďalší krok:

stepExecution .getJobExecution () .getExecutionContext () .put ("riadky", this.lines);

V tomto okamihu už náš prvý krok splnil svoju zodpovednosť: načítanie liniek CSV do a Zoznam v pamäti. Prejdime k druhému kroku a spracujme ich.

4.5. LinesProcesor

LinesProcesor bude tiež implementovať StepExecutionListener a samozrejme, Tasklet. To znamená, že sa bude realizovať predKrok, vykonať a afterStep metódy tiež:

verejná trieda LinesProcessor implementuje Tasklet, StepExecutionListener {private Logger logger = LoggerFactory.getLogger (LinesProcessor.class); súkromné ​​riadky zoznamu; @Override public void beforeStep (StepExecution stepExecution) {ExecutionContext executionContext = stepExecution .getJobExecution () .getExecutionContext (); this.lines = (Zoznam) executionContext.get ("riadky"); logger.debug ("Procesor riadkov inicializovaný."); } @Override public RepeatStatus execute (StepContribution stepContribution, ChunkContext chunkContext) vyvolá výnimku {for (Line line: lines) {long age = ChronoUnit.YEARS.b Between (line.getDob (), LocalDate.now ()); logger.debug ("Vypočítaný vek" + vek + "pre riadok" + riadok.toString ()); line.setAge (vek); } návrat RepeatStatus.FINISHED; } @Override public ExitStatus afterStep (StepExecution stepExecution) {logger.debug ("Procesor riadkov skončil."); vrátiť ExitStatus.COMPLETED; }}

Je ľahké to pochopiť načíta sa to riadky zoznam z kontextu práce a počíta vek každého človeka.

Nie je potrebné dávať do kontextu ďalší zoznam výsledkov, pretože k úpravám dochádza u toho istého objektu, ktorý pochádza z predchádzajúceho kroku.

A sme pripravení na náš posledný krok.

4.6. LinesWriter

LinesWriterÚlohou je prejsť ďalej riadky zoznam a do výstupného súboru napíš meno a vek:

verejná trieda LinesWriter implementuje Tasklet, StepExecutionListener {private final Logger logger = LoggerFactory .getLogger (LinesWriter.class); súkromné ​​riadky zoznamu; súkromný FileUtils fu; @Override public void beforeStep (StepExecution stepExecution) {ExecutionContext executionContext = stepExecution .getJobExecution () .getExecutionContext (); this.lines = (Zoznam) executionContext.get ("riadky"); fu = new FileUtils ("output.csv"); logger.debug ("Spisovateľ riadkov bol inicializovaný."); } @Override public RepeatStatus execute (StepContribution stepContribution, ChunkContext chunkContext) vyvolá výnimku {for (Line line: lines) {fu.writeLine (line); logger.debug ("Napísal riadok" + line.toString ()); } návrat RepeatStatus.FINISHED; } @Override public ExitStatus afterStep (StepExecution stepExecution) {fu.closeWriter (); logger.debug ("Spisovač riadkov bol ukončený."); vrátiť ExitStatus.COMPLETED; }}

S implementáciou našej práce sme hotoví! Vytvorme test na jeho spustenie a pozrite si výsledky.

4.7. Spustenie úlohy

Na spustenie úlohy vytvoríme test:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (classes = TaskletsConfig.class) verejná trieda TaskletsTest {@Autowired private JobLauncherTestUtils jobLauncherTestUtils; @Test public void givenTaskletsJob_whenJobEnds_thenStatusCompleted () vyvolá výnimku {JobExecution jobExecution = jobLauncherTestUtils.launchJob (); assertEquals (ExitStatus.COMPLETED, jobExecution.getExitStatus ()); }}

ContextConfiguration anotácia ukazuje na triedu konfigurácie jari, ktorá má našu definíciu úlohy.

Pred vykonaním testu budeme musieť pridať pár fazule navyše:

@Bean public JobLauncherTestUtils jobLauncherTestUtils () {vrátiť nový JobLauncherTestUtils (); } @Bean public JobRepository jobRepository () vyvolá výnimku {MapJobRepositoryFactoryBean factory = nový MapJobRepositoryFactoryBean (); factory.setTransactionManager (actionManager ()); návrat (JobRepository) factory.getObject (); } @Bean public PlatformTransactionManager transactionManager () {vrátiť nový ResourcelessTransactionManager (); } @Bean public JobLauncher jobLauncher () hodí výnimku {SimpleJobLauncher jobLauncher = nový SimpleJobLauncher (); jobLauncher.setJobRepository (jobRepository ()); vrátiť jobLauncher; }

Všetko je pripravené! Pokračujte a vykonajte test!

Po dokončení práce výstup.csv má očakávaný obsah a protokoly zobrazujú priebeh vykonávania:

[main] DEBUG o.b.t.tasklets.LinesReader - čítačka riadkov bola inicializovaná. [main] DEBUG obttasklets.LinesReader - text na čítanie: [Mae Hodges, 22.10.1972] [main] DEBUG obttasklets.LinesReader - text na čítanie: [Gary Potter, 22.2.1953] [main] DEBUG obttasklets .LinesReader - Čítaný riadok: [Betty Wise, 17.02.1968] [hlavný] DEBUG obttasklets.LinesReader - Čítaný riadok: [Wayne Rose, 04/06/1977] [hlavný] DEBUG obttasklets.LinesReader - Čítaný riadok: [Adam Caldwell, 09/27/1995] [hlavné] DEBUG obttasklets.LinesReader - riadok na čítanie: [Lucille Phillips, 14.05.1992] [hlavné] DEBUG obttasklets.LinesReader - riadok Reader skončil. [main] DEBUG o.b.t.tasklets.LinesProcessor - riadky boli inicializované. [main] DEBUG obttasklets.LinesProcessor - Vypočítaný vek 45 pre linku [Mae Hodges, 22.10.1972] [main] DEBUG obttasklets.LinesProcessor - Vypočítaný vek 64 pre linku [Gary Potter, 22.2.1953] [main ] DEBUG obttasklets.LinesProcessor - Vypočítaný vek 49 pre linku [Betty Wise, 02/17/1968] [main] DEBUG obttasklets.LinesProcessor - Vypočítaný vek 40 pre linku [Wayne Rose, 04/06/1977] [main] DEBUG obttasklets.LinesProcessor - Vypočítaný vek 22 pre linku [Adam Caldwell, 09/27/1995] [main] DEBUG obttasklets.LinesProcessor - Vypočítaný vek 25 pre linku [Lucille Phillips, 14.05.1992] [main] DEBUG obttasklets .LinesProcessor - riadok procesora skončil. [main] DEBUG o.b.t.tasklets.LinesWriter - program na zápis riadkov inicializovaný. [hlavný] DEBUG obttasklets.LinesWriter - napísaná linka [Mae Hodges, 10/22/1972,45] [hlavný] DEBUG obttasklets.LinesWriter - napísaná linka [Gary Potter, 22.02.1953,64] [hlavná] DEBUG obttasklets.LinesWriter - napísaná linka [Betty Wise, 02/17/1968,49] [main] DEBUG obttasklets.LinesWriter - napísaná linka [Wayne Rose, 04/06/1977,40] [main] DEBUG obttasklets.LinesWriter - Napísaný riadok [Adam Caldwell, 09/27/1995,22] [hlavný] DEBUG obttasklets.LinesWriter - Napísaný riadok [Lucille Phillips, 14.5.1992,25] [hlavný] DEBUG obttasklets.LinesWriter - Spisovateľ riadkov skončil .

To je pre Tasklety všetko. Teraz môžeme prejsť na prístup Chunks.

5. Prístup kúskov

5.1. Úvod a dizajn

Ako už názov napovedá, tento prístup vykonáva akcie nad hromadami údajov. To znamená, že namiesto čítania, spracovania a zápisu všetkých riadkov naraz bude čítať, spracovávať a zapisovať naraz pevné množstvo záznamov (diskových blokov).

Potom bude cyklus opakovať, kým v súbore nebudú ďalšie údaje.

Výsledkom bude mierne odlišný tok:

  1. Aj keď existujú riadky:
    • Urobte pre X počet riadkov:
      • Prečítajte si jeden riadok
      • Spracujte jeden riadok
    • Napíš X počet riadkov.

Musíme teda tiež vytvárať tri fazule pre prístup orientovaný na kus:

verejná trieda LineReader {// ...}
verejná trieda LineProcessor {// ...}
verejná trieda LinesWriter {// ...}

Pred prechodom na implementáciu si nakonfigurujme našu prácu.

5.2. Konfigurácia

Definícia úlohy bude tiež vyzerať inak:

@Configuration @EnableBatchProcessing verejná trieda ChunksConfig {@Autowired súkromné ​​úlohy JobBuilderFactory; @Autowired súkromné ​​kroky StepBuilderFactory; @Bean public ItemReader itemReader () {return new LineReader (); } @Bean public ItemProcessor itemProcessor () {return new LineProcessor (); } @Bean public ItemWriter itemWriter () {return new LinesWriter (); } @Bean chránené Step processLines (čítačka ItemReader, procesor ItemProcessor, zapisovač ItemWriter) {návrat steps.get ("processLines"). kus (2). čítačka (čítačka). procesor (procesor). spisovateľ (zapisovateľ) .build (); } @Bean public Job job () {return jobs .get ("chunksJob") .start (processLines (itemReader (), itemProcessor (), itemWriter ())) .build (); }}

V takom prípade existuje iba jeden krok, v ktorom sa vykoná iba jeden tasklet.

Avšak tá úloha definuje čítačku, zapisovačku a procesor, ktorý bude pracovať na hromadách dát.

Všimnite si, že interval potvrdenia označuje množstvo údajov, ktoré sa majú spracovať v jednom bloku. Naša práca bude čítať, spracovávať a písať dva riadky naraz.

Teraz sme pripravení pridať našu logiku bloku!

5.3. LineReader

LineReader bude mať na starosti prečítanie jedného záznamu a vrátenie a Riadok napríklad svojím obsahom.

Ak sa chcete stať čitateľom, naša trieda musí implementovať ItemReader rozhranie:

verejná trieda LineReader implementuje ItemReader {@Override public Line read () vyvolá výnimku {Line line = fu.readLine (); if (line! = null) logger.debug ("Čítať riadok:" + line.toString ()); spätné vedenie; }}

Kód je priamy, iba načíta jeden riadok a vráti ho. Budeme tiež implementovať StepExecutionListener pre konečnú verziu tejto triedy:

verejná trieda LineReader implementuje ItemReader, StepExecutionListener {private final Logger logger = LoggerFactory .getLogger (LineReader.class); súkromný FileUtils fu; @Override public void beforeStep (StepExecution stepExecution) {fu = new FileUtils ("taskletsvschunks / input / tasklets-vs-chunks.csv"); logger.debug ("Inicializácia čítačky liniek."); } @Override public Line read () vyvolá výnimku {Line line = fu.readLine (); if (line! = null) logger.debug ("Čítať riadok:" + line.toString ()); spätné vedenie; } @Override public ExitStatus afterStep (StepExecution stepExecution) {fu.closeReader (); logger.debug ("Aplikácia Line Reader skončila."); vrátiť ExitStatus.COMPLETED; }}

To si treba všimnúť predKrok a afterStep vykonať pred a po celom kroku.

5.4. LineProcessor

LineProcessor sleduje skoro rovnakú logiku ako LineReader.

V tomto prípade však implementujeme ItemProcessor a jeho metóda proces ():

verejná trieda LineProcessor implementuje ItemProcessor {private Logger logger = LoggerFactory.getLogger (LineProcessor.class); @Override public Line process (Line line) hodí Exception {long age = ChronoUnit.YEARS .between (line.getDob (), LocalDate.now ()); logger.debug ("Vypočítaný vek" + vek + "pre riadok" + riadok.toString ()); line.setAge (vek); spätné vedenie; }}

The proces () metóda vezme vstupný riadok, spracuje ho a vráti výstupný riadok. Opäť budeme tiež implementovať StepExecutionListener:

verejná trieda LineProcessor implementuje ItemProcessor, StepExecutionListener {private Logger logger = LoggerFactory.getLogger (LineProcessor.class); @Override public void beforeStep (StepExecution stepExecution) {logger.debug ("Inicializovaný riadkový procesor."); } @Override public Line process (Line line) throws Exception {long age = ChronoUnit.YEARS .b Between (line.getDob (), LocalDate.now ()); logger.debug ("Vypočítaný vek" + vek + "pre riadok" + line.toString ()); line.setAge (vek); spätné vedenie; } @Override public ExitStatus afterStep (StepExecution stepExecution) {logger.debug ("Line Processor skončil."); vrátiť ExitStatus.COMPLETED; }}

5.5. LinesWriter

Na rozdiel od čítačky a procesora LinesWriter napíše celý riadok aby dostávala a Zoznam z Riadky:

verejná trieda LinesWriter implementuje ItemWriter, StepExecutionListener {private final Logger logger = LoggerFactory .getLogger (LinesWriter.class); súkromný FileUtils fu; @Override public void beforeStep (StepExecution stepExecution) {fu = new FileUtils ("output.csv"); logger.debug ("Program na zapisovanie liniek inicializovaný."); } @Override public void write (List lines) throws Exception {for (Line line: lines) {fu.writeLine (line); logger.debug ("Napísal riadok" + line.toString ()); }} @Override public ExitStatus afterStep (StepExecution stepExecution) {fu.closeWriter (); logger.debug ("Zapisovač riadkov bol ukončený."); vrátiť ExitStatus.COMPLETED; }}

LinesWriter kód hovorí za všetko. A opäť sme pripravení vyskúšať si svoju prácu.

5.6. Spustenie úlohy

Vytvoríme nový test, ktorý sme vytvorili pre prístup k úlohám:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (classes = ChunksConfig.class) verejná trieda ChunksTest {@Autowired private JobLauncherTestUtils jobLauncherTestUtils; @Test public void givenChunksJob_whenJobEnds_thenStatusCompleted () vyvolá výnimku {JobExecution jobExecution = jobLauncherTestUtils.launchJob (); assertEquals (ExitStatus.COMPLETED, jobExecution.getExitStatus ()); }}

Po nakonfigurovaní ChunksConfig ako je vysvetlené vyššie pre Konfigurácia úloh, sme pripravení test vykonať!

Po dokončení práce to vidíme výstup.csv obsahuje opäť očakávaný výsledok a protokoly popisujú tok:

[main] DEBUG o.b.t.chunks.LineReader - čítačka liniek inicializovaná. [main] DEBUG o.b.t.chunks.LinesWriter - zapisovač riadkov inicializovaný. [main] DEBUG o.b.t.chunks.LineProcessor - inicializovaný linkový procesor. [main] DEBUG obtchunks.LineReader - Prečítajte si riadok: [Mae Hodges, 22.10.1972] [main] DEBUG obtchunks.LineReader - Prečítajte si riadok: [Gary Potter, 22.2.1953] [main] DEBUG obtchunks .LineProcessor - Vypočítaný vek 45 rokov pre linku [Mae Hodges, 22.10.1972] [hlavný] DEBUG obtchunks.LineProcessor - Vypočítaný vek 64 rokov pre linku [Gary Potter, 22.02.1953] [hlavný] DEBUG obtchunks.LinesWriter - Napísaný riadok [Mae Hodges, 10/22/1972,45] [hlavný] DEBUG obtchunks.LinesWriter - Napísaný riadok [Gary Potter, 02/22 / 1953,64] [hlavný] DEBUG obtchunks.LineReader - Prečítajte si riadok: [Betty Wise, 17.2.1968] [main] DEBUG obtchunks.LineReader - Prečítajte si riadok: [Wayne Rose, 04/06/1977] [main] DEBUG obtchunks.LineProcessor - Vypočítaný vek 49 pre linku [Betty Wise, 17. 2. 1968] [hlavný] DEBUG obtchunks.LineProcessor - Vypočítaný vek 40 rokov pre linku [Wayne Rose, 4. 6. 1977] [hlavný] DEBUG obtchunks.LinesWriter - napísaný riadok [Betty Wise, 17. 2. 1968 , 49] [hlavný] DEBUG obtchunks.LinesWriter - napísaný riadok [Wayne Rose, 06.06.1977,40] [hlavný] DEBUG ob t.chunks.LineReader - Čítať riadok: [Adam Caldwell, 09/27/1995] [hlavné] DEBUG obtchunks.LineReader - Čítať riadok: [Lucille Phillips, 14/14/1992] [hlavné] DEBUG obtchunks.LineProcessor - Vypočítaný vek 22 rokov pre linku [Adam Caldwell, 09/27/1995] [hlavný] DEBUG obtchunks.LineProcessor - Vypočítaný vek 25 rokov pre linku [Lucille Phillips, 05/14/1992] [hlavný] DEBUG obtchunks.LinesWriter - napísaná linka [Adam Caldwell, 09/27/1995,22] [main] DEBUG obtchunks.LinesWriter - napísaná linka [Lucille Phillips, 05/14 / 1992,25] [main] DEBUG obtchunks.LineProcessor - linkový procesor skončil. [main] DEBUG o.b.t.chunks.LinesWriter - program na zápis riadkov sa skončil. [main] DEBUG o.b.t.chunks.LineReader - čítačka liniek skončila.

Máme rovnaký výsledok a iný tok. Z protokolov je zrejmé, ako sa úloha vykonáva podľa tohto prístupu.

6. Záver

Rôzne kontexty ukážu potrebu jedného alebo druhého prístupu. Zatiaľ čo sa Tasklety cítia pre scenáre „jedna úloha za druhou“ prirodzenejšie, bloky poskytujú jednoduché riešenie, ako zvládnuť stránkované čítania alebo situácie, keď nechceme ponechať značné množstvo údajov v pamäti.

Kompletnú implementáciu tohto príkladu nájdete v projekt GitHub.


$config[zx-auto] not found$config[zx-overlay] not found