
Когда мы задумывали Startpoint.uz, у нас была амбициозная цель: студент не должен чувствовать разницы между VS Code на своем ноутбуке и нашим редактором в браузере. Никаких имитаций - только настоящий код, настоящий терминал и настоящее окружение. Чтобы кнопка "Run" работала магически быстро, нам пришлось построить сложную систему оркестрации, о которой мы сегодня и расскажем.
Frontend: Больше, чем просто редактор текста
То, что вы видите в браузере - это сложный SPA. За основу редактора кода мы взяли Monaco Editor (тот самый движок, на котором работает VS Code), а для терминала используем xterm.js. Но самое интересное - как это всё общается с сервером.
Связь гибридная. HTTP и WebSockets. Мы разделили потоки данных, чтобы оптимизировать нагрузку:
HTTP(S) используется для "тяжелого" контента. Когда вы открываете файл, его содержимое прилетает обычным GET-запросом.
WebSockets - это нервная система IDE. Через сокеты в реальном времени летит:
Главные челленджи фронтенда:
Умное автосохранение. Мы не могли просто сохранять файл при каждом нажатии клавиши (это убило бы сеть). Пришлось писать сложную логику дебаунса (задержки) и очереди запросов, чтобы сохранение было надежным, но незаметным.
AFK-режим (Away From Keyboard). Виртуальные серверы стоят денег и ресурсов. Если студент открыл вкладку и ушел пить чай на 2 часа, мы не можем держать контейнер запущенным. Мы внедрили систему отслеживания активности: если пользователь бездействует, мы рвем соединение по WebSockets и "усыпляем" контейнеры, экономя ресурсы.
Обработка ошибок. "Упал" интернет? Контейнер не запустился? Лимит памяти? Фронтенд должен уметь отличать десятки типов ошибок и понятно объяснять студенту, что произошло. Но всё еще ловим ошибки и быстро их устраняем.
Backend: Оркестр контейнеров
Самая "мякоть" находится на серверах. Для каждой практики под каждого студента мы поднимаем изолированную сеть Docker-контейнеров.
Как это работает: Когда вы заходите в урок, наш Оркестратор раздает команды:
Терминал в браузере. Чтобы соединить веб-интерфейс с Linux-консолью, мы взяли утилиту GoTTY (написана на Go) и серьезно её допилили под свои нужды. Она транслирует ввод/вывод из контейнера прямо в WebSocket, который слушает xterm.js на клиенте.
Парадокс "Свобода в ограничениях"
Нам нужно дать студенту полную свободу: пиши любой код, создавай файлы, ломай систему. Но при этом мы не можем допустить, чтобы один студент "положил" весь сервер. Решение: Тонкая настройка Docker. Контейнер выглядит для пользователя как полноценный Linux, но он жестко ограничен по CPU и RAM, а также изолирован от хост-системы.
Live-синхронизация (inotify)
Если код создает новый файл (например, лог работы программы), он должен мгновенно появиться в дереве файлов слева. Мы используем inotify на сервере, чтобы следить за изменениями файловой системы и через сокеты пушить уведомления на фронт: "Эй, тут файл создался, отрисуй его!".
Веб-превью (Port Forwarding)
Как учить React или HTML, если не видишь результат? Для веб-практик мы настроили динамический проброс портов. Когда вы запускаете локальный сервер внутри контейнера (например, на порту 3000), наша система проксирует его наружу. Вы получаете уникальную ссылку и видите свой сайт так, будто он запущен локально.
Итог
Так мы описали то, что легко и быстро вспоминается. Возможно что-то упустили, но всегда открыты к вопросам!
IDE в Startpoint - это результат сотен часов отладки, настройки Linux-ядра и оптимизации JS. Мы сделали это сложным внутри, чтобы для вас обучение было простым снаружи.