Make sure pending metadata is reset and is thread safe

Summary: We have gotton concurrent modification crashes from this

Reviewed By: lblasa

Differential Revision: D42343224

fbshipit-source-id: 9cf4046da63d40cbe6632c3ae24d95abd21081ba
This commit is contained in:
Luke De Feo
2023-01-25 04:47:11 -08:00
committed by Facebook GitHub Bot
parent 18b6ce6f24
commit 412d10b280
3 changed files with 25 additions and 21 deletions

View File

@@ -59,7 +59,7 @@ class UIDebuggerFlipperPlugin(
MetadataUpdateEvent.name,
Json.encodeToString(
MetadataUpdateEvent.serializer(),
MetadataUpdateEvent(MetadataRegister.getPendingMetadata())))
MetadataUpdateEvent(MetadataRegister.extractPendingMetadata())))
context.treeObserverManager.start()
}

View File

@@ -23,9 +23,11 @@ object MetadataRegister {
const val TYPE_LAYOUT = "layout"
const val TYPE_DOCUMENTATION = "documentation"
private val lock = "lock"
private var generator: MetadataId = 0
private val register: MutableMap<String, Metadata> = mutableMapOf()
private val pending: MutableSet<String> = mutableSetOf()
private val pendingKeys: MutableSet<String> = mutableSetOf()
private fun key(namespace: String, name: String): String = "${namespace}_$name"
@@ -41,13 +43,15 @@ object MetadataRegister {
return m.id
}
val identifier = ++generator
val metadata = Metadata(identifier, type, namespace, name, mutable, possibleValues)
synchronized(lock) {
val identifier = ++generator
val metadata = Metadata(identifier, type, namespace, name, mutable, possibleValues)
register[key] = metadata
pending.add(key)
register[key] = metadata
pendingKeys.add(key)
return identifier
return identifier
}
}
fun get(namespace: String, name: String): Metadata? {
@@ -55,24 +59,24 @@ object MetadataRegister {
return register[key]
}
fun getMetadata(): Map<MetadataId, Metadata> {
val metadata: MutableMap<MetadataId, Metadata> = mutableMapOf()
register.forEach { entry -> metadata[entry.value.id] = entry.value }
/** gets all pending metadata to be sent and resets the pending list */
fun extractPendingMetadata(): Map<MetadataId, Metadata> {
synchronized(lock) {
val pendingMetadata: MutableMap<MetadataId, Metadata> = mutableMapOf()
return metadata
}
pendingKeys.forEach { key ->
register[key]?.let { metadata -> pendingMetadata[metadata.id] = metadata }
}
pendingKeys.clear()
fun getPendingMetadata(): Map<MetadataId, Metadata> {
val pendingMetadata: MutableMap<MetadataId, Metadata> = mutableMapOf()
pending.forEach { key ->
register[key]?.let { metadata -> pendingMetadata[metadata.id] = metadata }
return pendingMetadata
}
return pendingMetadata
}
fun reset() {
pending.clear()
register.forEach { entry -> pending.add(entry.key) }
synchronized(lock) {
pendingKeys.clear()
register.forEach { entry -> pendingKeys.add(entry.key) }
}
}
}

View File

@@ -90,7 +90,7 @@ class TreeObserverManager(val context: Context) {
}
private fun sendMetadata() {
val metadata = MetadataRegister.getPendingMetadata()
val metadata = MetadataRegister.extractPendingMetadata()
if (metadata.size > 0) {
context.connectionRef.connection?.send(
MetadataUpdateEvent.name,