记一个暗藏颇深的缓存问题

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);  }

而后,TextReplyprocessText() 办法,脑子一热,对成员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);       } }

总结:

  • 批改成员的行为要小心
  • 返回的后果,尽量避免援用对象,尽量采纳深复制拷一份