我正在探索反应式编程和RxJava.这很有趣,但我遇到了一个无法找到答案的问题.我的基本问题:什么是一种反应性的方法来终止一个无限运行的Observable?我也欢迎有关我的代码的批评和反应性最佳实践.
作为练习,我正在编写一个日志文件尾实用程序.日志文件中的行流由a表示Observable<String>.为了BufferedReader继续阅读添加到文件中的文本,我忽略了通常的reader.readLine() == null终止检查,而是将其解释为意味着我的线程应该休眠并等待更多的记录器文本.
但是当我可以使用Ob终止Observer时takeUntil,我需要找到一种干净的方法来终止无限运行的文件观察器.我可以编写自己的terminateWatcher方法/字段,但这会打破Observable/Observer封装 - 我希望尽可能严格遵守反应范式.
这是Observable<String>代码:
public class FileWatcher implements OnSubscribeFunc<String> {
private Path path = . . .;
@Override
// The <? super String> generic is pointless but required by the compiler
public Subscription onSubscribe(Observer<? super String> observer) {
try (BufferedReader reader = new BufferedReader(new FileReader(path.toFile()))) {
String newLine = "";
while (!Thread.interrupted()) { // How do I terminate this reactively?
if ((newLine = reader.readLine()) …Run Code Online (Sandbox Code Playgroud) 我有一些DynamoDB表,所有表都具有相同结构的条目.我想创建一个POJO来表示所有这些条目,然后使用DynamoDB的Mapper API来加载和保存这些对象.
问题是API需要@DynamoDBTable我的POJO上的注释.这是一个编译时注释需要一个表名参数,因此会阻止我以动态方式使用POJO.DynamoDBMapperConfig似乎只允许这种动态行为更改.不幸的是,它对我不起作用:我收到客户端DDB错误,说我的POJO由于我在注释中放入的空字符串而未通过验证.
我一直在寻找为什么我的DynamoDBMapperConfig没有被尊重但却找不到任何东西.我的代码如下,精简到以下内容:
我的POJO:
@DynamoDBTable(tableName = "") // table name must be overridden on each call
public class TableEntry {
. . .
}
Run Code Online (Sandbox Code Playgroud)
我的客户:
public class MyMapper {
private final DynamoDBMapper mapper;
private final DynamoDBMapperConfig configs;
public MyMapper(String tableName) {
AmazonDynamoDBClient client = . . .;
mapper = new DynamoDBMapper(client);
configs = new DynamoDBMapperConfig.Builder()
.withTableNameOverride(TableNameOverride.withTableNameReplacement(tableName))
.build();
}
. . .
public void getEntry(String key) {
return mapper.load(TableEntry.class, key, configs);
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行我的代码(基本上类似于我在这里粘贴的代码)时,我收到以下消息:
2 validation …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个lazy seq来为给定的输入int 生成Collatz序列.
我喜欢这个函数,因为它是如此干净地映射到数学定义:
(defn collatz
"Returns a lazy seq of the Collatz sequence starting at n and ending at 1 (if
ever)."
[n]
(letfn [(next-term [x]
(if (even? x)
(/ x 2)
(inc (* 3 x))))]
(iterate next-term n)))
Run Code Online (Sandbox Code Playgroud)
问题在于,由于Collatz序列的行为方式,这会产生无限的seq:
(take 10 (collatz 5))
=> (5 16 8 4 2 1 4 2 1 4)
Run Code Online (Sandbox Code Playgroud)
我可以通过添加来轻松地删除循环(take-while #(not= 1 %) ...),但是1 是序列的一部分.我认为所有其他的方法都会在一个丑陋之后修剪周期,并使Collatz序列的数学核心模糊不清.
(我已经考虑将看到的值存储在一个原子中并在take-while谓词中使用它,或者只是在一个原子中存储一个标志以达到类似的效果.但我觉得有一些更好,更漂亮,更少侵入性的方式来做我所做的事情.想要在这里.)
所以我的问题是:在无限序列中检测和修剪周期的干净方法是什么?或者,我可以以某种方式(可能使用for)生成我的懒惰seq,当它达到1(包括)时自动修剪?