# 常用配置项参考

# Config配置类

  • 构造方法

    Config(ModeEnum modeEnum);
    
    • 目前可选:(介绍见下文)

      • ModeEnum.CLASSIC - 经典模式(默认)

      • ModeEnum.THREAD_POOL - 线程池模式

  • 添加配置

    • configDocker(dockerSocket)

      设置 Docker 的 TCP 或 Unix Socket(推荐)。

      默认为:unix:///var/run/docker.sock

    • configCodePath(codePath)

      配置代码文件存放目录。

    • addLang()

      参见添加新的编程语言

    • addDefaultLang()

      添加默认的三种语言的支持,即 Java 、 Python 和 C++ 。

    • enableSeccomp(seccompPath)

      设置 seccomp 文件的路径,对容器进行系统调用能力限制,参见安全性是如何保证的? #2。

# Allocator模式

# 1.ModeEnum.CLASSIC - 经典模式

DJudger v0.x版本的唯一可选模式。

每个Docker容器对应一个线程,每种语言对应一个阻塞队列,Allocator仅负责启动容器线程,并将任务放入队列,并等待任务完成。

容器线程会主动从队列中取出任务,并在对应容器进行执行。

如果容器执行出现问题,对应的线程会被结束,如果有需要,会新建一个容器线程,对应新的容器。

示例如下:

Config config = new Config()
  .configCodePath("/path/to/code")
  .configDocker("unix:///var/run/docker.sock")
  .addDefaultLang()
  .configClassicAllocator(collectInterval,queuedTaskCnt,maxContainers);
名称 含义 默认值
collectInterval 清理无用容器的时间间隔(秒) 1800
queuedTaskCnt 每个容器的最多排队任务(超出后将会增加容器,直至达到maxContainer 4
maxContainer 每个语言最多的容器数目 2

# 2.ModeEnum.THREAD_POOL - 线程池模式

基于 Java 的 ThreadPoolExecutor ,是 DJudger v1.x 新增的 Allocator 模式,由于配置项较多,建议仅熟悉线程池的用户使用。

对于每种语言,维护一个线程池,线程池内的线程和容器一一对应,如果容器出现问题,则会删除旧容器,新建容器后替换当前线程对应的容器。

参数即为 ThreadPoolExecutor 的构造参数(除 ThreadFactory ),BlockQueue<Runable>RejectedExecutionHandler需要使用 Lambda 表达式提供,示例如下:

Config config = new Config(ModeEnum.THREAD_POOL)
  .configCodePath("/path/to/code")
  .configDocker("unix:///var/run/docker.sock")
  .addDefaultLang()
  .configThreadPoolAllocator(2,4,20,TimeUnit.SECONDS,()->new ArrayBlockingQueue<>(10),ThreadPoolExecutor.CallerRunsPolicy::new);

# AllocatorFactory

构造 Allocator :

Allocator allocator = AllocatorFactory.build(config);

# Allocator的runCode方法

// 语言名称,默认Python为py、Java为java、C++为c
String lang = "py"; 
// 需要执行的命令
List<String> commands = Arrays.asList("python $(code)");
// 时间限制
Integer timeLimit = 1000;
// 时间限制的单位
TimeUnit timeUnit = TimeUnit.MILLISECONDS;
// 代码标识符
String identifier = "my_first_code";
// 代码
String code = "print(\"Hello DJudger!\")";
Task task = allocator.runCode(lang,commands,2000,timeUnit,identifier,code);
// Task对象中含有代码的运行结果等信息
System.out.print(task.getStdout());

# 日志

使用了Slf4j,您可以自行选择底层日志系统。

上次更新: 2022年9月26日星期一下午4点45分 GMT+8