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