rime / librime

Rime Input Method Engine, the core library
https://rime.im
BSD 3-Clause "New" or "Revised" License
3.37k stars 551 forks source link

__patch频繁失效 #141

Closed xiaoqun2016 closed 7 years ago

xiaoqun2016 commented 7 years ago

在试rime新增的复用功能,遇到了__patch时灵时不灵的问题。
复现方法如下: 更改方案schema,改变句号键行为

punctuator:
  __include: default:/punctuator
  __patch:
    half_shape:
      ".": {commit: "测试"}

在来回切换方案的时候,__patch的内容有一定的概率会失效(切换20次,大概有9次会失效)
在pime与同文上都有这个问题。

请问我的写法对不对?问题出在哪里?

osfans commented 7 years ago

@kionz #138

kionz commented 7 years ago

这个patch替换了整个half_shape的内容为只有.一项?

xiaoqun2016 commented 7 years ago

是的。这里只是为了模拟出__patch失效问题。
实际方案并不是这样写的

lotem commented 7 years ago

我附議。是有樓主說的問題。 不過這個功能先擱置不用,比以前也不少啥,代碼就不撤銷了。@kionz 慢慢調試吧。

xiaoqun2016 commented 7 years ago

同文的主题trime.yaml有些颇为复杂,有数千行,还挺需要这个__patch功能的
加油

lotem commented 7 years ago

各位有什麼發現嘛? 我懷疑是 __patch__include 執行順序的問題。 因爲我試了樓主的模擬,只要將 __include 改回用 import_preset: default 就屢試不爽了。 如果是 __patch 先執行,那不就掛了嘛?

lotem commented 7 years ago

加了些日誌。果然看到:

I0902 21:22:47.971751 2923140032 config_data.cc:62] loading config file '/Users/lotem/Library/Rime/luna_pinyin.schema.
I0902 21:22:47.972306 2923140032 config_compiler.cc:384] ParsePatch(<literal>)
I0902 21:22:47.972313 2923140032 config_compiler.cc:166] ConfigDependencyGraph::Add(), node_stack.size() = 2
I0902 21:22:47.972326 2923140032 config_compiler.cc:172] target_path = luna_pinyin.schema:/punctuator, #deps = 1
I0902 21:22:47.972332 2923140032 config_compiler.cc:184] parent_path = luna_pinyin.schema:, #deps = 1
I0902 21:22:47.972337 2923140032 config_compiler.cc:344] ParseInclude(default:/punctuator)
I0902 21:22:47.972342 2923140032 config_compiler.cc:166] ConfigDependencyGraph::Add(), node_stack.size() = 2
I0902 21:22:47.972345 2923140032 config_compiler.cc:172] target_path = luna_pinyin.schema:/punctuator, #deps = 2
I0902 21:22:47.972350 2923140032 config_compiler.cc:184] parent_path = luna_pinyin.schema:, #deps = 2
I0902 21:22:47.972555 2923140032 config_compiler.cc:403] Link(luna_pinyin.schema)
I0902 21:22:47.972561 2923140032 config_compiler.cc:413] ResolveDependencies(luna_pinyin.schema:)
I0902 21:22:47.972565 2923140032 config_compiler.cc:413] ResolveDependencies(luna_pinyin.schema:/punctuator)
I0902 21:22:47.972571 2923140032 config_compiler.cc:151] PatchLiteral::Resolve()
I0902 21:22:47.972575 2923140032 config_compiler.cc:156] patching half_shape
I0902 21:22:47.972579 2923140032 config_data.cc:210] TraverseCopyOnWrite(half_shape)
I0902 21:22:47.972587 2923140032 config_compiler.cc:420] resolved Patch(<literal>)(blocking)
I0902 21:22:47.972591 2923140032 config_compiler.cc:122] IncludeReference::Resolve(reference = default:/punctuator)
I0902 21:22:47.972596 2923140032 config_compiler.cc:331] resource not found, compiling: default
I0902 21:22:47.972609 2923140032 config_data.cc:62] loading config file '/Users/lotem/Library/Rime/default.yaml'.
I0902 21:22:47.974809 2923140032 config_compiler.cc:272] GetResolvedItem(default:/punctuator)
I0902 21:22:47.974822 2923140032 config_compiler.cc:295] advance with key: punctuator
I0902 21:22:47.974829 2923140032 config_compiler.cc:420] resolved Include(default:/punctuator)(blocking)
I0902 21:22:47.974838 2923140032 config_compiler.cc:423] all dependencies resolved.
I0902 21:22:47.974841 2923140032 config_compiler.cc:420] resolved PendingChild(luna_pinyin.schema:/punctuator)
I0902 21:22:47.974845 2923140032 config_compiler.cc:413] ResolveDependencies(luna_pinyin.schema:/punctuator)
I0902 21:22:47.974849 2923140032 config_compiler.cc:423] all dependencies resolved.
I0902 21:22:47.974853 2923140032 config_compiler.cc:420] resolved PendingChild(luna_pinyin.schema:/punctuator)
I0902 21:22:47.974858 2923140032 config_compiler.cc:423] all dependencies resolved.

可見 PatchLiteral 先解析到,於是鏈接階段也是先於 Include 執行的。然後又看到命令加入隊列的順序取決於解析順序,解析順序取決於從 YAML map 閱讀的順序……再往下跟是 YAML-CPP 的可怕代碼。 我想那個 YAML 閱讀順序大概是沒有辦法保證的。 看來對第三方代碼應保持謹慎的懷疑態度。包括 PR。


更新:以上日誌裏還發現一個小問題,PendingChild(luna_pinyin.schema:/punctuator) 也執行了兩次。 代碼怪複雜的,今晚將將能理順頭緒。明天試着改改。