记一个隐藏颇深的缓存问题
DmNode
是根据节点 ID 缓存的,里面有嵌套很深的对话逻辑结构,包含了Reply
。
传递到答案生成时,已经看不到DmNode
的踪影了,因为放在 FlowResult
里面。
@Override
public AnswerPod generate(FlowResult flowResult, DmContext dmContext, Env env) {
List<ReplyItem> replyItems = Lists.newArrayList();
for (Reply reply: flowResult.getReplies()) {
ReplyItem item;
try {
item = generate(reply, dmContext, env);
} catch (Exception e) {
// 对话过程中,generate 异常,则吞掉不展示这个答案
log.warn("答案生成失败 error: {}", e);
continue;
}
replyItems.add(item);
}
List<CapsuleDto> capsuleDtos = capsuleService.convert(flowResult.getCapsules());
return answerPodBuilder.create(flowResult, replyItems, capsuleDtos);
}
然后,TextReply
的 processText()
方法,脑子一热,对成员text
进行了修改。结果因为 Reply
是缓存的,所以生成结果被缓存了下来。
public class TextReply implements Reply {
private String text;
public TextReply(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void processText(DmContext dmContext, MarkService markService) {
this.text = TextProcessor.process(text, dmContext, markService);
}
}
总结:
- 修改成员的行为要小心
- 返回的结果,尽量避免引用对象,尽量采用深复制拷一份
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。