记一个暗藏颇深的缓存问题
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);
}
}
总结:
- 批改成员的行为要小心
- 返回的后果,尽量避免援用对象,尽量采纳深复制拷一份