1
+ /*
2
+ * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3
+ */
4
+
5
+ package kotlinx.coroutines.flow
6
+
7
+ import kotlinx.atomicfu.*
8
+ import kotlinx.coroutines.*
9
+ import org.junit.*
10
+ import org.junit.Test
11
+ import kotlin.collections.ArrayList
12
+ import kotlin.test.*
13
+ import kotlin.time.*
14
+
15
+ @ExperimentalTime
16
+ class SharedFlowStressTest : TestBase () {
17
+ private val nProducers = 5
18
+ private val nConsumers = 3
19
+ private val nSeconds = 3 * stressTestMultiplier
20
+
21
+ private val sf: MutableSharedFlow <Long > = MutableSharedFlow (1 )
22
+ private val view: SharedFlow <Long > = sf.asSharedFlow()
23
+
24
+ @get:Rule
25
+ val producerDispatcher = ExecutorRule (nProducers)
26
+ @get:Rule
27
+ val consumerDispatcher = ExecutorRule (nConsumers)
28
+
29
+ private val totalProduced = atomic(0L )
30
+ private val totalConsumed = atomic(0L )
31
+
32
+ @Test
33
+ fun testStress () = runTest {
34
+ val jobs = ArrayList <Job >()
35
+ jobs + = List (nProducers) { producerIndex ->
36
+ launch(producerDispatcher) {
37
+ var cur = producerIndex.toLong()
38
+ while (isActive) {
39
+ sf.emit(cur)
40
+ totalProduced.incrementAndGet()
41
+ cur + = nProducers
42
+ }
43
+ }
44
+ }
45
+ jobs + = List (nConsumers) { consumerIndex ->
46
+ launch(consumerDispatcher) {
47
+ while (isActive) {
48
+ view
49
+ .dropWhile { it % nConsumers != consumerIndex.toLong() }
50
+ .take(1 )
51
+ .collect {
52
+ check(it % nConsumers == consumerIndex.toLong())
53
+ totalConsumed.incrementAndGet()
54
+ }
55
+ }
56
+ }
57
+ }
58
+ var lastProduced = 0L
59
+ var lastConsumed = 0L
60
+ for (sec in 1 .. nSeconds) {
61
+ delay(1 .seconds)
62
+ val produced = totalProduced.value
63
+ val consumed = totalConsumed.value
64
+ println (" $sec sec: produced = $produced ; consumed = $consumed " )
65
+ assertNotEquals(lastProduced, produced)
66
+ assertNotEquals(lastConsumed, consumed)
67
+ lastProduced = produced
68
+ lastConsumed = consumed
69
+ }
70
+ jobs.forEach { it.cancel() }
71
+ jobs.forEach { it.join() }
72
+ println (" total: produced = ${totalProduced.value} ; consumed = ${totalConsumed.value} " )
73
+ }
74
+
75
+ private fun showStats (s : String ) {
76
+ }
77
+ }
0 commit comments