Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ public String getSnapshotsParentDir() {
return snapshotsParentDir;
}

@Override
public RocksDBCheckpointDiffer getRocksDBCheckpointDiffer() {
return rocksDBCheckpointDiffer;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -697,10 +697,12 @@ public BackgroundService getMultipartUploadCleanupService() {
return multipartUploadCleanupService;
}

@Override
public SstFilteringService getSnapshotSstFilteringService() {
return snapshotSstFilteringService;
}

@Override
public SnapshotDeletingService getSnapshotDeletingService() {
return snapshotDeletingService;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.ozone.rocksdiff.RocksDBCheckpointDiffer;

import org.apache.ratis.thirdparty.com.google.common.base.Preconditions;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -55,6 +56,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If suggestion to use list is accepted, this becomes unused.

Suggested change
import java.util.Optional;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. PTAL.

import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -644,29 +646,42 @@ public BootstrapStateHandler.Lock getBootstrapStateLock() {
}

static class Lock extends BootstrapStateHandler.Lock {
private final BootstrapStateHandler keyDeletingService;
private final BootstrapStateHandler sstFilteringService;
private final BootstrapStateHandler rocksDbCheckpointDiffer;
private final BootstrapStateHandler snapshotDeletingService;
private final Optional<BootstrapStateHandler> keyDeletingService;
private final Optional<BootstrapStateHandler> sstFilteringService;
private final Optional<BootstrapStateHandler> rocksDbCheckpointDiffer;
private final Optional<BootstrapStateHandler> snapshotDeletingService;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private final Optional<BootstrapStateHandler> keyDeletingService;
private final Optional<BootstrapStateHandler> sstFilteringService;
private final Optional<BootstrapStateHandler> rocksDbCheckpointDiffer;
private final Optional<BootstrapStateHandler> snapshotDeletingService;
private final List<BootstrapStateHandler.Lock> locks;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion. Updated.

private final OzoneManager om;

Lock(OzoneManager om) {
Preconditions.checkNotNull(om);
Preconditions.checkNotNull(om.getKeyManager());
Preconditions.checkNotNull(om.getMetadataManager());
Preconditions.checkNotNull(om.getMetadataManager().getStore());

this.om = om;
keyDeletingService = om.getKeyManager().getDeletingService();
sstFilteringService = om.getKeyManager().getSnapshotSstFilteringService();
rocksDbCheckpointDiffer = om.getMetadataManager().getStore()
.getRocksDBCheckpointDiffer();
snapshotDeletingService = om.getKeyManager().getSnapshotDeletingService();
keyDeletingService = Optional.ofNullable(om.getKeyManager().getDeletingService());
sstFilteringService = Optional.ofNullable(om.getKeyManager().getSnapshotSstFilteringService());
rocksDbCheckpointDiffer = Optional.ofNullable(om.getMetadataManager().getStore()
.getRocksDBCheckpointDiffer());
snapshotDeletingService = Optional.ofNullable(om.getKeyManager().getSnapshotDeletingService());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
keyDeletingService = Optional.ofNullable(om.getKeyManager().getDeletingService());
sstFilteringService = Optional.ofNullable(om.getKeyManager().getSnapshotSstFilteringService());
rocksDbCheckpointDiffer = Optional.ofNullable(om.getMetadataManager().getStore()
.getRocksDBCheckpointDiffer());
snapshotDeletingService = Optional.ofNullable(om.getKeyManager().getSnapshotDeletingService());
locks = Stream.of(
om.getKeyManager().getDeletingService(),
om.getKeyManager().getSnapshotSstFilteringService(),
om.getMetadataManager().getStore().getRocksDBCheckpointDiffer(),
om.getKeyManager().getSnapshotDeletingService()
)
.filter(Objects::nonNull)
.map(BootstrapStateHandler::getBootstrapStateLock)
.collect(Collectors.toList());

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. PTAL.

}

@Override
public BootstrapStateHandler.Lock lock()
throws InterruptedException {
// First lock all the handlers.
keyDeletingService.getBootstrapStateLock().lock();
sstFilteringService.getBootstrapStateLock().lock();
rocksDbCheckpointDiffer.getBootstrapStateLock().lock();
snapshotDeletingService.getBootstrapStateLock().lock();
if (keyDeletingService.isPresent()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can changed to ifPresent.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since lock throws InterruptedException (unlike unlock), it might not be possible to use ifPresent.

keyDeletingService.get().getBootstrapStateLock().lock();
}
if (sstFilteringService.isPresent()) {
sstFilteringService.get().getBootstrapStateLock().lock();
}
if (rocksDbCheckpointDiffer.isPresent()) {
rocksDbCheckpointDiffer.get().getBootstrapStateLock().lock();
}
if (snapshotDeletingService.isPresent()) {
snapshotDeletingService.get().getBootstrapStateLock().lock();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (keyDeletingService.isPresent()) {
keyDeletingService.get().getBootstrapStateLock().lock();
}
if (sstFilteringService.isPresent()) {
sstFilteringService.get().getBootstrapStateLock().lock();
}
if (rocksDbCheckpointDiffer.isPresent()) {
rocksDbCheckpointDiffer.get().getBootstrapStateLock().lock();
}
if (snapshotDeletingService.isPresent()) {
snapshotDeletingService.get().getBootstrapStateLock().lock();
}
for (BootstrapStateHandler.Lock lock : locks) {
lock.lock();
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. PTAL.


// Then wait for the double buffer to be flushed.
om.awaitDoubleBufferFlush();
Expand All @@ -675,10 +690,11 @@ public BootstrapStateHandler.Lock lock()

@Override
public void unlock() {
snapshotDeletingService.getBootstrapStateLock().unlock();
rocksDbCheckpointDiffer.getBootstrapStateLock().unlock();
sstFilteringService.getBootstrapStateLock().unlock();
keyDeletingService.getBootstrapStateLock().unlock();
snapshotDeletingService.ifPresent(deletingService -> deletingService.getBootstrapStateLock().unlock());
rocksDbCheckpointDiffer.ifPresent(
rocksDBCheckpointDiffer -> rocksDBCheckpointDiffer.getBootstrapStateLock().unlock());
sstFilteringService.ifPresent(filteringService -> filteringService.getBootstrapStateLock().unlock());
keyDeletingService.ifPresent(deletingService -> deletingService.getBootstrapStateLock().unlock());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
snapshotDeletingService.ifPresent(deletingService -> deletingService.getBootstrapStateLock().unlock());
rocksDbCheckpointDiffer.ifPresent(
rocksDBCheckpointDiffer -> rocksDBCheckpointDiffer.getBootstrapStateLock().unlock());
sstFilteringService.ifPresent(filteringService -> filteringService.getBootstrapStateLock().unlock());
keyDeletingService.ifPresent(deletingService -> deletingService.getBootstrapStateLock().unlock());
locks.forEach(BootstrapStateHandler.Lock::unlock);

Note: this will release locks in the same order as they were acquired, instead of in reverse order. I think both are fine as long as the order is fixed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated PTAL.

Note: this will release locks in the same order as they were acquired, instead of in reverse order. I think both are fine as long as the order is fixed.

I think it should be fine.

However, seems like lock and unlock call are not synchronized properly on the Lock object. This might cause possible deadlocks. Shall we synchronize on the lock object (synhronized(this)) inside the lock and unlock call?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean the lock/unlock methods of OMDBCheckpointServlet.Lock?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I was thinking whether it's necessary to add synchronized block inside the lock and unlock. However, after I think about it again, it should be fine as it is.

}
}
}