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:
committed by
Facebook GitHub Bot
parent
18b6ce6f24
commit
412d10b280
@@ -59,7 +59,7 @@ class UIDebuggerFlipperPlugin(
|
|||||||
MetadataUpdateEvent.name,
|
MetadataUpdateEvent.name,
|
||||||
Json.encodeToString(
|
Json.encodeToString(
|
||||||
MetadataUpdateEvent.serializer(),
|
MetadataUpdateEvent.serializer(),
|
||||||
MetadataUpdateEvent(MetadataRegister.getPendingMetadata())))
|
MetadataUpdateEvent(MetadataRegister.extractPendingMetadata())))
|
||||||
|
|
||||||
context.treeObserverManager.start()
|
context.treeObserverManager.start()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,11 @@ object MetadataRegister {
|
|||||||
const val TYPE_LAYOUT = "layout"
|
const val TYPE_LAYOUT = "layout"
|
||||||
const val TYPE_DOCUMENTATION = "documentation"
|
const val TYPE_DOCUMENTATION = "documentation"
|
||||||
|
|
||||||
|
private val lock = "lock"
|
||||||
|
|
||||||
private var generator: MetadataId = 0
|
private var generator: MetadataId = 0
|
||||||
private val register: MutableMap<String, Metadata> = mutableMapOf()
|
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"
|
private fun key(namespace: String, name: String): String = "${namespace}_$name"
|
||||||
|
|
||||||
@@ -41,13 +43,15 @@ object MetadataRegister {
|
|||||||
return m.id
|
return m.id
|
||||||
}
|
}
|
||||||
|
|
||||||
val identifier = ++generator
|
synchronized(lock) {
|
||||||
val metadata = Metadata(identifier, type, namespace, name, mutable, possibleValues)
|
val identifier = ++generator
|
||||||
|
val metadata = Metadata(identifier, type, namespace, name, mutable, possibleValues)
|
||||||
|
|
||||||
register[key] = metadata
|
register[key] = metadata
|
||||||
pending.add(key)
|
pendingKeys.add(key)
|
||||||
|
|
||||||
return identifier
|
return identifier
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun get(namespace: String, name: String): Metadata? {
|
fun get(namespace: String, name: String): Metadata? {
|
||||||
@@ -55,24 +59,24 @@ object MetadataRegister {
|
|||||||
return register[key]
|
return register[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMetadata(): Map<MetadataId, Metadata> {
|
/** gets all pending metadata to be sent and resets the pending list */
|
||||||
val metadata: MutableMap<MetadataId, Metadata> = mutableMapOf()
|
fun extractPendingMetadata(): Map<MetadataId, Metadata> {
|
||||||
register.forEach { entry -> metadata[entry.value.id] = entry.value }
|
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> {
|
return pendingMetadata
|
||||||
val pendingMetadata: MutableMap<MetadataId, Metadata> = mutableMapOf()
|
|
||||||
pending.forEach { key ->
|
|
||||||
register[key]?.let { metadata -> pendingMetadata[metadata.id] = metadata }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pendingMetadata
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
pending.clear()
|
synchronized(lock) {
|
||||||
register.forEach { entry -> pending.add(entry.key) }
|
pendingKeys.clear()
|
||||||
|
register.forEach { entry -> pendingKeys.add(entry.key) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ class TreeObserverManager(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun sendMetadata() {
|
private fun sendMetadata() {
|
||||||
val metadata = MetadataRegister.getPendingMetadata()
|
val metadata = MetadataRegister.extractPendingMetadata()
|
||||||
if (metadata.size > 0) {
|
if (metadata.size > 0) {
|
||||||
context.connectionRef.connection?.send(
|
context.connectionRef.connection?.send(
|
||||||
MetadataUpdateEvent.name,
|
MetadataUpdateEvent.name,
|
||||||
|
|||||||
Reference in New Issue
Block a user