Haskell Shake 构建:如何使用 shakeShare and/or shakeCloud 设置共享缓存文件夹?

Haskell Shake build: how can I set up a shared cache folder using shakeShare and/or shakeCloud?

我知道这是 GHC 的 Hadrian 构建系统正在开发的一项新功能,因此工作流程可能是先进的、非常具体的,或者仍在不断发展。到目前为止我读了这些:

听起来它应该适用于我的用例:一种用于生物信息学的特定领域语言,它将极大地受益于大型基因组之间的缓存比较。我很乐意从一个基本的最小示例或对在哪里查看的描述开始工作。但我也包含了有关我的程序的更多详细信息,以防它们使它更容易...

shortcut 解释器构建了许多工件,其名称源自其输入的哈希值(有点像 Nix),理论上它们应该可以跨机器甚至操作系统移植。一个小程序 运行 可能会生成这样的文件 + 符号链接:

~/.shortcut
├── cache
│   ├── each
│   │   ├── 59e0192b1f
│   │   │   ├── 2633d268bf.ndb -> ../../../exprs/makeblastdb_nucl/2633d268bf_0.ndb
│   │   │   └── 2633d268bf.ndb.args -> ../../../cache/lines/3428ab5186.txt
│   │   ├── 623e07ac5b
│   │   │   ├── b9361606af.str.list -> ../../../exprs/extract_queries/b9361606af_0.str.list
│   │   │   └── b9361606af.str.list.args -> ../../../cache/lines/12ae82a598.txt
│   │   └── f477cfe47b
│   │       ├── 35e97350d8.bht -> ../../../exprs/blastn/ce1c174684_420e4f7fdf_35e97350d8_0.bht
│   │       └── 35e97350d8.bht.args -> ../../../cache/lines/9491bbe6a0.txt
│   ├── lines
│   │   ├── 0094e500eb.txt
│   │   ├── 12ae82a598.txt
│   │   ├── 246ddae0d8.txt
│   │   ├── 3428ab5186.txt
│   │   ├── 46767f8ae8.txt
│   │   ├── 5d54256d91.txt
│   │   ├── 61a97fd32d.txt
│   │   ├── 6de4b9ad67.txt
│   │   ├── 778251fd80.txt
│   │   ├── 81f7f42c42.txt
│   │   ├── 91ce94df26.txt
│   │   ├── 9491bbe6a0.txt
│   │   ├── b575c745e6.txt -> ../../cache/lines/6de4b9ad67.txt
│   │   ├── f094bac04c.txt
│   │   └── fcfb7a47a6.txt
│   ├── load
│   │   ├── 1e7afd22cf.gbk -> /home/jefdaj/shortcut/data/Mycoplasma_bovis_HB0801-P115.gbk
│   │   └── 28ce925871.gbk -> /home/jefdaj/shortcut/data/Mycoplasma_genitalium_M2321.gbk
│   ├── makeblastdb
│   │   └── 6de4b9ad67
│   │       ├── 6de4b9ad67.ndb.err
│   │       ├── 6de4b9ad67.ndb.nhr
│   │       ├── 6de4b9ad67.ndb.nin
│   │       ├── 6de4b9ad67.ndb.nsq
│   │       └── 6de4b9ad67.ndb.out
│   └── seqio
├── exprs
│   ├── any
│   │   └── e5677b1051_0.str.list.list -> ../../cache/lines/91ce94df26.txt
│   ├── blastn
│   │   ├── ce1c174684_420e4f7fdf_35e97350d8_0.bht -> ../../exprs/blastn/ce1c174684_420e4f7fdf_35e97350d8_0.bht.out
│   │   ├── ce1c174684_420e4f7fdf_35e97350d8_0.bht.out
│   │   └── ce1c174684_420e4f7fdf_35e97350d8_0.bht.out.err
│   ├── blastn_db
│   │   ├── 46e62edec1_420e4f7fdf_9ef76468c4_0.bht -> ../../exprs/blastn_db/46e62edec1_420e4f7fdf_9ef76468c4_0.bht.out
│   │   ├── 46e62edec1_420e4f7fdf_9ef76468c4_0.bht.out
│   │   └── 46e62edec1_420e4f7fdf_9ef76468c4_0.bht.out.err
│   ├── blastn_each
│   │   └── 46e62edec1_420e4f7fdf_2943ae4ea3_0.bht.list -> ../../cache/lines/12ae82a598.txt
│   ├── extract_queries
│   │   ├── 53376e198d_0.str.list -> ../../cache/lines/246ddae0d8.txt
│   │   ├── 53376e198d_0.str.list.tmp
│   │   ├── 53376e198d_0.str.list.tmp.err
│   │   ├── b9361606af_0.str.list -> ../../cache/lines/246ddae0d8.txt
│   │   ├── b9361606af_0.str.list.tmp
│   │   └── b9361606af_0.str.list.tmp.err
│   ├── extract_queries_each
│   │   └── d724d35317_0.str.list.list -> ../../cache/lines/91ce94df26.txt
│   ├── gbk_to_fna
│   │   ├── 262cf7e4e4_a355cc10e8_0.fna
│   │   └── 262cf7e4e4_cdab12f059_0.fna
│   ├── list
│   │   ├── 3bbbf950a3_0.str.list.list -> ../../cache/lines/91ce94df26.txt
│   │   ├── 65127d0127_0.fna.list -> ../../cache/lines/6de4b9ad67.txt
│   │   └── df91bd4d94_0.str.list.list.list -> ../../cache/lines/46767f8ae8.txt
│   ├── load_fna
│   ├── load_gbk
│   │   ├── 15e3d91521_0.gbk -> ../../cache/load/28ce925871.gbk
│   │   └── 74e27ec9a5_0.gbk -> ../../cache/load/1e7afd22cf.gbk
│   ├── makeblastdb_nucl
│   │   ├── 2633d268bf_0.ndb -> ../../cache/lines/81f7f42c42.txt
│   │   └── 954abc5fe7_0.ndb -> ../../cache/lines/81f7f42c42.txt
│   ├── makeblastdb_nucl_each
│   │   └── 209fe6406d_0.ndb.list -> ../../cache/lines/5d54256d91.txt
│   ├── num
│   │   └── a53b190835_0.num -> ../../cache/lines/778251fd80.txt
│   ├── singletons
│   │   └── 954abc5fe7_0.fna.list.list -> ../../cache/lines/0094e500eb.txt
│   └── str
│       ├── 90811d06ee_0.str -> ../../cache/lines/f094bac04c.txt
│       ├── b4da62b027_0.str -> ../../cache/lines/fcfb7a47a6.txt
│       └── b81c880be5_0.str -> ../../cache/lines/61a97fd32d.txt
├── profile.html
└── vars
    ├── mapped.str.list.list -> ../exprs/extract_queries_each/d724d35317_0.str.list.list
    ├── mbov.fna -> ../exprs/gbk_to_fna/262cf7e4e4_a355cc10e8_0.fna
    ├── mgen.fna -> ../exprs/gbk_to_fna/262cf7e4e4_cdab12f059_0.fna
    ├── result -> ../exprs/any/e5677b1051_0.str.list.list
    └── single.str.list -> ../exprs/extract_queries/53376e198d_0.str.list

27 directories, 64 files

我尝试将 shakeShare = Just "sharedir" 添加到我的 Shake 选项中。当我 运行 构建、删除所有工件并重新 运行 时,找不到缓存文件:

error! Error when running Shake build system:
  at want, called at ./ShortCut/Core/Eval.hs:253:7 in main:ShortCut.Core.Eval
* Depends on: eval
  at need, called at ./ShortCut/Core/Eval.hs:256:25 in main:ShortCut.Core.Eval
* Depends on: /root/.shortcut/vars/result
  at need, called at ./ShortCut/Core/Actions.hs:110:3 in main:ShortCut.Core.Actions
* Depends on: /root/.shortcut/exprs/all/b2ba759dce_0.str.list
  at need, called at ./ShortCut/Core/Actions.hs:110:3 in main:ShortCut.Core.Actions
* Depends on: /root/.shortcut/exprs/any/0a89231af6_0.str.list.list
  at need, called at ./ShortCut/Core/Actions.hs:110:3 in main:ShortCut.Core.Actions
* Depends on: /root/.shortcut/exprs/list/df91bd4d94_0.str.list.list.list
  at need, called at ./ShortCut/Core/Actions.hs:110:3 in main:ShortCut.Core.Actions
* Depends on: /root/.shortcut/vars/mapped.str.list.list
  at need, called at ./ShortCut/Core/Actions.hs:110:3 in main:ShortCut.Core.Actions
* Depends on: /root/.shortcut/exprs/extract_queries_each/730901fdda_0.str.list.list
  at need, called at ./ShortCut/Core/Actions.hs:110:3 in main:ShortCut.Core.Actions
* Depends on: /root/.shortcut/exprs/tblastn_each/46e62edec1_183f436b85_a5a22079c6_0.bht.list
  at need, called at ./ShortCut/Core/Actions.hs:110:3 in main:ShortCut.Core.Actions
* Depends on: /root/.shortcut/exprs/num/a53b190835_0.num
* Raised the exception:
/home/jefdaj/shortcut/sharedir/.shake.cache/2faae061b9976bed/0x134125AC: getPermissions:getFileStatus: does not exist (No such file or directory)

这是意料之中的事情,但现在我该如何解决呢?哈希值应该是稳定的,因为所有符号链接都是相对于顶级 tmpdir(此处为 ~/.shortcut)的。而且 Shake 应该知道它们中的每一个,因为我确保调用 trackWrite.

我是否需要在构建时使用 newCachenewCacheIO、and/or oracle 显式地将所有文件添加到缓存中,还是我遗漏了一些更简单的东西?

理想情况下,我会有一个共享目录来缓存在 the demo server 上完成的所有内容,并让用户可以选择将他们自己的实例连接到它,就像 Nix 二进制缓存一样。

我误解了 Shake 缓存的用途:我假设它们缓存由所有输入索引的构建工件,但实际上它们只是缓存读取 + 处理用于在生成这些工件时决定事情的文件。就像这个来自 the docs 的例子:

digits <- newCache $ \file -> do
    src <- readFile' file
    return $ length $ filter isDigit src
"*.digits" %> \x -> do
    v1 <- digits (dropExtension x)
    v2 <- digits (dropExtension x)
    writeFile' x $ show (v1,v2)

如其所说,"This function is useful when creating files that store intermediate values, to avoid the overhead of repeatedly reading from disk, particularly if the file requires expensive parsing."我认为这里的缓存相当于写了一个中间.digits文件然后needing了两次

我通过编写一个 need' 函数来实现我正在寻找的东西,该函数检查文件是否在缓存中(本地或远程),如果可能的话获取它,然后调用 Development.Shake.need .根据构建系统的不同,也可以使用 rsync.

之类的东西来执行这种 "caching"

对于我的代码部分来说,Shake 缓存看起来仍然非常有用,它需要每个程序将所有序列 ID 的列表读入内存一次运行,并在以后从各种规则中引用它们。

我认为这里有一个混淆,即 newCachenewCacheIO 与 Cloud Shake 功能有关。它们不是 - 事实上,newCache 恰好是对云缓存没有影响的事物之一(巧合,而不是因为名称中的 Cache)。我认为您的用例没有理由不能与 Cloud Shake 一起使用。

异常/home/jefdaj/shortcut/sharedir/.shake.cache/2faae061b9976bed/0x134125AC: getPermissions:getFileStatus: does not exist (No such file or directory)似乎暗示Shake记录了上述文件在缓存中,可以用来满足文件。那么问题来了,文件去了哪里?当您清理文件时,他们是否也从缓存中删除了文件? --share-copy--share-symlink 都可以 运行 - 我推荐前者以确保远距离操作更少,这也可以解释删除文件的原因.我还建议使用 Shake HEAD,因为有一些修复程序尚未发布。

如果还是不行,或许可以在 Shake GitHub 上提出问题?