Java 动态集合上的通量

Java 动态集合上的通量,java,spring,project-reactor,spring-webflux,Java,Spring,Project Reactor,Spring Webflux,好的,我有点困惑我应该如何在Spring的Webflux/Reactor API中使用Reactor模式 假设我在一个目录中不断添加文件。每当出现一个新文件时,我的应用程序都应该处理它。如果队列已满,则应忽略新文件(因此没有FileWatcher),直到队列中有空间为止 以下只是伪代码,我只是想了解一般的想法,而不是具体的实现细节 类目录观察器 管理计划任务,该任务每2秒检查一次是否出现新文件。如果是,我们尝试将它们添加到队列中 @PostConstruct public void initia

好的,我有点困惑我应该如何在Spring的Webflux/Reactor API中使用Reactor模式

假设我在一个目录中不断添加文件。每当出现一个新文件时,我的应用程序都应该处理它。如果队列已满,则应忽略新文件(因此没有FileWatcher),直到队列中有空间为止

以下只是伪代码,我只是想了解一般的想法,而不是具体的实现细节

类目录观察器

管理计划任务,该任务每2秒检查一次是否出现新文件。如果是,我们尝试将它们添加到队列中

@PostConstruct
public void initialize() {

    this.flux = Flux.generate(consumer -> {
        consumer.next(this.deque.pop()); 
    });

    this.flux.log();
}

@Scheduled(fixedRate = 2000)
public void checkDirectory() {
   // list files, for each add to deque (if not present)
}

public Flux<Path> getObserver() {
    return this.flux; 
}
这种方法有意义吗?如果是,我需要做什么才能在向队列中添加新项目时触发我的订阅(目前仅在启动时执行一次)

更新 以下是我的工作实现:

public class DirectoryObserverTask {

@Autowired
private Path observedDirectory;

private Consumer<Path> newFilesConsumer;
private Consumer<Throwable> errorsConsumer;

private Flux<Path> flux; 


@PostConstruct
public void init() {
    this.observedDirectory = Paths.get(importDirectoryProperty);
}

public void subscribe(Consumer<Path> consumer) {
    if(this.flux == null) {
        this.flux = Flux.push(sink -> {
            this.onError(err -> sink.error(err));
            this.onNewFile(file -> sink.next(file));
        }); 
        this.flux = this.flux.onBackpressureBuffer(10,  BufferOverflowStrategy.DROP_LATEST); 
    }

    this.flux.subscribe(consumer); 

}


@Scheduled(fixedRate = 2000)
public void checkDirectoryContent() throws IOException {    
    Files.newDirectoryStream(this.observedDirectory).forEach(path -> {
        this.newFilesConsumer.accept(path);
    });
}

public void onNewFile(Consumer<Path> newFilesConsumer) {
    this.newFilesConsumer = newFilesConsumer;
}

public void onError(Consumer<Throwable> errorsConsumer) {
    this.errorsConsumer = errorsConsumer;
}

您不需要使用队列,这种行为已经内置

我会这样做:

FileWatchService watcher = ...

Flux<File> fileFlux = Flux.push(sink -> {
    watcher.onError(err -> sink.error(err));
    watcher.onNewFile(file -> sink.next(file));
});

fileFlux
    .onBackPressureBuffer(10, BufferOverflowStrategy.DROP_LATEST)
    .subscribe(...)
  • 使用文件监视程序检测更改

  • 将更改推送到
    通量

  • 根据请求,限制排队事件的数量(使用背压):

    filesFlux.onBackPressureBuffer(10,BufferOverflowStrategy.DROP\u最新版本)

  • 照常订阅

  • 对背压的一个糟糕的解释是:“当我们不能足够快地处理元素时该怎么做”

    在本例中,我们将元素缓冲到10个,然后在缓冲区已满时丢弃最新的元素

    更新:有许多方法可以产生流量。在本例中,我将查看
    create
    push
    方法(请参阅)

    示例:假设您有一个
    FileWatchService
    ,您可以在其中注册检测到新文件时的回调,以及在出现错误时的回调。你可以这样做:

    FileWatchService watcher = ...
    
    Flux<File> fileFlux = Flux.push(sink -> {
        watcher.onError(err -> sink.error(err));
        watcher.onNewFile(file -> sink.next(file));
    });
    
    fileFlux
        .onBackPressureBuffer(10, BufferOverflowStrategy.DROP_LATEST)
        .subscribe(...)
    
    FileWatchService-watcher=。。。
    通量文件通量=通量推送(水槽->{
    watcher.onError(err->sink.error(err));
    onNewFile(文件->sink.next(文件));
    });
    通量
    .onBackPressureBuffer(10,BufferOverflowStrategy.DROP_最新)
    .订阅(…)
    
    谢谢,你能给我举一个步骤2的例子吗?我将如何推动对现有流量的更改?我应该使用哪种静态方法(generate()、push()、…)来创建通量?@Xogaz我用一个简单的例子更新了答案。
    FileWatchService watcher = ...
    
    Flux<File> fileFlux = Flux.push(sink -> {
        watcher.onError(err -> sink.error(err));
        watcher.onNewFile(file -> sink.next(file));
    });
    
    fileFlux
        .onBackPressureBuffer(10, BufferOverflowStrategy.DROP_LATEST)
        .subscribe(...)