smengcl commented on a change in pull request #1670:
URL: https://github.com/apache/ozone/pull/1670#discussion_r551496385
##########
File path:
hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconContainerManager.java
##########
@@ -171,23 +182,93 @@ public void addNewContainer(long containerId,
/**
* Add a container Replica for given DataNode.
- *
- * @param containerID
- * @param replica
*/
@Override
public void updateContainerReplica(ContainerID containerID,
ContainerReplica replica)
throws ContainerNotFoundException {
super.updateContainerReplica(containerID, replica);
- // Update container_history table
- long currentTime = System.currentTimeMillis();
- String datanodeHost = replica.getDatanodeDetails().getHostName();
- containerSchemaManager.upsertContainerHistory(containerID.getId(),
- datanodeHost, currentTime);
+
+ final long currTime = System.currentTimeMillis();
+ final long id = containerID.getId();
+ final DatanodeDetails dnInfo = replica.getDatanodeDetails();
+ final UUID uuid = dnInfo.getUuid();
+
+ // Map from DataNode UUID to replica last seen time
+ final Map<UUID, ContainerReplicaHistory> replicaLastSeenMap =
+ replicaHistoryMap.get(id);
+
+ boolean flushToDB = false;
+
+ // If replica doesn't exist in in-memory map, add to DB and add to map
+ if (replicaLastSeenMap == null) {
+ // putIfAbsent to avoid TOCTOU
+ replicaHistoryMap.putIfAbsent(id,
+ new ConcurrentHashMap<UUID, ContainerReplicaHistory>() {{
+ put(uuid, new ContainerReplicaHistory(uuid, currTime, currTime));
+ }});
+ flushToDB = true;
+ } else {
+ // ContainerID exists, update timestamp in memory
+ final ContainerReplicaHistory ts = replicaLastSeenMap.get(uuid);
+ if (ts == null) {
+ // New Datanode
+ replicaLastSeenMap.put(uuid,
+ new ContainerReplicaHistory(uuid, currTime, currTime));
+ flushToDB = true;
+ } else {
+ // if the object exists, only update the last seen time field
+ ts.setLastSeenTime(currTime);
+ }
+ }
+
+ if (flushToDB) {
+ containerSchemaManager.upsertContainerHistory(id, uuid, currTime);
+ }
}
+ /**
+ * Remove a Container Replica of a given DataNode.
+ */
+ @Override
+ public void removeContainerReplica(ContainerID containerID,
+ ContainerReplica replica) throws ContainerNotFoundException,
+ ContainerReplicaNotFoundException {
+ super.removeContainerReplica(containerID, replica);
+
+ final long id = containerID.getId();
+ final DatanodeDetails dnInfo = replica.getDatanodeDetails();
+ final UUID uuid = dnInfo.getUuid();
+
+ final Map<UUID, ContainerReplicaHistory> replicaLastSeenMap =
+ replicaHistoryMap.get(id);
+ if (replicaLastSeenMap != null) {
+ final ContainerReplicaHistory ts = replicaLastSeenMap.get(uuid);
+ if (ts != null) {
+ // Flush to DB, then remove from in-memory map
+ containerSchemaManager.upsertContainerHistory(id, uuid,
+ ts.getLastSeenTime());
+ replicaLastSeenMap.remove(uuid);
+ }
+ }
+ }
+
+ @VisibleForTesting
public ContainerSchemaManager getContainerSchemaManager() {
return containerSchemaManager;
}
+
+ @VisibleForTesting
+ public Map<Long, Map<UUID, ContainerReplicaHistory>> getReplicaHistoryMap() {
Review comment:
It is referenced only in
`TestReconContainerManager#testUpdateContainerReplica`
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]