Mutex lock on flush#36
Conversation
This change allows PureeLogger to operate without a lifecycle, which is primarily relevant for iOS where a default lifecycle isn't always available or necessary.
On Android, PureeLogger continues to use ProcessLifecycleOwner by default.
Key changes:
- `DefaultLifecycleOwner` has been removed.
- `PureeLogger` now accepts a nullable `Lifecycle`. If null, it immediately calls `resume()`.
- The iOS `Puree.build()` method now passes `null` for the lifecycle.
- The Android `Puree` constructor now directly uses `ProcessLifecycleOwner.get().lifecycle`.
- `PureeBufferedOutput.resume()` is now a suspend function and uses a Mutex for `requestFlush` to prevent concurrent flush operations.
- Updated iOS sample app:
- Added a "Flush!" button to manually trigger flushing.
- Modified `OSLogBufferedOutput` to simulate a delay in `emit` for testing purposes.
- Adjusted `AddTimeFilter` to include fractional seconds in the timestamp.
This commit refactors how CoroutineScope is created and used within `PureeLogger` and `PureeBufferedOutput`.
- `PureeLogger`:
- Now directly accepts a `CoroutineContext` (renamed from `dispatcher`) in its constructor.
- The internal `scope` is initialized directly with this context.
- The `CoroutineExceptionHandler` and `SupervisorJob` are now configured at the platform-specific `Puree` builder level (`Puree.android.kt` and `Puree.ios.kt`) and passed into `PureeLogger`.
- `PureeBufferedOutput`:
- The `initialize` method now accepts a `CoroutineScope` directly instead of a `CoroutineContext`.
- This simplifies the initialization as the `CoroutineExceptionHandler` and `SupervisorJob` are now handled by the `CoroutineScope` provided by `PureeLogger`.
This change aims to centralize the CoroutineScope configuration at the builder level, making the core components more focused on their specific responsibilities and improving testability by allowing injection of a pre-configured scope.
| * @see resume | ||
| */ | ||
| internal suspend fun requestFlush() { | ||
| internal suspend fun requestFlush() = flushMutex.withLock { |
There was a problem hiding this comment.
Mutex を用いて二重に呼ばれないように調整します。
| coroutineScope.launch { | ||
| internal suspend fun resume() { | ||
| workerJob?.cancelAndJoin() | ||
| workerJob = coroutineScope.launch { |
There was a problem hiding this comment.
resume が二重に呼ばれないようにも調整します
| ) | ||
| if (lifecycle != null) { | ||
| lifecycle.addObserver( | ||
| object : DefaultLifecycleObserver { |
There was a problem hiding this comment.
iOS で onResume を返すだけの LifecycleOwner を作って使用していましたが、これが悪さしている可能性をなくすため、nullable にして ios では null を渡すようにしています。
| internal var dispatcher: CoroutineDispatcher = newSingleThreadContext("PureeLogger") | ||
| internal val dispatcher = newSingleThreadContext("PureeLogger") | ||
| .plus(SupervisorJob()) | ||
| .plus( |
There was a problem hiding this comment.
dispatcher を puree 全体で統一しています
This commit introduces a new output class, `PurgeableOSLogWarningBufferedOutput`, specifically for `PeriodicLog` types. Additionally, comments were updated in `OSLogBufferedOutput.swift` and minor formatting adjustments were made in `AddTimeFilter.swift`.
| internal fun resume() { | ||
| coroutineScope.launch { | ||
| internal suspend fun resume() { | ||
| workerJob?.cancelAndJoin() |
There was a problem hiding this comment.
resume はどのスレッドから呼ばれる想定ですか?
もしメインスレッドで実行されていた場合、 cancelAndJoin によって workerJob が完了するまでメインスレッドをブロックしないか少し心配しています。
There was a problem hiding this comment.
https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/new-single-thread-context.html によると、newSingleThreadContext は占有のスレッドを新しく立ち上げて用いるようです。
そのためスレッドプールも IO や Main とは異なり、メインスレッドが割り当てられることはありません。
There was a problem hiding this comment.
良さそう。調査ありがとうございました。
|
レビューありがとうございました 🙏 |
Related links
Why?
How?
flushが二重に走ることのないように、mutex でロックしますTesting 🔍