Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

非阻塞式打包支持 #145

Closed
petronny opened this issue Apr 19, 2020 · 21 comments
Closed

非阻塞式打包支持 #145

petronny opened this issue Apr 19, 2020 · 21 comments

Comments

@petronny
Copy link
Member

petronny commented Apr 19, 2020

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

初步构想的改动如下:

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

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

@petronny
Copy link
Member Author

petronny commented Apr 19, 2020

怎么同时跑多个同一 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
Copy link
Member

lilydjwg commented Apr 19, 2020

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

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

@felixonmars
Copy link
Member

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

@petronny
Copy link
Member Author

petronny commented May 20, 2020

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

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

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

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

@petronny
Copy link
Member Author

petronny commented Jul 11, 2020

我在思考另一种非阻塞的运行方式。然后同时结合一下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
Copy link
Member Author

petronny commented Jul 11, 2020

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

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

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

@lilydjwg
Copy link
Member

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

@petronny
Copy link
Member Author

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

@petronny
Copy link
Member Author

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

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

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

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

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

@lilydjwg
Copy link
Member

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

1 similar comment
@lilydjwg
Copy link
Member

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

@lilydjwg
Copy link
Member

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

@petronny
Copy link
Member Author

嗯,老migrate也挺麻烦的

@petronny
Copy link
Member Author

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

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

@lilydjwg
Copy link
Member

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

class IRunner:
  def can_run_task(self) -> float: ...
  async def run(self, pkgbase: str) -> Result: ...

@petronny
Copy link
Member Author

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

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

@petronny
Copy link
Member Author

petronny commented Dec 9, 2020

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

@lilydjwg
Copy link
Member

lilydjwg commented Dec 9, 2020

SGE 是什么?

@petronny
Copy link
Member Author

petronny commented Dec 9, 2020

Son of Grid Engine

总之就是某种资源管理器

@lilydjwg
Copy link
Member

lilydjwg commented Jan 5, 2023

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

@lilydjwg lilydjwg closed this as completed Jan 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants