<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Development of an automated system for conducting, checking and evaluating programming competitions</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Bohdan V. Hrebeniuk</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Olena H. Rybalchenko</string-name>
          <email>rybalchenko@knu.edu.ua</email>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Kryvyi National University</institution>
          ,
          <addr-line>11 Vitalii Matusevych Str., Kryvyi Rih, 50027</addr-line>
          ,
          <country country="UA">Ukraine</country>
        </aff>
      </contrib-group>
      <fpage>104</fpage>
      <lpage>114</lpage>
      <abstract>
        <p>The paper analyzes the existing platforms for conducting programming contests. Possible approaches are analyzed for creating isolated environments and running participants' solutions, advantages and disadvantages of both approaches are highlighted. Requirements for the user interface are defined that must provide quick and convenient work in the system; the system was planned and developed. It was concluded that designed system has a potential for conducting contests and further development.</p>
      </abstract>
      <kwd-group>
        <kwd>eol&gt;competiteve programming</kwd>
        <kwd>isolated environment</kwd>
        <kwd>virtualization</kwd>
        <kwd>containerization</kwd>
        <kwd>REST</kwd>
      </kwd-group>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>1. Introduction</title>
      <p>Competitive programming has been maintaining a dynamic development rate for several decades.
Year by year, more and more teams take part in local, regional and international contests,
therefore making the needs of both contest organizers and participants grow.</p>
      <p>Kryvyi Rih National University supports the development of competitive programming –
local contests are held, and the university annually hosts the qualification phase of the
international student contest under the aegis of ACM/ICPC. To maintain the level of students and
teachers competence, it is necessary to have our own flexible system, since existing analogues
have certain disadvantages.</p>
      <p>The aim of the work is to study and analyze the process of creating isolated environments,
design and develop a flexible system for conducting, checking and evaluating programming
contests.</p>
    </sec>
    <sec id="sec-2">
      <title>2. Development of a system for conducting, checking and evaluating programming competitions</title>
      <sec id="sec-2-1">
        <title>2.1. Analysis of existing systems</title>
        <p>
          One of the first systems with automatic checking of tasks is UVa Online Judge, an online system
of the University of Valladolid with an installed task archive. The archive is constantly being
updated, but it is impossible to create tasks yourself using this system – any system updates
(uploading new tasks, supporting new programming languages, changing the rules for creating
a rating) are possible only with permission and active interaction with developers. Additionally,
downloading the software and installing it for use are prohibited due to the product license,
because the system uses the “SaaS” (Software as a Service) model [
          <xref ref-type="bibr" rid="ref1">1</xref>
          ]. Under this model, the
software is not installed on users’ computers, but on the provider’s servers, and the user does
not have any access to the system. This disadvantage makes the system unsuitable for
longterm contests due to the fact that the terms of the service provider can change at any moment
and the user (in our case, the organizer of the contest) will not be able to do anything [
          <xref ref-type="bibr" rid="ref2">2</xref>
          ].
        </p>
        <p>
          One of the most successful systems in history was PCSM2, which was formed by combining
the APPES and PCMS systems and is characterized by the flexibility of the internal structure.
Software units have low connectivity due to the fact that they rely on high-level abstractions
of each other. This makes the PCSM2 system easy to upgrade on a programming level. But
this flexibility has made it dificult to customize the server, as most of the business logic is
described by configuration files. Some parts of the system are still being developed, so to set
them up, you need to add and connect specialized modules that only the authors of the system
can perform. Another serious drawback is that the PCSM2 server supports only the Windows
operating system, which makes it dificult to run the system on servers that use Linux [
          <xref ref-type="bibr" rid="ref3">3</xref>
          ].
        </p>
        <p>
          The qualification phases of the ACM/ICPC contests are managed by the ejudge system [
          <xref ref-type="bibr" rid="ref4">4</xref>
          ],
which is significantly diferent from PCSM2. The system was created using the C programming
language, it supports only the Linux operating system, has a web interface for administration
and detailed documentation, but also has a number of disadvantages. The most important of
these is the ineficient allocation of resources between the system and processes with user’s
solutions. As a result, incorrect verdicts may occur due to exceeding the time limit. The system
also doesn’t support scaling out — you can’t connect a new machine to an existing one. The
only way to improve parallel code execution is to increase the number of processes on the
server, which can lead to competition for process access to RAM. An equally important factor
is linking the system to the operating system. This dependency makes it impossible to deploy
the project on servers that do not support Linux.
        </p>
      </sec>
      <sec id="sec-2-2">
        <title>2.2. Analysis of approaches of running participants’ code</title>
        <p>Automation of contest processes has become a necessary condition for such events, because
with the increase in the number of teams and tasks, the required amount of time for receiving
solutions, checking them, and summing up results has also significantly increased. And,
although such systems have existed for decades, with the introduction of new technologies, new
opportunities for their creation appear.</p>
        <p>
          To protect such systems from malicious user code actions, the common practice is to run the
code in some isolated environment. This makes the system protected from malicious solutions
that may attempt to interfere with the evaluation process [
          <xref ref-type="bibr" rid="ref5">5</xref>
          ].
        </p>
        <p>One potential solution to this problem can be virtual machines that emulate a hardware
server. In this event, all components of a real computer are virtualized – I/O devices, hard
disk, ports, etc., followed by the installation of the operating system. Although such system is
isolated from the host, using virtual machines means running the entire operating system and
allocating resources to emulate virtualization, which often negatively afects the performance
of the platform.</p>
        <p>
          An alternative way to achieve process isolation is containerization, in which the source code
of the program is encapsulated along with dependencies to run on any infrastructure in an
isolated environment [
          <xref ref-type="bibr" rid="ref6">6</xref>
          ]. Unlike virtual machines, containers allow you to run software in a
single process, isolated from each other, on a single host, using the resources of an existing
operating system. Since containers are only a part of the operating system, they are sometimes
less flexible to use, for example, they can only run programs that are compatible with the
current system [
          <xref ref-type="bibr" rid="ref7">7</xref>
          ].
        </p>
        <p>
          Despite mentioned limitations, containers are widely used to create an isolated process
environment. One of the most well-known examples of such containers is “chroot jail”. The idea
is to copy (or create) links to the system files needed to run processes. After that, restrictions
are set for the created processes — the root directory of the system is changed to the root
directory of the environment. Since processes cannot refer to paths outside the modified root,
they cannot perform malicious operations in these locations [
          <xref ref-type="bibr" rid="ref8">8</xref>
          ]. Containerization is the best
option for the system being created, because containers allow you to run programs in an
isolated environment with restrictions on system resources and at the same time work only in
one process of the operating system.
        </p>
      </sec>
      <sec id="sec-2-3">
        <title>2.3. Docker usage</title>
        <p>One of the tools for working with containerization is Docker, which allows you to create an
isolated space for a process using the Linux kernel namespace. Each container creates its own
spaces with unique access, including the following:
• PID namespace (for process isolation);
• NET namespace (for managing network interfaces);
• IPC namespace (for managing access to IPC resources);
• MNT namespace (for managing file system mounting points), etc.</p>
        <p>Docker also uses kernel control groups to allocate resources and isolate them. These groups
set limits for the program for certain resources, including:
• memory control groups;
• CPU control groups;
• control groups of devices, and so on.
• compiling the user’s code;
• running the user’s code.</p>
        <sec id="sec-2-3-1">
          <title>The containers must be used in our platform for the next purposes:</title>
          <p>Therefore, it is necessary to have two containers for each programming language in the
system – one container compiles the code, the second executes it. Creating containers is achieved
by running images, which in turn encapsulate all the components and dependencies needed to
run the application. Images are created using Dockerfile - text files with instructions created
according to the rules of a Dockerfile syntax.</p>
          <p>For example, let’s take a DockerfileBase file for creating images for the Python programming
language:
FROM python:3.7.5-slim
COPY compile_py.py .</p>
          <p>This file describes the image that will be based on the python:3.7.5-slim image, the oficial
Python version 3.7.5 image, the slim build. Copy the script to the virtual address space
compile.py, which is responsible for compiling the user’s code. The contents of the file are shown
below:
import pathlib
import py_compile
import sys
if len(sys.argv) != 3:</p>
          <p>raise ValueError(’Wrong amount of arguments!’)
_, input_file, output_file = sys.argv
input_file_path = pathlib.Path(input_file)
if not input_file_path.exists():</p>
          <p>raise ValueError(’There is no user file!’)
py_compile.compile(input_file, output_file, doraise=True)</p>
          <p>The base image (python-base) is created before the platform starts working. Based on this
image, we create two new images – DockerfileCompiler and DockerfileRunner for compiling
and running code respectively. The content of DockerfileCompiler is shown below:
FROM python-base
COPY ./code /code
CMD ["python", "compile_py.py", "./code/main.py", "./code-compiled/main.pyc"]</p>
        </sec>
        <sec id="sec-2-3-2">
          <title>The content of the DockerfileRunner file is as follows:</title>
          <p>FROM python-base
COPY ./code-compiled /code-compiled
CMD ["python", "/code-compiled/main.pyc"]</p>
          <p>For each new user solution, a pair of such images will be created. An image based on
DockerfileCompiler copies the code directory to its virtual address space and runs the script
compile.py, which compiles the source code to byte-code. Due to the presence of volume (which
must be configured before starting the container), the contents of the directory will remain
available to other processes, in particular for the image created from the DockerfileRunner file,
on the basis of which the container will execute the compiled code.</p>
          <p>To simplify interaction with the Docker Engine API, which is an interface in the form of an
HTTP client for other applications, a facade is implemented that is a wrapper over the client.
Its main task is to define the interface of a real client by transferring the necessary methods to
a single class:
• build-creates an image based on a specific Docker file and assigns it a name;
• run-starts a container with a specific configuration based on the specified image and
returns the result of its operation;
• remove-deletes a specific image.</p>
          <p>This class is used in “workers” – components that encapsulate the logic of working with
containers and images for a given set of programming languages. Workers are waiting for the
user’s solution, which is used to create a context for running code, namely:
• creating a directory with further configuring volumes;
• building a “Compiler” – an image and creating a one-time container based on it;
• building a “Runner” image based on a compiled solution.</p>
          <p>To avoid creating new “Runner” images to run the solution with diferent tests, input data
is passed in arguments to run the container. After testing the solution, the docker context is
destroyed (images and containers are deleted).</p>
          <p>After implementing a software component to run user solutions, the next step is to create a
system that meets business requirements.</p>
        </sec>
      </sec>
      <sec id="sec-2-4">
        <title>2.4. System’s architecture</title>
        <p>The client-server architecture was chosen as the basis for the created software, so the selection
of frameworks for developing both the backend and the frontend turned out to be an important
issue.</p>
        <p>
          The Python programming language (specifically version 3.7.4) was used to develop the
backend. Although Django and Flask are the leading frameworks for creating Python web
applications, a relatively new aiohttp framework was chosen to develop our system. The framework
uses new features of the language, namely support for asynchronous programming at the
syntax level [
          <xref ref-type="bibr" rid="ref9">9</xref>
          ]. The main concept of this paradigm is the use of deferred calls, which violate the
usual order of instructions execution. At the same time, the resource usage model significantly
difers from the model using processes and threads – there is only one thread in an
asynchronous application, and new requests are served using asynchronous I/O primitives of the
operating system – as a result, a small amount of resources is used for allocating new
connection. Although the framework was created relatively recently (the first oficial “stable” release
dates back to September 16, 2016), 3 major updates were released in this short period of time,
and the framework repository on GitHub became the “main” one in AIO-libs, a community
of programmers who develop Python packages and modules for asynchronous programming
[
          <xref ref-type="bibr" rid="ref10">10</xref>
          ].
        </p>
        <p>
          The choice of such a framework afected the choice of database, because there is only one
adapter written for Python that supports asynchronous database access - that is psycopg2, a
connector for PostgreSQL. Based on this adapter, the aiopg library package was created, which
implements a DBAPI interface with asynchronous syntax support and is responsible for
supporting SQLAlchemy, a library for working with relational databases using ORM Technology
[
          <xref ref-type="bibr" rid="ref11">11</xref>
          ].
        </p>
        <p>
          It is worth noting that not only PostgreSQL implements support for asynchronous
operations. The MySQL DBMS also has it, but there is no oficial client for the Python programming
language that would support this mode, so the PostgreSQL was chosen [
          <xref ref-type="bibr" rid="ref12">12</xref>
          ].
        </p>
        <p>The React framework was chosen for the frontend. The programming code created using
this framework is modular, i.e. it consists of loosely coupled components that can be reused
in several places at once. Thanks to the virtual DOM, applications created using React run
much faster than alternative frameworks (for example, Angular). The Redux library, a
platform with unidirectional data flow and centralized data storage, was used to manage the
application status. These features of the platform allow you to implement a predictable and
easyto-understand system for moving an application from one state to another.</p>
        <p>
          REST was chosen as the architectural style of interaction between the backend and the
frontend. Some features of this architecture are described below [
          <xref ref-type="bibr" rid="ref13">13</xref>
          ]:
• client-server architecture – separating the interface from business logic simplifies the
portability of the user interface to diferent platforms and increases scalability by
simplifying server components;
• state absence – each request to the server must contain all the necessary information
for its successful execution, i.e. the server does not store any context between diferent
requests (for example, in the form of sessions), and all information needed for the user’s
“session” is stored on the client’s side (for example, an access token);
• uniform interface – following REST involves creating a “virtual” resource system, in
which each of the resources has universal methods for working with it, including
creating, reading, updating, and deleting. However, the true location of the entity (for
example, in a database) may be located in a diferent virtual space.
        </p>
        <p>The functional diagram shows a graph with transitions from one state of the program to
another. When initializing the system, connections to the Docker Engine API are created;
connecting to the database and starting the web server. After that, the system waits for a
request from the user.</p>
        <p>Each request to the system’s API is accompanied by user authorization – it checks whether
the user can have access to the specified resource. If authorization fails, the user is sent a
message describing the cause of the error. In other case, the request goes further through the
system.</p>
        <p>There are two main types of API requests:
• a “CRUD request” is a request for manipulating an entity that requires interaction with
the database;
• a code execution request is a request to execute code from the user in order to get the
result of the program. The request requires interaction with the Docker Engine API.</p>
      </sec>
      <sec id="sec-2-5">
        <title>2.5. User interface and user experience</title>
        <p>One of the necessary requirements for the system is the speed and convenience of creating and
conducting competitions, so certain restrictions were set on the system interface for efective
user experience.</p>
        <p>The most important of them is that the user should not be focusing on the elements that are
not related to the context of the current resource - it is necessary to create a virtual space that
does not allow the user to move randomly around the system, but on the contrary, suggests
the right actions to achieve the goal.</p>
        <p>For example, the pages “view available competitions” and “create a new competition” belong
to the same type of system resources - “competitions”, so manipulations on this resource are
“close” to each other in the virtual space of the system.</p>
        <p>When viewing a specific competition, the user has more features, so the header has
significantly more elements – the virtual space has expanded significantly at this stage, and links to
loosely linked pages (creating a new competition) are not displayed.</p>
        <p>The user experience of the system is based on building clear sequences of actions that lead
to resources in one most intuitive way. This design allows you to focus the user’s attention on
performing the planned action, instead of confusing them with oversaturated pages and long
transitions.</p>
      </sec>
    </sec>
    <sec id="sec-3">
      <title>3. Conclusions</title>
      <p>Research on technologies for creating isolated environments has shown that containerization,
despite a number of disadvantages, is well suited for running processes isolated from each
other. The use of virtual machines, on the contrary, could lead to irrational use of system
resources, so it was decided to use containers as components for running user code.</p>
      <p>After the development of this component, a system for holding contests was created, which
can be used by both participants and contests organizers. A scheme for a relational database is
designed for the system. The software is designed to emulate the client/server architecture,
using Python and JavaScript. The system has passed several tests, which have shown an efective
system operation and a great potential for further development.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>O. M.</given-names>
            <surname>Markova</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S. O.</given-names>
            <surname>Semerikov</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A. M.</given-names>
            <surname>Striuk</surname>
          </string-name>
          ,
          <article-title>The cloud technologies of learning:</article-title>
          <source>Origin, Information Technologies and Learning Tools</source>
          <volume>46</volume>
          (
          <year>2015</year>
          )
          <fpage>29</fpage>
          -
          <lpage>44</lpage>
          . URL: https://journal.iitta. gov.ua/index.php/itlt/article/view/1234. doi:
          <volume>10</volume>
          .33407/itlt.v46i2.
          <fpage>1234</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>D.</given-names>
            <surname>Irtegov</surname>
          </string-name>
          ,
          <string-name>
            <given-names>T.</given-names>
            <surname>Nesterenko</surname>
          </string-name>
          ,
          <string-name>
            <given-names>T.</given-names>
            <surname>Churina</surname>
          </string-name>
          ,
          <article-title>Systems for automated evaluation of programming tasks: Development, use and perspectives</article-title>
          ,
          <source>Vestnik NSU. Series: Information Technologies</source>
          <volume>17</volume>
          (
          <year>2019</year>
          )
          <fpage>61</fpage>
          -
          <lpage>73</lpage>
          . doi:
          <volume>10</volume>
          .25205/1818-7900-2019-17-2-61-7.
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>D.</given-names>
            <surname>Irtegov</surname>
          </string-name>
          ,
          <string-name>
            <given-names>T.</given-names>
            <surname>Nesterenko</surname>
          </string-name>
          , T. Churina,
          <article-title>Development of automated evaluation systems for programming tasks</article-title>
          ,
          <source>System Informatics Journal</source>
          (
          <year>2017</year>
          )
          <fpage>91</fpage>
          -
          <lpage>116</lpage>
          . doi:
          <volume>10</volume>
          .31144/si. 2307-
          <fpage>6410</fpage>
          .
          <year>2017</year>
          .n11.
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <surname>ejudge</surname>
            <given-names>system</given-names>
          </string-name>
          ,
          <year>2020</year>
          . URL: https://ejudge.ru/wiki/index.php/%D0%
          <article-title>A1%D0%B8%D1%81% D1%82%D0%B5%D0%BC%D0%B0_ejudge.</article-title>
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          <article-title>[5] Selected papers ofthe International Conference joint withthe XXII International Olympiad in InformaticsWaterloo, Canada</article-title>
          ,
          <source>August 14-21</source>
          ,
          <year>2010</year>
          , volume
          <volume>4</volume>
          , Institute of Mathematics and Informatics, Vilnius, Lithuania,
          <year>2010</year>
          . URL: https://ioinformatics.org/files/volume4. pdf.
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>IBM</given-names>
            <surname>Cloud Education</surname>
          </string-name>
          , Containerization explained,
          <year>2019</year>
          . URL: https://www.ibm.com/ cloud/learn/containerization.
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>J.</given-names>
            <surname>Turnbull</surname>
          </string-name>
          ,
          <source>The Docker Book: Containerization Is the New Virtualization</source>
          ,
          <year>2014</year>
          . URL: https://dockerbook.com/.
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          <article-title>[8] chroot “jail” - what is it and how do I use it</article-title>
          ?,
          <year>2010</year>
          . URL: https://unix.stackexchange.com/ questions/105/chroot-jail
          <article-title>-what-is-it-and-how-do-i-use-it.</article-title>
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>Y.</given-names>
            <surname>Selivanov</surname>
          </string-name>
          , PEP 492 -
          <article-title>Coroutines with async</article-title>
          and
          <source>await syntax</source>
          ,
          <year>2015</year>
          . URL: https://www. python.org/dev/peps/pep-0492/.
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <article-title>aio-libs: The set of asyncio-based libraries built with high quality</article-title>
          ,
          <year>2021</year>
          . URL: https:// github.com/aio-libs.
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [11]
          <string-name>
            <given-names>A.</given-names>
            <surname>Svetlov</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Firsov</surname>
          </string-name>
          , Welcome to AIOPG,
          <year>2020</year>
          . URL: https://aiopg.readthedocs.io/en/ stable/.
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [12]
          <article-title>Is there an asynchronous Python client for MySQL with pooling features?</article-title>
          ,
          <year>2015</year>
          . URL: https://www.quora.com/ Is-there
          <article-title>-an-asynchronous-Python-client-for-MySQL-with-pooling-features.</article-title>
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          [13] restfulapi.net,
          <source>What is REST</source>
          ,
          <year>2020</year>
          . URL: https://restfulapi.net/.
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>