Skip to content
This repository was archived by the owner on Oct 23, 2023. It is now read-only.

Commit c004fb5

Browse files
committed
Added some documentation to the uis
1 parent c02a22d commit c004fb5

File tree

12 files changed

+261
-56
lines changed

12 files changed

+261
-56
lines changed

cpp/server/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ kj::MainFunc Main::getMain() {
4343
"Port to listen on")
4444
.addOptionWithArg(
4545
{'c', "cache-size"}, util::setUint(&Flags::cache_size), "<SZ>",
46-
"Maximum size of the cache, in megabytes. 0 means unlimited")
46+
"Maximum size of the cache, in MiB. 0 means unlimited")
4747
.callAfterParsing(KJ_BIND_METHOD(*this, Run))
4848
.build();
4949
}

cpp/worker/main.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@
22
#include <capnp/ez-rpc.h>
33
#include <thread>
44

5-
#include "capnp/server.capnp.h"
65
#include "util/daemon.hpp"
76
#include "util/flags.hpp"
87
#include "util/log_manager.hpp"
98
#include "util/misc.hpp"
109
#include "util/version.hpp"
1110
#include "worker/executor.hpp"
12-
#include "worker/manager.hpp"
1311

1412
const size_t EXP_BACKOFF_MIN = 1;
1513
const size_t EXP_BACKOFF_MAX = 60000;
@@ -86,7 +84,7 @@ kj::MainFunc Main::getMain() {
8684
"Maximum number of pending requests")
8785
.addOptionWithArg(
8886
{'c', "cache-size"}, util::setUint(&Flags::cache_size), "<SZ>",
89-
"Maximum size of the cache, in megabytes. 0 means unlimited")
87+
"Maximum size of the cache, in MiB. 0 means unlimited")
9088
.callAfterParsing(KJ_BIND_METHOD(*this, Run))
9189
.build();
9290
}

python/config.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
#!/usr/bin/env python3
22
import os
3-
from typing import List, Optional
43
import pytoml
5-
64
from task_maker.args import CacheMode, UIS, TaskFormat, Arch
5+
from typing import List, Optional
76

87

98
class Config:
@@ -55,7 +54,7 @@ def __init__(self):
5554
self.run_worker = False
5655
self.storedir = "~/.cache/task-maker/files"
5756
self.tempdir = "~/.cache/task-maker/temp"
58-
self.cache_size = 128
57+
self.cache_size = 2048 # in MiB
5958
self._get_host_port()
6059
self._resolve_dir()
6160

python/manager.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#!/usr/bin/env python3
22

3-
import os.path
4-
import subprocess
53
import time
64

5+
import os.path
6+
import subprocess
77
from task_maker.config import Config
88
from task_maker.task_maker_frontend import Frontend
99
from typing import List
@@ -69,6 +69,8 @@ def spawn_worker(config: Config):
6969
args += ["--keep_sandboxes"]
7070
if config.worker_name is not None:
7171
args += ["--name", config.worker_name]
72+
if config.worker_num_cores is not None:
73+
args += ["--num-cores", str(config.worker_num_cores)]
7274
if config.worker_port is not None:
7375
args += ["--port", str(config.worker_port)]
7476
if config.worker_address is not None:

python/uis/__init__.py

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,39 @@
11
#!/usr/bin/env python3
2+
import time
3+
24
import curses
35
import signal
46
import threading
5-
import time
67
import traceback
78
from abc import ABC, abstractmethod
89
from contextlib import contextmanager
910
from enum import Enum
10-
from typing import Dict, List, Optional
11-
1211
from task_maker.config import Config
1312
from task_maker.formats import Task
1413
from task_maker.printer import StdoutPrinter, Printer, CursesPrinter
1514
from task_maker.source_file import SourceFile
1615
from task_maker.task_maker_frontend import Result, ResultStatus, Resources
16+
from typing import Dict, List, Optional
1717

1818

1919
class SourceFileCompilationStatus(Enum):
20+
"""
21+
Status of the compilation of a source file
22+
- WAITING: the compilation has not started yet
23+
- COMPILING: the compilation has started
24+
- DONE: the compilation has successfully completed
25+
- FAILURE: the compilation failed
26+
"""
2027
WAITING = 0
2128
COMPILING = 1
2229
DONE = 2
2330
FAILURE = 3
2431

2532

2633
class SourceFileCompilationResult:
34+
"""
35+
Result information about a compilation of a source file
36+
"""
2737
def __init__(self, need_compilation):
2838
self.need_compilation = need_compilation
2939
self.status = SourceFileCompilationStatus.WAITING
@@ -32,11 +42,23 @@ def __init__(self, need_compilation):
3242

3343

3444
class UIInterface:
45+
"""
46+
This class is the binding between the frontend and the task format and the
47+
UIs. The format will register the solutions, the frontend will call its
48+
callbacks and the state is stored in this class (and in it's subclasses).
49+
The UI will use the data inside this.
50+
"""
3551
def __init__(self, task: Task, do_print: bool):
52+
"""
53+
:param task: The task this UIInterface is bound to
54+
:param do_print: Whether the logs should be printed to stdout (print
55+
interface)
56+
"""
3657
self.task = task
3758
self.non_solutions = dict(
3859
) # type: Dict[str, SourceFileCompilationResult]
3960
self.solutions = dict() # type: Dict[str, SourceFileCompilationResult]
61+
# all the running tasks: (name, monotonic timestamp of start)
4062
self.running = dict() # type: Dict[str, float]
4163
self.warnings = list() # type: List[str]
4264
self.errors = list() # type: List[str]
@@ -47,11 +69,16 @@ def __init__(self, task: Task, do_print: bool):
4769
self.printer = Printer()
4870

4971
def add_non_solution(self, source_file: SourceFile):
72+
"""
73+
Add a non-solution file to the ui (ie a generator/checker/...)
74+
"""
5075
name = source_file.name
5176
log_prefix = "Compilation of non-solution {} ".format(name).ljust(50)
5277
self.non_solutions[name] = SourceFileCompilationResult(
5378
source_file.language.need_compilation)
5479
self.printer.text(log_prefix + "WAITING\n")
80+
81+
# TODO: at some point extract those functionality into some wrapper
5582
if source_file.language.need_compilation:
5683

5784
def notifyStartCompiltion():
@@ -88,6 +115,9 @@ def getStderr(stderr):
88115
self.non_solutions[name].status = SourceFileCompilationStatus.DONE
89116

90117
def add_solution(self, source_file: SourceFile):
118+
"""
119+
Add a solution to the UI
120+
"""
91121
name = source_file.name
92122
log_prefix = "Compilation of solution {} ".format(name).ljust(50)
93123
self.solutions[name] = SourceFileCompilationResult(
@@ -130,18 +160,30 @@ def getStderr(stderr):
130160
self.solutions[name].status = SourceFileCompilationStatus.DONE
131161

132162
def add_warning(self, message: str):
163+
"""
164+
Add a warning message to the list of warnings
165+
"""
133166
self.warnings.append(message)
134167
self.printer.yellow("WARNING ", bold=True)
135168
self.printer.text(message.strip() + "\n")
136169

137170
def add_error(self, message: str):
171+
"""
172+
Add an error message to the list of errors, this wont stop anything
173+
"""
138174
self.errors.append(message)
139175
self.printer.red("ERROR ", bold=True)
140176
self.printer.text(message.strip() + "\n")
141177

142178
@contextmanager
143179
def run_in_ui(self, curses_ui: Optional["CursesUI"],
144180
finish_ui: Optional["FinishUI"]):
181+
"""
182+
Wrap a block in the UI's setup/teardown. A curses UI should be stopped
183+
before the program exists otherwise the terminal is messed up. This
184+
wrapper will start the UIs, yield and stop them after. At the end it
185+
will print with the finish ui
186+
"""
145187
if curses_ui:
146188
curses_ui.start()
147189
try:
@@ -159,6 +201,11 @@ def run_in_ui(self, curses_ui: Optional["CursesUI"],
159201

160202

161203
class FinishUI(ABC):
204+
"""
205+
UI used to print the summary of the execution
206+
"""
207+
# if the time / memory usage is greater of the limit * LIMITS_MARGIN that
208+
# time/memory is highlighted
162209
LIMITS_MARGIN = 0.8
163210

164211
def __init__(self, config: Config, interface: Optional[UIInterface]):
@@ -168,13 +215,22 @@ def __init__(self, config: Config, interface: Optional[UIInterface]):
168215

169216
@abstractmethod
170217
def print(self):
218+
"""
219+
Print the entire result summary
220+
"""
171221
pass
172222

173223
@abstractmethod
174224
def print_summary(self):
225+
"""
226+
Print only the summary grid with the overview of the results
227+
"""
175228
pass
176229

177230
def print_final_messages(self):
231+
"""
232+
Print the warning and error messages
233+
"""
178234
if not self.interface:
179235
return
180236
if sorted(self.interface.warnings):
@@ -267,34 +323,47 @@ def _print_exec_stat(self, time, memory, time_limit, memory_limit, name):
267323

268324

269325
class CursesUI(ABC):
326+
"""
327+
Running interface using the curses library to look nice in the terminal
328+
"""
329+
# limit the frame rate
270330
FPS = 30
271331

272332
def __init__(self, config: Config, interface: UIInterface):
273333
self.config = config
274334
self.interface = interface
335+
# the ui runs in a different thread
275336
self.thread = threading.Thread(
276337
target=curses.wrapper, args=(self._wrapper, ))
277338
self.stopped = False
278339
self.errored = False
279340

280341
def start(self):
342+
"""
343+
Start the UI starting the thread and messing up the terminal
344+
"""
281345
self.stopped = False
282346
self.thread.start()
283347

284348
def stop(self):
349+
"""
350+
Stops the thread and wait for it's termination. This will fix the
351+
terminal closing curses
352+
"""
285353
self.stopped = True
286354
self.thread.join()
287355

288356
def _wrapper(self, stdscr):
289357
try:
290358
curses.start_color()
291359
curses.use_default_colors()
292-
for i in range(1, curses.COLORS):
293-
curses.init_pair(i, i, -1)
360+
if hasattr(curses, "COLORS"):
361+
for i in range(1, curses.COLORS):
362+
curses.init_pair(i, i, -1)
294363
curses.halfdelay(1)
295364
pad = curses.newpad(10000, 1000)
296365
printer = CursesPrinter(pad)
297-
loading_chars = "-\\|/"
366+
loading_chars = r"◐◓◑◒"
298367
cur_loading_char = 0
299368
pos_x, pos_y = 0, 0
300369
while not self.stopped:
@@ -333,6 +402,10 @@ def _wrapper(self, stdscr):
333402

334403
@abstractmethod
335404
def _loop(self, printer: CursesPrinter, loading: str):
405+
"""
406+
The UI should inherit from this class and implement this method to print
407+
to the screen
408+
"""
336409
pass
337410

338411
def _print_running_tasks(self, printer: CursesPrinter):

python/uis/bulk_finish_ui.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,37 @@
11
#!/usr/bin/env python3
2-
from typing import List
32
import shutil
4-
5-
from task_maker.printer import StdoutPrinter
63
from task_maker.config import Config
4+
from task_maker.printer import StdoutPrinter
75
from task_maker.uis import FinishUI, UIInterface
86
from task_maker.uis.ioi import IOIUIInterface
97
from task_maker.uis.ioi_finish_ui import IOIFinishUI
108
from task_maker.uis.terry import TerryUIInterface
119
from task_maker.uis.terry_finish_ui import TerryFinishUI
10+
from typing import List
1211

1312

1413
def _horizontal_line():
14+
"""
15+
Print an horizontal line in the center of the screen
16+
"""
1517
size = shutil.get_terminal_size((80, 20))
1618
print("\u2014" * size.columns)
1719

1820

1921
class BulkFinishUI(FinishUI):
22+
"""
23+
Finish UI for bulk makes, this will take many UIInterfaces
24+
"""
2025
def __init__(self, config: Config):
2126
super().__init__(config, None)
2227
self.interfaces = list() # type: List[UIInterface]
2328
self.uis = list() # type: List[FinishUI]
2429
self.errors = list() # type: List[str]
2530

2631
def add_interface(self, interface: UIInterface):
32+
"""
33+
Add a new interface to track and later print the final result
34+
"""
2735
if isinstance(interface, IOIUIInterface):
2836
ui = IOIFinishUI(self.config, interface)
2937
elif isinstance(interface, TerryUIInterface):
@@ -35,9 +43,15 @@ def add_interface(self, interface: UIInterface):
3543
self.uis.append(ui)
3644

3745
def add_error(self, message: str):
46+
"""
47+
Add an error to the errors list
48+
"""
3849
self.errors.append(message)
3950

4051
def print(self):
52+
"""
53+
Print the final result of all the interfaces
54+
"""
4155
for ui in self.uis:
4256
_horizontal_line()
4357
ui.print()
@@ -46,6 +60,9 @@ def print(self):
4660
self.print_final_messages()
4761

4862
def print_summary(self):
63+
"""
64+
Print the summary of the executions of each task close together
65+
"""
4966
printer = StdoutPrinter()
5067
printer.blue("Bulk summary:\n", bold=True)
5168
for i, ui in enumerate(self.uis):
@@ -57,6 +74,9 @@ def print_summary(self):
5774
ui.print_final_messages()
5875

5976
def print_final_messages(self):
77+
"""
78+
Print the list of bulk errors
79+
"""
6080
if self.errors:
6181
printer = StdoutPrinter()
6282
print()

0 commit comments

Comments
 (0)