{"id":16873876,"url":"https://github.com/nurkiewicz/reactor-workshop","last_synced_at":"2025-10-04T12:51:46.265Z","repository":{"id":37828667,"uuid":"146503569","full_name":"nurkiewicz/reactor-workshop","owner":"nurkiewicz","description":"Spring Reactor hands-on training (3 days)","archived":false,"fork":false,"pushed_at":"2023-07-21T04:58:09.000Z","size":1177,"stargazers_count":141,"open_issues_count":14,"forks_count":44,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-09-04T00:30:02.460Z","etag":null,"topics":["concurrency","java","reactor","spring","spring-boot","webflux"],"latest_commit_sha":null,"homepage":"https://nurkiewicz.com/slides/reactor-workshop","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nurkiewicz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-28T20:33:10.000Z","updated_at":"2025-08-13T11:19:07.000Z","dependencies_parsed_at":"2024-10-27T12:11:15.347Z","dependency_job_id":"ac35dfa6-8e68-4de6-b546-f5f098bf5606","html_url":"https://github.com/nurkiewicz/reactor-workshop","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nurkiewicz/reactor-workshop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nurkiewicz%2Freactor-workshop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nurkiewicz%2Freactor-workshop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nurkiewicz%2Freactor-workshop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nurkiewicz%2Freactor-workshop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nurkiewicz","download_url":"https://codeload.github.com/nurkiewicz/reactor-workshop/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nurkiewicz%2Freactor-workshop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278315198,"owners_count":25966775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-04T02:00:05.491Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["concurrency","java","reactor","spring","spring-boot","webflux"],"created_at":"2024-10-13T15:28:04.692Z","updated_at":"2025-10-04T12:51:46.250Z","avatar_url":"https://github.com/nurkiewicz.png","language":"Java","readme":"# Reactor training\n\n[![Java CI master](https://github.com/nurkiewicz/reactor-workshop/actions/workflows/gradle.yml/badge.svg)](https://github.com/nurkiewicz/reactor-workshop/actions/workflows/gradle.yml) [![Java CI solutions](https://github.com/nurkiewicz/reactor-workshop/actions/workflows/gradle.yml/badge.svg?branch=solutions)](https://github.com/nurkiewicz/reactor-workshop/actions/workflows/gradle.yml)\n\nSpring [Reactor](https://projectreactor.io) hands-on training (3 days)\n\nSee also [workshop notes](https://nurkiewicz.com/slides/reactor-workshop).\n\n## Day 1: Introduction\n\n- What is reactive programming\n- Crash course to `CompletableFuture` and thread pools\n- Introducing Reactor\n- How to create a stream?\n  - `just()`, `generate()`, `create()`, `fromCallable()`, `fromStream()`\n- Laziness\n  - Hot vs. cold\n- Basic operators\n  - `map()`, `filter()`, `filterWhen()` `flatMap()`, `handle()`, `take()`, `skip()`\n  - `doOn*()` operators\n  - `window()`, `buffer()`, `distinct()`\n  - `cast()`, `ofType()`, `index()`\n  - `timestamp()`, `elapsed()`\n  - `zip()`, `merge()`\n- Error handling\n  - `timeout()`, `retry*()`, `retryBackoff()`\n  - `onError*()`\n- Blocking and reactive, back and forth\n- Concurrency with blocking code and thread pools\n  - `subscribeOn()`, `parallel()`\n- Unit testing\n\n## Day 2: Reactor advanced\n- Concurrency with non-blocking code\n- Advanced error handling and retries\n- `transform()` vs. `transformDeferred()`\n- Advanced operators\n  - `groupBy()`, `window()`\n  - `reduce()`, `scan()`\n  - `expand*()`\n- Backpressure\n  - `onBackpressure*()`\n- `Processor` API\n  - `Unicast`, `Emitter`, `Replay`\n- Advanced testing with virtual time\n- `Context`\n- Speculative execution example\n- [RxJava](https://github.com/ReactiveX/RxJava) interoperability\n\n## Day 3: Practical\n- Comparison to blocking and asynchronous servlets\n- Refactoring existing application to Reactor\n- [Spring Boot](https://spring.io/projects/spring-boot)\n  - Reactive database access\n  - Reactive controllers\n  - `WebFilter`\n  - Global error handling\n  - Payload validation\n  - Web sockets\n- Streaming data in and out\n- Troubleshooting and debugging\n  - `checkpoint()`, `onOperatorDebug()`, `doOn*()`\n\n## Reference materials\n\n1. [Reactor 3 Reference Guide](https://projectreactor.io/docs/core/release/reference/)\n2. [Web on Reactive Stack](https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#spring-webflux) in [Spring Framework Documentation](https://docs.spring.io/spring/docs/current/spring-framework-reference/index.html)\n3. [The \"Spring WebFlux Framework\"](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html#boot-features-webflux) in [Spring Boot Reference Guide](https://docs.spring.io/spring-boot/docs/current/reference/html/)\n\n## Troubleshooting, tips and tricks\n\n### IntelliJ test runner\n\nIn IntelliJ it's much faster to run tests directly, rather than through Gradle.\nGo to `Preferences` -\u003e `Build, Execution, Deployment` -\u003e `Build Tools` -\u003e `Gradle` and select `IntelliJ IDEA` from `Run Tests Using` drop-down.\n\n### Error `Can not connect to Ryuk at localhost:...`\n\nAdd this environment variable:\n\n```\nTESTCONTAINERS_RYUK_DISABLED=true\n```\n\nSee: [Disabling Ryuk](https://www.testcontainers.org/features/configuration/#disabling-ryuk)\n\n### Reusing containers in testcontainers\n\nIn `.testcontainers.properties` in your `$HOME` folder put the following line:\n\n```\ntestcontainers.reuse.enable=true\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnurkiewicz%2Freactor-workshop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnurkiewicz%2Freactor-workshop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnurkiewicz%2Freactor-workshop/lists"}