2022-33: Metacamp
August 21, 2022

这周一整周都在北京出差。一方面和北京的同事交流沟通,熟悉起来,方便未来工作上的协作,另一方面是协助准备 Metacamp 程序设计大赛。回过头来看,这两方面的目的都完美达成了,这次出差效果非常不错!

主要说说 Metacamp 的准备工作吧。作为曾经的 OI + ACM 竞赛选手,我却从来没有在幕后参与过竞赛准备的工作,可以说是有点小遗憾了。这次 Metacamp 算是为我弥补了这部分缺憾,我和另外一个北京的同事一起负责 OJ 的准备和现场的裁判工作。

很早就确定要使用 domjudge 作为评测环境,于是我提前两三周的时候就开始看文档,折腾了很久在自己的开发机上安装环境,最后发现 docker 真香。参考这篇文章,用很简单的几个命令就能用 docker 起一个评测环境。本地测试过发现非常丝滑,没有遇到什么特别坑爹的问题。

于是我们赛前一周左右申请了一台 102 个核心,384G 的大机器,配上 1T 的 PL2 SSD,在主机上启动了一个 domserver 加上 102 个 judgehost,应对 50 个选手的现场比赛绝对是绰绰有余。但为了彻底放心,我琢磨了下 domjudge 的 API, 用 python 写了个压测程序,赛前测试提交 10000 发 TLE/MLE 的测试程序,除了需要排队评测外,domserver 完全能扛住压力。不过测完还是发现有些 judgehost 会被打挂,这个问题直到赛前一天才发现原因——所有的 judgehost 默认都共享同一个 uid,而每个 uid 配置了最多只能占用 64 个核,因此会在有超过 64 个 judgehost 同时评测时导致错误——可能这是 CPU 核心多才会有的烦恼吧。为此我们写了个脚本自动 start 或者 restart 所有的 judgehost,写法非常的粗暴,直接用 vim 的宏和块编辑模式,把操作一个 judgehost 的 docker 命令复刻了 101 遍。

周日到比赛现场,check in 入住了望京凯悦酒店,到门口才发现原来去年我来过这里——也是大概这个时候,当时在参加 PingCAP 的开发者大会,活动的场地则是完全相同的大厅,不由得感慨时过境迁。

现场将近 60 台电脑。我们先是举办了一场小型的真题模拟赛,由内部工作人员参与,发现了一些 OJ 的小 bug,譬如不能同时有超过两场 activated 的比赛,否则同时参加这两场比赛的选手看到的界面,两场比赛的信息会混在一起。

为了方便配置选手账号,我继续魔改 python 压测脚本,利用 domserver 本身的 API 和一些只有 web 界面才有的请求路径,结合 requests 搞了一套自动创建或者删除选手账号的脚本,于是便可以很欢快地一键重置所有选手账号,从而不再需要在 web 界面点来点去。自动化的魔力是无穷的!

此外还发现现场的机器时间不对。因为现场的机器不允许访问除了 domserver 之外的 IP,所以连带 NTP 服务器也无法访问了,因此时间都是错乱的。于是我又搞了套自动修改所有机器的时间的脚本,原理是先通过 nmap 扫出所有选手机器的 IP(全部在 192.168.100.0/24 这个网段下),然后逐个 ssh 上去执行改时间的命令,特别是通过 hwclock 把时间写到硬件上,从而即使重启时间也是对的。

大概长这样

#! /bin/zsh
export SSHPASS="XXX"

for host_ip in $(nmap -n -sn 192.168.100.0/24 -oG - | awk '/Up$/{print $2}')
do
    echo obtain $host_ip
    sshpass -e ssh -o StrictHostKeyChecking=no dev@$host_ip "echo XXX | sudo -S date --set=\"$(date)\"; echo XXX | sudo -S hwclock -w" || echo "failed to ssh into $host_ip"
    # sshpass -e ssh -o StrictHostKeyChecking=no dev@$host_ip "cat /dev/null > ~/.bash_history; history -c"
    # sshpass -e ssh -o StrictHostKeyChecking=no dev@$host_ip "echo XXX | sudo -S reboot" || echo "failed to ssh into $host_ip"
done

稍微改改还能实现删除命令行历史记录和重启机器的功能,特别是自动重启所有机器,当脚本一运行,全场机器应声一台一台地重启,效果非常令人满意。

现场还有很多有趣的准备工作,作为工作人员,能明显感觉到大家一起准备比赛的投入感和责任感,是很有意思的经历。

总算所有事情都准备好了,就等明天开赛!希望能给所有参赛选手最好的比赛体验,也算是不枉北京此行了。