gavinchou commented on code in PR #359: URL: https://github.com/apache/doris-thirdparty/pull/359#discussion_r2381178743
########## src/main/java/com/sleepycat/je/rep/utilint/net/CertificateFileWatcher.java: ########## @@ -0,0 +1,340 @@ +/*- + * Copyright (C) 2002, 2025, Oracle and/or its affiliates. All rights reserved. + * + * This file was distributed by Oracle as part of a version of Oracle NoSQL + * Database made available at: + * + * http://www.oracle.com/technetwork/database/database-technologies/nosqldb/downloads/index.html + * + * Please see the LICENSE file included in the top-level directory of the + * appropriate version of Oracle NoSQL Database for a copy of the license and + * additional information. + */ + +package com.sleepycat.je.rep.utilint.net; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; +import java.nio.file.StandardWatchEventKinds; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.TimeUnit; + +import com.sleepycat.je.rep.net.InstanceLogger; +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; +import static java.util.logging.Level.FINE; + +/** + * A file watcher that monitors certificate files for changes and notifies + * registered listeners when changes occur. + */ +public class CertificateFileWatcher { + + private final WatchService watchService; + private final ConcurrentHashMap<String, CertificateReloadListener> listeners; + private final ConcurrentHashMap<String, FileState> fileStates; + private final AtomicBoolean running; + private final Thread watcherThread; + private final InstanceLogger logger; + private final long refreshIntervalSeconds; + + /** + * Tracks the state of a monitored file to detect delete-then-recreate scenarios. + */ + private static class FileState { + final String filePath; + volatile boolean exists; + volatile long lastModified; + volatile long size; + + FileState(String filePath) { + this.filePath = filePath; + updateFromFile(); + } + + void updateFromFile() { + File file = new File(filePath); + this.exists = file.exists(); + this.lastModified = exists ? file.lastModified() : 0; + this.size = exists ? file.length() : 0; + } + + boolean hasChanged() { + File file = new File(filePath); + boolean currentExists = file.exists(); + long currentLastModified = currentExists ? file.lastModified() : 0; + long currentSize = currentExists ? file.length() : 0; + + boolean changed = (currentExists != exists) || + (currentExists && (currentLastModified != lastModified || currentSize != size)); + + if (changed) { + exists = currentExists; + lastModified = currentLastModified; + size = currentSize; + } + + return changed; + } + + boolean wasDeletedThenRecreated() { + File file = new File(filePath); + boolean currentExists = file.exists(); + + // File was deleted and then recreated if: + // 1. Our tracked state shows it didn't exist before (exists = false) + // 2. It currently exists + // 3. This indicates a delete->create sequence + return !exists && currentExists; + } + } + + /** + * Interface for listeners that want to be notified when certificate files change. + */ + public interface CertificateReloadListener { + /** + * Called when a certificate file has been modified. + * @param filePath the path of the file that was modified + */ + void onCertificateFileChanged(String filePath); + } + + /** + * Create a new certificate file watcher. + * + * @param logger the logger to use for logging messages + * @param refreshIntervalSeconds the interval in seconds to check for file changes + * (0 means use blocking wait) + * @throws IOException if the watch service cannot be created + */ + public CertificateFileWatcher(InstanceLogger logger, long refreshIntervalSeconds) throws IOException { + this.watchService = FileSystems.getDefault().newWatchService(); + this.listeners = new ConcurrentHashMap<>(); + this.fileStates = new ConcurrentHashMap<>(); + this.running = new AtomicBoolean(false); + this.logger = logger; + this.refreshIntervalSeconds = refreshIntervalSeconds; + this.watcherThread = new Thread(this::watchLoop, "CertificateFileWatcher"); Review Comment: 关注下线程数, 会不会有非常多 -- 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. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
