Skip to content

Overview

What is Showdown?

Showdown is a portable remote code execution and judge server, written in GoLang, that supports multiple popular programming languages. It comes with an already-built docker image with compilers and runners for selected programming languages and configurations to use the required binaries to execute the code based on the language provided.

It acts as a server that listens to requests for code execution and processes the requests either in asynchronous mode or immediate mode, depending upon the configuration. It's customizable in terms of execution and the configuration gives you enough control over your application-specific setup. It uses RabbitMQ for a queue that allows the Showdown to consist of multiple instances on different servers and act together as a distributed network worker.

How it works?

There are 4 key parts of its design.

  1. Application (Standalone/Manager/Worker)
  2. Isolate (Sandbox for securely executing untrusted programs)
  3. Compilers (Docker image with collection of compilers/runners)
  4. Message queue (RabbitMQ)

The application, which is Showdown, is a mediator between the client/user and the compilers. It is responsible for listening to user requests for any code execution. It parses the request and extracts the language, based on which it selects the appropriate compiler or the runner for the language and at last, executes it.

For execution, it utilizes Isolate, which is a sandbox that allows Showdown to isolate the code submitted by the user and execute it safely. Using it we can set up CPU time or memory limits as well.

Now the application can be started on your local machine. You can specify the paths of the required compilers in its config file. Otherwise, an ideal condition (recommended) to start it would be through the docker images provided. The images are based upon our Compilers image which is already a package of supported languages and Isolate installation which is required for Showdown to work.

At last, the application can work in 3 modes. Worker, whose only job is to consume the available execution requests lying in the message queue. Manager, which is only responsible for listening to user requests and just adding the request into the message queue. Standalone, which is quite self-explanatory; starting a standalone instance would be sufficient for small or most use cases, as you won't be required to run manager or worker instance separately.