fix: dzienny ingest filmow nie przepada o 05:00, apka nie staje na bledzie keystore
- scheduler: misfire_grace_time 1 h zamiast domyslnej 1 s. O 05:00 UTC startuje kilkanascie
zadan naraz, movie-ingest dostawal watek 1,1 s po czasie i APScheduler go pomijal, wiec
filmy nie przychodzily od 17.09 (watchdog, Sentry).
- getDeviceId: blad SecureStore ("Could not encrypt the value", Samsung A7, Android 10)
wywalal kazde zapytanie do API. Teraz id zostaje w pamieci do konca sesji. Wejdzie z
najblizsza paczka OTA.
- latka expo-modules-core 2.2.3, JNIDeallocator: watek sprzatajacy blokowal sie na sobie,
nie na deallocatorze, stad ConcurrentModificationException przy przeladowaniu JS
(Sentry GOON-48). Wejdzie z najblizszym APK.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
73853eb9ed
commit
ca2a6a1547
3 changed files with 52 additions and 3 deletions
|
|
@ -525,7 +525,12 @@ def build_scheduler(cfg: dict[str, Any]) -> BlockingScheduler:
|
||||||
performer_continuous_seconds: int | None
|
performer_continuous_seconds: int | None
|
||||||
performer_continuous_refresh_days: int
|
performer_continuous_refresh_days: int
|
||||||
"""
|
"""
|
||||||
sched = BlockingScheduler(timezone="UTC")
|
# misfire_grace_time: domyslnie 1 s. O 05:00 UTC (wspolny anchor) startuje kilkanascie
|
||||||
|
# zadan naraz i dzienny movie-ingest dostawal watek 1,1 s po czasie, wiec APScheduler go
|
||||||
|
# POMIJAL ("was missed by 0:00:01"), dzien w dzien. Filmy staly 4-8 dni, zanim watchdog
|
||||||
|
# to pokazal (2026-09-19). Godzina zapasu; coalesce i max_instances=1 i tak zbijaja
|
||||||
|
# zaleglosci w jedno uruchomienie.
|
||||||
|
sched = BlockingScheduler(timezone="UTC", job_defaults={"misfire_grace_time": 3600})
|
||||||
|
|
||||||
sched.add_job(
|
sched.add_job(
|
||||||
_job_site_icons,
|
_job_site_icons,
|
||||||
|
|
|
||||||
31
mobile/patches/expo-modules-core+2.2.3.patch
Normal file
31
mobile/patches/expo-modules-core+2.2.3.patch
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
diff --git a/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt b/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt
|
||||||
|
--- a/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt
|
||||||
|
+++ b/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt
|
||||||
|
@@ -34,7 +34,10 @@ class JNIDeallocator(shouldCreateDestructorThread: Boolean = true) : AutoCloseab
|
||||||
|
// Referent of PhantomReference were garbage collected so we can remove it from our registry.
|
||||||
|
// Note that we don't have to call `deallocate` method - it was called [com.facebook.jni.HybridData].
|
||||||
|
val current = referenceQueue.remove()
|
||||||
|
- synchronized(this) {
|
||||||
|
+ // Goon: `this` w `object : Thread` to watek, nie deallocator. Blokada na watku
|
||||||
|
+ // nic nie chronila i remove szedl rownolegle z iteracja w deallocate(), stad
|
||||||
|
+ // ConcurrentModificationException przy przeladowaniu JS (Sentry GOON-48).
|
||||||
|
+ synchronized(this@JNIDeallocator) {
|
||||||
|
destructorMap.remove(current)
|
||||||
|
}
|
||||||
|
} catch (e: InterruptedException) {
|
||||||
|
@@ -65,10 +68,13 @@ class JNIDeallocator(shouldCreateDestructorThread: Boolean = true) : AutoCloseab
|
||||||
|
* Deallocates valid references and clears the internal registry.
|
||||||
|
*/
|
||||||
|
internal fun deallocate() = synchronized(this) {
|
||||||
|
- destructorMap.values.forEach {
|
||||||
|
+ // Goon: kopia przed wolaniem deallocate(), ktore moze wrocic do tej mapy z tego
|
||||||
|
+ // samego watku (blokada jest reentrant, wiec by nie zatrzymala), GOON-48.
|
||||||
|
+ val refs = destructorMap.values.toList()
|
||||||
|
+ destructorMap.clear()
|
||||||
|
+ refs.forEach {
|
||||||
|
it.get()?.deallocate()
|
||||||
|
}
|
||||||
|
- destructorMap.clear()
|
||||||
|
destructorThread?.interrupt()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -18,10 +18,23 @@ function _genDeviceId(): string {
|
||||||
|
|
||||||
export async function getDeviceId(): Promise<string> {
|
export async function getDeviceId(): Promise<string> {
|
||||||
if (_deviceIdCache) return _deviceIdCache;
|
if (_deviceIdCache) return _deviceIdCache;
|
||||||
let id = await SecureStore.getItemAsync(DEVICE_KEY);
|
// Keystore potrafi odmowic ("Could not encrypt the value for key 'goon.device_id'",
|
||||||
|
// Samsung A7 z Androidem 10, Sentry 2026-09-19). Kazde zapytanie do API czeka na to id,
|
||||||
|
// wiec wyjatek stad wylaczal cala apke. Teraz id zostaje w pamieci do konca sesji; bez
|
||||||
|
// zapisu po restarcie powstanie nowe, ale apka dziala.
|
||||||
|
let id: string | null = null;
|
||||||
|
try {
|
||||||
|
id = await SecureStore.getItemAsync(DEVICE_KEY);
|
||||||
|
} catch {
|
||||||
|
id = null;
|
||||||
|
}
|
||||||
if (!id) {
|
if (!id) {
|
||||||
id = _genDeviceId();
|
id = _genDeviceId();
|
||||||
|
try {
|
||||||
await SecureStore.setItemAsync(DEVICE_KEY, id);
|
await SecureStore.setItemAsync(DEVICE_KEY, id);
|
||||||
|
} catch {
|
||||||
|
// zostaje tylko w _deviceIdCache
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_deviceIdCache = id;
|
_deviceIdCache = id;
|
||||||
return id;
|
return id;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue