All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pl.touk.tscreload.impl.ReloadableConfig Maven / Gradle / Ivy

/*
 * Copyright 2015 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package pl.touk.tscreload.impl;

import com.typesafe.config.Config;
import lombok.extern.slf4j.Slf4j;
import pl.touk.tscreload.Reloadable;

import java.io.File;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

@Slf4j
public class ReloadableConfig extends Reloadable implements Observer {

    private final List scannedFiles;

    private final Duration checkInterval;

    private final Supplier configSupplier;

    private ConfigWithTimestamps configWithTimestamps;

    public ReloadableConfig(List scannedFiles, Duration checkInterval, Supplier configSupplier) {
        super(configSupplier.get());
        this.scannedFiles = scannedFiles;
        this.checkInterval = checkInterval;
        this.configSupplier = configSupplier;
        this.configWithTimestamps = new ConfigWithTimestamps(configSupplier.get(), optionalLastModified().get(), Instant.now());
    }

    @Override
    public synchronized void notifyChanged(Instant now) {
        ConfigWithTimestamps current = configWithTimestamps;
        if (now.isAfter(current.getLastCheck().plus(checkInterval))) {
            optionalLastModified()
                    .filter(lastModified -> lastModified.isAfter(current.getLastModified()))
                    .map(lastModifiedAfterCurrent -> invalidateCache(lastModifiedAfterCurrent, now))
                    .orElseGet(() -> {
                        configWithTimestamps = current.withLastCheck(now);
                        return null;
                    });
        }
    }

    private Optional optionalLastModified() {
        return scannedFiles.stream()
                .map(File::lastModified)
                .max(Long::compare)
                .map(Instant::ofEpochMilli);
    }

    private Void invalidateCache(Instant lastModified, Instant lastCheck) {
        log.debug("Found changes. Reloading configuration.");
        updateCurrentValue(prev -> {
            Config newValue = configSupplier.get();
            configWithTimestamps = new ConfigWithTimestamps(newValue, lastModified, lastCheck);
            return newValue;
        });
        return null;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy