archlinuxcn / lilac

Lilac is the build bot for archlinuxcn
GNU General Public License v3.0
113 stars 40 forks source link

非阻塞式打包支持 #145

Closed petronny closed 1 year ago

petronny commented 4 years ago

如题。某些奇奇怪怪的包会强制-j1,对于这些包感觉没必要让其他核心一直空着。 所以在想能不能实现对这些包实行非阻塞,其他仍然是阻塞式。

初步构想的改动如下:

  1. 仍然保持拓扑排序的结果。
  2. archbuild会创建多个打包session,同时维护一个哪个session当前在打哪个包的对应关系表A
  3. 轮到某个包时,在表A中检查其依赖是否都已经打包,否则就等着。
  4. 若当前包依赖关系已经解决,则打包
  5. 若当前打包的是一个非阻塞的包时,则同时也处理下一个包
lilydjwg commented 4 years ago

首先要解决的一个问题是:怎么同时跑多个同一 prefix 的 chroot? 其次是资源评估。CPU 资源还好,大不了慢一些,可是万一并行的几个包占用空间大、/var/lib/archbuild 满了咋办?

petronny commented 4 years ago

怎么同时跑多个同一 prefix 的 chroot?

我猜extra-x86_64-build -- -l session2 应该是会在/var/lib/archbuild/extra-x86_64/session2里跑

可是万一并行的几个包占用空间大、/var/lib/archbuild 满了咋办?

是个问题。初步想法是先限制一下并行的数量。比如只允许开2个session,有表A的话可以查,多了就等着。可以解决一部分问题吧。。。

进一步的话可以在lilac.*里写一下预估的资源需求(比如写space_requirement_g=5),如果空间磁盘不够5g就也等着,如果此时表A里是空的那么就可以发out of space的邮件了

lilydjwg commented 4 years ago

我猜 extra-x86_64-build -- -l session2

原来还有这么个选项。那是不是肥猫二号、三号可以下岗了? @felixonmars

felixonmars commented 4 years ago

@lilydjwg 我修改版的自动打包脚本今天换上了这个选项,看看有没有什么问题。如果没问题就可以下岗了~

petronny commented 4 years ago

感觉应该是start_build这个函数要改了

我在想是要改async还是就while等着就行。。。

while 打包list不为空:
    if session都被占满了:
        sleep(1)
        continue
    session = 获取空闲session
    package = 从打包list中挑出下一个前置依赖都解决了的 # 这里也可以不严格按照拓扑排序的顺序
    build_package(package, session)

我们可以先从session上限为1开始试一下。。。

petronny commented 4 years ago

我在思考另一种非阻塞的运行方式。然后同时结合一下github actions实现分布式打包

首先需要一个数据库,存

  1. newver和oldver nvchecker不再由lilac调用,而是自己定时启动更新数据库
  2. 打包各session的情况 没有本地session,本地session也由github action托管 各action prefix的session最大数量不一样。比如 action-extra-x86_64 20, action-extra-x86_64-powerful(本地托管的) 1或者有几个写几个。
  3. rebuild flag 每个包都一个手动rebuild的bool,和一个配套触发这个的api,则调用该API即可触发rebuild,不用再创建一个commit了
  4. 包最新下载链接 artifacts link或者repo

然后lilac改为每若干分钟运行的定时任务,每次运行时

  1. 先根据数据库状态,取回结束了的session包,应用session回传的patch,nvtake对应的包,更新下载链接等等
  2. 根据newver, oldver, session情况决定当前要打哪个包或者不打包 然后根据依赖关系和数据库返回repo_depends链接给session session中执行新的可执行脚本lilac-remote

lilac-remote接收参数为一串包下载链接,没有的从repo下,所以本地也是可以直接运行的。 然后读取lilac.yaml和lilac.py,得到mod 然后执行single_main 结束后去数据库标记状态(这要求数据库可以公网访问或者可以公网 web API间接访问)

那么并行状态应该是最优的,也没有必须等待上一波lilac都运行完了的问题。 触发rebuild可以接近随叫随到(给个高优先级什么的),感觉可以去掉build机手动打包上传渠道,只留一个gpg key。

目前就是single_main太弱了,需要做的改进有:

  1. 自动下载repo_depends
  2. 设置PACKAGER环境变量
  3. 防止打旧包功能
  4. 去group功能,比只检查官方group严格但是实现不依赖archrepo了

这么看其实别的remote方案也是可以的。。。甚至ssh上去执行都行。。。可能主要就是白嫖了github的20个runner吧。。。

petronny commented 4 years ago

改进single_main为lilac-remote我觉得好处也挺多的

大家可以不用配置lilac就能调试lilac.*什么的

然后也有助于淘汰lilac.py (有自动迁移工具么。。。)

lilydjwg commented 4 years ago

目前的问题在于没有 build runner 的抽象。

petronny commented 4 years ago

一点点来吧。。。 我们可以先改进single_main,然后还有nvchecker存数据库什么的?

petronny commented 4 years ago

想了想我打算基于数据库ORM先写一个Runner类,LocalRunner类,GithubActionsRunner类。

Runner的各种数据都ORM到数据库里,然后新进程也能从数据库恢复Runner出来。虽然最后每个Runner类都会搞出一个表出来不过应该ok吧。。。

LocalRunner会启动一个调用single_main的进程。这个进程就是将来大家本地调试lilac mod的那个,应该就是把lilac_build解藕出来的意思。

我大概明天能初步整一个出来。。。?

有个问题就是用啥ORM比较好。。。

lilydjwg commented 4 years ago

记一下:GithubActionsRunner 的 can_run_task 方法要先去检查一下 GitHub Status。

lilydjwg commented 4 years ago

记一下:GithubActionsRunner 的 can_run_task 方法要先去检查一下 GitHub Status。

lilydjwg commented 4 years ago

ORM 当然是用 SQLAlchemy 啦。不过我打算先把 Runner 写好,再做数据库的部分。

petronny commented 4 years ago

嗯,老migrate也挺麻烦的

petronny commented 4 years ago

呃我是不是对Runner的理解出现了偏差。。。 我现在那份Runner代码其实是不是更接近于Job...

不过说起来我的确没想好哪里配置哪个runner是多少并行

lilydjwg commented 4 years ago

嗯……你那个不像是 Runner,而像是 Runnee。我想到 Runner 大概是:

class IRunner:
  def can_run_task(self) -> float: ...
  async def run(self, pkgbase: str) -> Result: ...
petronny commented 4 years ago

我把原来的Runner挪到BuildJob了,然后新写了一个Runner类。

然后就是我构想的触发打包的进程,和接收打好的包、签名、移交给archrepo的进程不是一个进程,甚至可以不在一个地方。 比如由github actions触发前一部分的打包。后者应该是只能本地了吧,生成archrepo db应该是需要串行的。

petronny commented 3 years ago

我打算把各种Runner的资源管理什么的通过扔给SGE去做了, Runner 就对应到队列了,应该就不用写了吧。。。

lilydjwg commented 3 years ago

SGE 是什么?

petronny commented 3 years ago

Son of Grid Engine

总之就是某种资源管理器

lilydjwg commented 1 year ago

已通过 max_concurrency 选项支持并行打包。