Skip to content

Commit e945701

Browse files
Spotless
1 parent 2e98990 commit e945701

File tree

2 files changed

+60
-75
lines changed
  • stream-android-core/src

2 files changed

+60
-75
lines changed

stream-android-core/src/main/java/io/getstream/android/core/api/utils/Threading.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ import java.util.concurrent.TimeUnit
4040
*
4141
* ### Exception Handling
4242
* - Exceptions thrown by [block] are captured and returned as `Result.failure`
43-
* - [CancellationException][kotlin.coroutines.cancellation.CancellationException] is rethrown
44-
* to preserve coroutine cancellation semantics
43+
* - [CancellationException][kotlin.coroutines.cancellation.CancellationException] is rethrown to
44+
* preserve coroutine cancellation semantics
4545
* - If the main looper is not initialized, throws [IllegalStateException]
4646
*
4747
* ### Use Cases
@@ -51,6 +51,7 @@ import java.util.concurrent.TimeUnit
5151
* - Synchronizing with main thread state before proceeding
5252
*
5353
* ### Example Usage
54+
*
5455
* ```kotlin
5556
* // From a background thread, safely add a lifecycle observer
5657
* runOnMainLooper {
@@ -76,7 +77,6 @@ import java.util.concurrent.TimeUnit
7677
* @return [Result.success] with the return value of [block], or [Result.failure] if an exception
7778
* was thrown
7879
* @throws IllegalStateException if the main looper is not initialized or if execution times out
79-
*
8080
* @see runOn for executing on a custom [Looper]
8181
*/
8282
@StreamInternalApi
@@ -101,20 +101,21 @@ public inline fun <T> runOnMainLooper(crossinline block: () -> T): Result<T> =
101101
*
102102
* ### Timeout
103103
* If the target looper does not execute [block] within **5 seconds**, this function throws
104-
* [IllegalStateException]. This prevents indefinite blocking if the target thread is stuck
105-
* or the looper is not running.
104+
* [IllegalStateException]. This prevents indefinite blocking if the target thread is stuck or the
105+
* looper is not running.
106106
*
107107
* ### Exception Handling
108108
* - Exceptions thrown by [block] are captured and returned as `Result.failure`
109-
* - [CancellationException][kotlin.coroutines.cancellation.CancellationException] is rethrown
110-
* to preserve coroutine cancellation semantics
109+
* - [CancellationException][kotlin.coroutines.cancellation.CancellationException] is rethrown to
110+
* preserve coroutine cancellation semantics
111111
*
112112
* ### Use Cases
113113
* - Executing code on a custom [HandlerThread][android.os.HandlerThread]'s looper
114114
* - Synchronizing operations across multiple threads with known loopers
115115
* - Testing thread-specific behavior with custom test loopers
116116
*
117117
* ### Example Usage
118+
*
118119
* ```kotlin
119120
* // Execute on a custom background thread
120121
* val handlerThread = HandlerThread("worker").apply { start() }
@@ -152,7 +153,6 @@ public inline fun <T> runOnMainLooper(crossinline block: () -> T): Result<T> =
152153
* @return [Result.success] with the return value of [block], or [Result.failure] if an exception
153154
* was thrown
154155
* @throws IllegalStateException if execution times out after 5 seconds
155-
*
156156
* @see runOnMainLooper for a convenience function that always uses the main looper
157157
*/
158158
@StreamInternalApi
@@ -179,4 +179,4 @@ public inline fun <T> runOn(looper: Looper, crossinline block: () -> T): Result<
179179
result!!.getOrThrow()
180180
}
181181
}
182-
}
182+
}

stream-android-core/src/test/java/io/getstream/android/core/api/utils/ThreadingTest.kt

Lines changed: 51 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package io.getstream.android.core.api.utils
1818

1919
import android.os.Build
20-
import android.os.Handler
2120
import android.os.HandlerThread
2221
import android.os.Looper
2322
import java.util.concurrent.CountDownLatch
@@ -128,9 +127,7 @@ class ThreadingTest {
128127
fun `runOnMainLooper executes block exactly once on success`() {
129128
val callCount = AtomicInteger(0)
130129

131-
val result = runOnMainLooper {
132-
callCount.incrementAndGet()
133-
}
130+
val result = runOnMainLooper { callCount.incrementAndGet() }
134131

135132
assertTrue(result.isSuccess)
136133
assertEquals(1, callCount.get())
@@ -141,10 +138,11 @@ class ThreadingTest {
141138
val callCount = AtomicInteger(0)
142139
val exception = RuntimeException("error")
143140

144-
val result = runOnMainLooper<Unit> {
145-
callCount.incrementAndGet()
146-
throw exception
147-
}
141+
val result =
142+
runOnMainLooper<Unit> {
143+
callCount.incrementAndGet()
144+
throw exception
145+
}
148146

149147
assertTrue(result.isFailure)
150148
assertSame(exception, result.exceptionOrNull())
@@ -161,9 +159,7 @@ class ThreadingTest {
161159
repeat(5) { index ->
162160
thread(start = true, name = "ThreadingTest-worker-$index") {
163161
val result = runOnMainLooper { index }
164-
synchronized(results) {
165-
results.add(result.getOrThrow())
166-
}
162+
synchronized(results) { results.add(result.getOrThrow()) }
167163
completed.countDown()
168164
}
169165
}
@@ -215,10 +211,11 @@ class ThreadingTest {
215211
val mainLooper = Looper.getMainLooper()
216212
val executionThread = AtomicReference<Thread?>()
217213

218-
val result = runOn(mainLooper) {
219-
executionThread.set(Thread.currentThread())
220-
Looper.myLooper()
221-
}
214+
val result =
215+
runOn(mainLooper) {
216+
executionThread.set(Thread.currentThread())
217+
Looper.myLooper()
218+
}
222219

223220
assertTrue(result.isSuccess)
224221
assertEquals(mainLooper, result.getOrNull())
@@ -233,10 +230,11 @@ class ThreadingTest {
233230
val completed = CountDownLatch(1)
234231

235232
thread(start = true, name = "ThreadingTest-worker") {
236-
val result = runOn(mainLooper) {
237-
executionThread.set(Thread.currentThread())
238-
"success"
239-
}
233+
val result =
234+
runOn(mainLooper) {
235+
executionThread.set(Thread.currentThread())
236+
"success"
237+
}
240238

241239
assertTrue(result.isSuccess)
242240
assertEquals("success", result.getOrNull())
@@ -260,10 +258,11 @@ class ThreadingTest {
260258
val completed = CountDownLatch(1)
261259

262260
thread(start = true, name = "ThreadingTest-caller") {
263-
val result = runOn(customLooper) {
264-
executionThread.set(Thread.currentThread())
265-
Looper.myLooper()
266-
}
261+
val result =
262+
runOn(customLooper) {
263+
executionThread.set(Thread.currentThread())
264+
Looper.myLooper()
265+
}
267266

268267
assertTrue(result.isSuccess)
269268
assertEquals(customLooper, result.getOrNull())
@@ -285,9 +284,7 @@ class ThreadingTest {
285284
val completed = CountDownLatch(1)
286285

287286
thread(start = true, name = "ThreadingTest-worker") {
288-
val result = runOn(mainLooper) {
289-
throw exception
290-
}
287+
val result = runOn(mainLooper) { throw exception }
291288

292289
assertTrue(result.isFailure)
293290
assertSame(exception, result.exceptionOrNull())
@@ -305,9 +302,7 @@ class ThreadingTest {
305302
val mainLooper = Looper.getMainLooper()
306303

307304
assertFailsWith<CancellationException> {
308-
runOn(mainLooper) {
309-
throw CancellationException("cancelled")
310-
}
305+
runOn(mainLooper) { throw CancellationException("cancelled") }
311306
}
312307
}
313308

@@ -316,10 +311,11 @@ class ThreadingTest {
316311
val mainLooper = Looper.getMainLooper()
317312
val callCount = AtomicInteger(0)
318313

319-
val result = runOn(mainLooper) {
320-
callCount.incrementAndGet()
321-
"done"
322-
}
314+
val result =
315+
runOn(mainLooper) {
316+
callCount.incrementAndGet()
317+
"done"
318+
}
323319

324320
assertTrue(result.isSuccess)
325321
assertEquals("done", result.getOrNull())
@@ -352,10 +348,11 @@ class ThreadingTest {
352348
val mainThread = Thread.currentThread()
353349
val executionThread = AtomicReference<Thread?>()
354350

355-
val result = runOn(backgroundLooper) {
356-
executionThread.set(Thread.currentThread())
357-
"from-background"
358-
}
351+
val result =
352+
runOn(backgroundLooper) {
353+
executionThread.set(Thread.currentThread())
354+
"from-background"
355+
}
359356

360357
assertTrue(result.isSuccess)
361358
assertEquals("from-background", result.getOrNull())
@@ -375,12 +372,11 @@ class ThreadingTest {
375372
val looper1 = thread1.looper
376373
val looper2 = thread2.looper
377374

378-
val result1 = runOn(looper1) {
379-
val result2 = runOn(looper2) {
380-
Looper.myLooper()
375+
val result1 =
376+
runOn(looper1) {
377+
val result2 = runOn(looper2) { Looper.myLooper() }
378+
result2.getOrThrow() to Looper.myLooper()
381379
}
382-
result2.getOrThrow() to Looper.myLooper()
383-
}
384380

385381
assertTrue(result1.isSuccess)
386382
val (innerLooper, outerLooper) = result1.getOrThrow()
@@ -417,11 +413,8 @@ class ThreadingTest {
417413
val resultRef = AtomicReference<Result<Unit>?>()
418414

419415
thread(start = true, name = "ThreadingTest-nested-worker") {
420-
val result = runOn(customLooper) {
421-
runOn(mainLooper) {
422-
throw exception
423-
}.getOrThrow()
424-
}
416+
val result =
417+
runOn(customLooper) { runOn(mainLooper) { throw exception }.getOrThrow() }
425418
resultRef.set(result)
426419
completed.countDown()
427420
}
@@ -449,11 +442,10 @@ class ThreadingTest {
449442
handlerThread.join(1000)
450443

451444
// This should timeout because the looper is no longer processing messages
452-
val exception = assertFailsWith<IllegalStateException> {
453-
runOn(stoppedLooper) {
454-
"should-not-execute"
455-
}.getOrThrow()
456-
}
445+
val exception =
446+
assertFailsWith<IllegalStateException> {
447+
runOn(stoppedLooper) { "should-not-execute" }.getOrThrow()
448+
}
457449

458450
assertTrue(exception.message?.contains("Timed out") == true)
459451
}
@@ -469,9 +461,7 @@ class ThreadingTest {
469461
repeat(10) { index ->
470462
thread(start = true, name = "ThreadingTest-worker-$index") {
471463
val result = runOn(customLooper) { index }
472-
synchronized(results) {
473-
results.add(result.getOrThrow())
474-
}
464+
synchronized(results) { results.add(result.getOrThrow()) }
475465
completed.countDown()
476466
}
477467
}
@@ -489,9 +479,7 @@ class ThreadingTest {
489479
val mainLooper = Looper.getMainLooper()
490480
val exception = IllegalStateException("custom error")
491481

492-
val result = runOn(mainLooper) {
493-
throw exception
494-
}
482+
val result = runOn(mainLooper) { throw exception }
495483

496484
assertTrue(result.isFailure)
497485
val caught = result.exceptionOrNull()
@@ -514,12 +502,11 @@ class ThreadingTest {
514502
val resultRef = AtomicReference<Pair<Thread, Thread>?>()
515503

516504
thread(start = true, name = "ThreadingTest-integration-worker") {
517-
val result = runOn(customLooper) {
518-
val mainResult = runOnMainLooper {
519-
Thread.currentThread()
505+
val result =
506+
runOn(customLooper) {
507+
val mainResult = runOnMainLooper { Thread.currentThread() }
508+
mainResult.getOrThrow() to Thread.currentThread()
520509
}
521-
mainResult.getOrThrow() to Thread.currentThread()
522-
}
523510
resultRef.set(result.getOrThrow())
524511
completed.countDown()
525512
}
@@ -548,9 +535,7 @@ class ThreadingTest {
548535
repeat(count) { index ->
549536
thread(start = true, name = "ThreadingTest-stress-$index") {
550537
val result = runOnMainLooper { index }
551-
synchronized(results) {
552-
results.add(result.getOrThrow())
553-
}
538+
synchronized(results) { results.add(result.getOrThrow()) }
554539
completed.countDown()
555540
}
556541
}

0 commit comments

Comments
 (0)