Structured Concurrency in Practice: CoroutineScope vs StructuredTaskScope [Part 3]
This post series assumes familiarity with Kotlin, Java, and Spring Boot. No AI was used during the writing of this post series. What happened to our logs? In Part 2 we completed the entire solution...
![Structured Concurrency in Practice: CoroutineScope vs StructuredTaskScope [Part 3]](https://media2.dev.to/dynamic/image/width=1200,height=627,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbtvcieep4ui7lsng90zv.jpg)
Source: DEV Community
This post series assumes familiarity with Kotlin, Java, and Spring Boot. No AI was used during the writing of this post series. What happened to our logs? In Part 2 we completed the entire solution, both the happy path and the sad paths. Here's what we ended up with: @RestController @RequestMapping("/books") class BooksController( private val booksRepository: BooksRepository, private val reviewsService: ReviewsService, ) { private val log = LoggerFactory.getLogger(BooksController::class.java) @GetMapping("/{id}") fun fetchBook(@PathVariable id: Long): Book = runBlocking(Dispatchers.IO) { log.info("[START] $id") val book = async { findBook(id) } val reviews = async { fetchReviewsFor(id) } book.await() .copy(reviews = reviews.await()) .also { log.info("[SUCCESS] Returning ${it.id}") } } private suspend fun findBook(id: Long) = runInterruptible { booksRepository.findById(id) ?: throw BookNotFoundException(id) } private suspend fun fetchReviewsFor(id: Long) = runInterruptible { reviewsServ