GuOJ Dev log.2

GuOJ Dev log.2
四季映姬·夜摩仙那度 from 东方人妖名鉴
We build codes done right.

在一段时间的停滞后,项目进行到了基本API和框架完备的阶段,是时候开始开发真正让这个OJ不同的评测系统了。

评测系统执行架构设计

去年年末,我开了一个评测机新坑Shikieiki(名字取自東方花映塚封面角色 四季映姬·夜魔仙那度),调研了一些和评测相关的技术。长期以来,大家有一种设想,使用类似CI/CD的方式配置某种通用的评测系统,社区中也有诸多实现(如Seele)。但并未有一个有足够通用性和健壮性处理大量通用评测任务的评测系统。Shikieiki的目标便是打破这一现状。基于Rust,我们可以设计快速高效的分布式评测系统。具体而言,Shikieiki目前有以下核心构想:

  • 动态加载的,节点化可配置的评测任务设置
  • 分布式的评测后端
  • 基于容器化技术的安全评测环境
  • 可配置的评测前端选项

接下来,我将简述目前实现这些构想的技术方案。

基于deno_core,Rust支持在运行时直接执行JavaScript/TypeScript代码,有鉴于此,我们不妨基于TypeScript设计一种插件形式。具体而言,一个插件的后端部分可能需要包含如下代码

// metadata.json

{
    "id": "1234abcd-5678efgh-9012ijkl-mnopqrst",
    "version": "1.0.0",
    "description": "This is a sample node config.",
    "inputs": [
        {
            "name": "files",
            "type": "fileList"
        },
        {
            "name": "integer",
            "type": "integer"
        }
    ],
    "outputs": [
        {
            "name": "files",
            "type": "fileList"
        },
        {
            "name": "integer",
            "type": "integer"
        }
    ],
    "config": [
        {
            "name": "config1",
            "type": "string"
        },
        {
            "name": "config2",
            "type": "integer"
        }
    ]
}  
// index.ts

import { type FileList, PluginError } from '@guoj/aya';

export interface Inputs {
    file: FileList,
    integer: number
}

export interface Outputs {
    file: FileList,
    integer: number
}

export const process = (inputs: Inputs): Outputs => {
    if (!inputs.file || inputs.file.length === 0) {
        throw new PluginError('No file provided');
    }
    if (typeof inputs.integer !== 'number' || isNaN(inputs.integer)) {
        throw new PluginError('Invalid integer provided');
    }
    // Process the file and integer here
    const processedFile = inputs.file; // Placeholder for actual processing logic
    const processedInteger = inputs.integer + 1; // Example processing: incrementing the integer
    return { file: processedFile, integer: processedInteger };
}

(基于rust shared library的插件规范开发中)

不仅如此,一个插件还可以携带一个可选的WebComponent(也可使用带有自动生成功能的模板)用于前端可视化。如:在工作流的起点节点使用一个带有传统OI提交功能的节点,在工作流的终点节点使用一个带有传统OI结果输出的节点等。通过多个节点构成的工作流,还带有一些选项可用于配置工作流执行所在的镜像环境等。通过这一系列基础设施,我们得以实现一个既多功能又足够通用的评测框架。

评测系统分布架构设计

在单节点的通用评测系统支撑下,我们希望引入更多的分布式机制帮助我们构建一个强大的多节点评测系统支撑一个现代化的计算机社区。具体而言,我们希望在全局评测机群,允许用户引入自己的评测机群,并允许配置评测机群拉取指定习题/习题集的评测队列执行任务,并实现一定的调度机制使得自托管的评测机可以使用较少的资源运行用户希望他们的评测机执行的任务(如为自己的客制化习题集/比赛提供高质量服务),也允许用户为全局评测机群贡献自己的力量。在这样的愿景下,目前我们认为有这样的问题有待解决

  • 如何实现高效的评测状态管理系统为每个节点分配任务,并避免评测队列中出现错误
  • 如何避免不合法的评测机连接(对私有评测机而言似乎不是问题)
  • 如何认证合法的评测机加入全站评测队列(目前而言,基于真实信任并丢弃产生非法结果的评测机)
  • 如何减小评测机性能差异的影响(为特定任务实现某种基准评测机评分,并允许用户选择高效评测机为自己服务或是自己搭建评测机)