{"id":13994459,"url":"https://github.com/vijos/jd4","last_synced_at":"2026-01-21T21:40:01.449Z","repository":{"id":48089269,"uuid":"72264883","full_name":"vijos/jd4","owner":"vijos","description":"Judging daemon for programming contests","archived":false,"fork":false,"pushed_at":"2024-09-09T20:55:19.000Z","size":409,"stargazers_count":96,"open_issues_count":13,"forks_count":30,"subscribers_count":15,"default_branch":"master","last_synced_at":"2024-11-29T16:39:20.475Z","etag":null,"topics":["asyncio","cgroup","cython","daemon","linux","linux-namespaces","online-judge","python","sandbox","vijos"],"latest_commit_sha":null,"homepage":"https://vijos.org","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vijos.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-10-29T04:28:52.000Z","updated_at":"2024-11-29T10:51:37.000Z","dependencies_parsed_at":"2024-09-09T22:58:31.335Z","dependency_job_id":null,"html_url":"https://github.com/vijos/jd4","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/vijos/jd4","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vijos%2Fjd4","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vijos%2Fjd4/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vijos%2Fjd4/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vijos%2Fjd4/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vijos","download_url":"https://codeload.github.com/vijos/jd4/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vijos%2Fjd4/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28644149,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T21:29:11.980Z","status":"ssl_error","status_checked_at":"2026-01-21T21:24:31.872Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asyncio","cgroup","cython","daemon","linux","linux-namespaces","online-judge","python","sandbox","vijos"],"created_at":"2024-08-09T14:02:53.210Z","updated_at":"2026-01-21T21:40:01.425Z","avatar_url":"https://github.com/vijos.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"Judge Daemon\n============\n\n.. image:: https://github.com/vijos/jd4/actions/workflows/main.yml/badge.svg?branch=master\n    :target: https://github.com/vijos/jd4/actions\n\n.. contents::\n\nIntroduction\n------------\n\njd4 is a judging daemon for programming contests like OI and ACM. It is called\njd4 because we had jd, jd2, jd3 before. Unlike previous versions that use\nWindows sandboxing techniques, jd4 uses newer sandboxing facilities that\nappear in Linux 5.19+. jd4 also multiplexes most I/O on an event loop so that\nonly two extra threads are used during a judge - one for input, and one for\noutput, thus allowing blocking custom judge implementations.\n\nUsage\n-----\n\nPrerequisites:\n\n- Linux 5.19+\n- Docker\n\nPut config.yaml in the configuration directory, usually in\n``$HOME/.config/jd4``. Examples can be found under the ``examples`` directory.\nCreate a directory for caching problem data, such as ``$HOME/.cache/jd4``.\n\nUse the following command to pull and run jd4::\n\n    docker run --privileged \\\n        -v ~/.config/jd4/config.yaml:/root/.config/jd4/config.yaml \\\n        -v ~/.cache/jd4:/root/.cache/jd4 \\\n        vijos/jd4\n\nDevelopment\n-----------\n\nPrerequisites:\n\n- Linux 5.19+\n- Python 3.8+\n\nUse the following command to install Python requirements::\n\n    pip3 install -r requirements.txt\n\nThe python libraries require kernel headers and libffi-dev.\n\nPut ``config.yaml`` and ``langs.yaml`` in the configuration directory, usually\nin ``$HOME/.config/jd4``. ``config.yaml`` includes the server address, user and\npassword and ``langs.yaml`` includes the compiler options. Examples can be found\nunder the ``examples`` directory.\n\nWe recommend to use the following commands to initialize the config::\n\n    mkdir -p ~/.config/jd4\n    cp examples/config.yaml ~/.config/jd4/\n    ln -sr examples/langs.yaml ~/.config/jd4/\n\nBuild the cython extensions inplace::\n\n    python3 setup.py build_ext --inplace\n\nUse the following command to run the daemon::\n\n    python3 -m jd4.daemon\n\nNote that this requires a ``sudo`` to create cgroups on first execution.\n\nPlaying with the sandbox\n------------------------\n\nUse the following command to create and enter the sandbox::\n\n    $ python3 -m jd4.sandbox\n    [D 170312 15:15:38 selector_events:53] Using selector: EpollSelector\n    [I 170312 15:15:38 sandbox:153] sandbox_dir: /tmp/jd4.sandbox.k6ig1fv8\n    bunny-4.3$ ls\n    bin  etc  in  lib  lib64  out  proc  usr\n    bunny-4.3$\n\nThe ``in`` and ``out`` directory are bound to the corresponding directory\nin ``sandbox_dir``, where ``in`` is read-only and ``out`` has write permission.\n\nFAQ\n---\n\nHow are the programs sandboxed?\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWe unshare everything (namely mount, uts, ipc, user, pid and net), and then\ncreate a root filesystem using tmpfs and bind mount, finally ``pivot_root``\ninto it. We also use cgroup to limit the time, memory and number of processes\nof user execution.\n\nWhy are the sandboxes reused?\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWe noticed that sandbox creation took around 100ms, therefore becomes the\nbottleneck while judging small programs. With sandbox pooling, we see 300-400\nexecutions per second on our development machine.\n\nWhy is comparator written in Cython?\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe comparator needs to process the user output by characters (in other word\nbytes). This kind of operation is very slow in Python. We see a 50x+\nthroughput increment by using Cython (like 3MB/s to 200MB/s).\n\nCopyright and License\n---------------------\n\nCopyright (c) 2024 Vijos Dev Team.  All rights reserved.\n\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU Affero General Public License as\npublished by the Free Software Foundation, either version 3 of the\nLicense, or (at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU Affero General Public License for more details.\n\nYou should have received a copy of the GNU Affero General Public License\nalong with this program.  If not, see \u003chttp://www.gnu.org/licenses/\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvijos%2Fjd4","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvijos%2Fjd4","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvijos%2Fjd4/lists"}