Bear in mind not every annotation for joining table is lazy-loading by default (eager-loading harms the data migration speed significantly).
We have studied how to create rate-limited concurrent tasks in golang here. With kotlin we can immitate the same concept directly!
1 suspend fun createDefaultTags() = coroutineScope {
2 val batchSize = 20
3 val total = teamRepository.count().toDouble()
4 val totalPages = Math.ceil(total/batchSize).toInt()
5 println("BatchSize: $batchSize, Pages: $totalPages")
6
7 val latch = CountDownLatch(totalPages)
8 val channel = kotlinx.coroutines.channels.Channel<Unit>(5)
9
10 for (page in 0..<totalPages) {
11 launch(Dispatchers.IO) {
12 try {
13 channel.send(Unit)
14 batchInsertTags(page, batchSize, totalPages)
15 } catch (e: Exception) {
16 throw e
17 } finally {
18 channel.receive()
19 latch.countDown()
20 }
21 }
22 }
23 println("Waiting for everything to finish ...")
24 latch.await()
25 println("Finished!")
26 }
In otherwords,
CountDownLatch plays the role as sync.WaitGroup and
Channel<Unit> plays the role as chan struct{}.