Установка и первый запуск: сборка, лог старта, первый запрос
От нуля до первого запроса нужно ровно две вещи: GCC и Python. Каждая строка лога и каждый ответ в этой главе — реальный вывод demo-single, его можно воспроизвести дословно.
Обзор
2.1 Введение
При развёртывании нового серверного стека мучительное — обычно не написание кода, а подготовка среды: Node требует nvm и node_modules, Go — toolchain и GOPATH, классическому C-сервису нужен собственный конвейер сборки. Ответ XServer — свернуть всё это в этап сборки и внутрь бинарника: при сборке ваш GCC создаёт xs.exe, одновременно TCC-компилятор, полный набор заголовков SDK и определения системных библиотек пакуются со сжатием LZMA внутрь бинарника; в рантайме на целевой машине устанавливать не нужно ничего.
Так что «установка XServer» — это два действия: один раз собрать хост, затем запустить готовый каталог приложения (demo-single). С них и начнём.
2.2 Сборка хоста
Предусловий всего два: GCC (выбирается через --cc) и Python 3. В корне репозитория xserver:
$ build.bat # минимальный вариант: default $ build.bat sqlite xtp # вкомпилировать расширения SQLite и XTP2 $ build.bat --list-extensions доступные расширения: sqlite, xtp
Эквивалент для Linux — bash build.sh sqlite xtp. Конвейер сборки делает пять вещей:
Последний шаг стоит подчеркнуть: артефакт заменяется только после успешной линковки. При неудачной сборке xs.exe в каталоге release остаётся нетронутым — эту «защиту от сбоя» охраняет отдельный тест-кейс; прерывание сборки в любой момент не оставит битый бинарник.
2.3 Запуск демо и разбор лога
demo-single — полное демонстрационное приложение из репозитория (маршрутизация, шаблоны, SQLite, контролируемые страницы). Зайдите в каталог и запустите:
$ cd release/demo-single $ ./xs.exe [xs] config loaded: D:\GIT\xserver\release\demo-single/xs.json (1 servers) [xs] server 'demo' class=http 127.0.0.1:9080 tls=off enabled [xs] default-host 'app' path=...\wwwroot devfile=...\main.c [xs] engine started, workers=12 [xs] script loaded: ...\main.c (2.6 KB gen 1) [demo] database opened: ...\db\main.db [xs] server 'demo' http bound on 127.0.0.1:9080 [xs] running, press Ctrl+C to stop
Что только что произошло — построчно:
| Строка лога | Смысл | На что смотреть |
|---|---|---|
config loaded (1 servers) | xs.json разобран | fail-fast: недопустимое поле завершит процесс здесь же с именем поля |
server 'demo' class=http ... | эхо конфигурации сервиса | последний взгляд на адрес / порт / TLS |
engine started, workers=12 | движок конкурентности готов | число worker из engine.workers, 0 = значение xrt по умолчанию (здесь 12) |
script loaded (2.6 KB gen 1) | компиляция TCC завершена | заметьте gen 1 — это «поколение», герой главы 3 |
[demo] database opened | ваш ServiceInit работает | строки с префиксом [demo] пишет сам скрипт приложения |
http bound on 127.0.0.1:9080 | прослушивание включено | при неудачном bind все уже занятые порты откатываются |
running, press Ctrl+C to stop | режим обслуживания | Ctrl+C / SIGTERM запускает пятифазную корректную остановку |
2.4 Отправка запросов
Откройте второй терминал и отправьте демо несколько запросов (весь вывод реальный):
$ curl -s http://127.0.0.1:9080/json {"server":"xs3 demo","ok":true,"host":"app"} $ curl -s http://127.0.0.1:9080/text demo-single ok (from includes/demo_extra.h) $ curl -s http://127.0.0.1:9080/api/v1/items/42 {"id":42,"name":"bench-write","created":1788494894} $ curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:9080/nope 404 $ curl -sI http://127.0.0.1:9080/json HTTP/1.1 405 Method Not Allowed Allow: GET
Что только что произошло:
/jsonпрошёл черезHandle_JSONв скрипте приложения — построение объекта через xvalue и сериализация (тема главы 18);/api/v1/items/42попал в динамический маршрут/api/v1/items/{id}; захваченный сегмент 42 искался в SQLite (глава 17);/nopeне совпал ни с одним маршрутом и обработчиком → 404;HEAD /jsonполучил 405 + Allow: GET — в маске методов маршрута зарегистрирован только GET, и HEAD был отвергнут в слоте метода до обработчика. Реальная деталь маршрутизации; глава 17 расскажет, как обрабатывать HEAD.
2.5 Контракт
- Потоки: число
workersфиксируется при старте и неизменно при горячей перезагрузке (изменения отклоняются). - Варианты: вариант сборки определяет доступные скрипту символы — в варианте default нет sqlite3_* / xtp2_*; их использование ломает компиляцию.
- Данные: db/main.db демо — настоящий файл данных; экспериментируйте смело, пересборка репозитория его восстановит.
Частые ошибки
- Симптом
bind failed, процесс завершается; при нескольких слушателях ранее занятые порты тоже не остаются обслуживаться наполовину.- Причина
- Целевой порт занят. Сборка XServer транзакционна: при отказе любого слушателя уже занятые полностью откатываются перед выходом — промежуточного состояния «половина сервиса работает» не бывает.
./xs
bind failed
./xs /* снова и снова, не зная, кто держит порт */netstat -ano | findstr 9080
/* сменить port в xs.json или завершить процесс-владелец */- Симптом
config load failed— хотя вы точно знаете, что xs.json лежит в каком-то каталоге.- Причина
- Без аргументов XServer ищет xs.json в каталоге исполняемого файла, а не в текущем рабочем. Скопируйте xs.exe куда-то отдельно и щёлкните — приложение он, конечно, не найдёт.
copy xs.exe C:\tools\
C:\tools\xs.exe /* config load failed *//* xs.json и каталог исходников рядом с exe;
* или явно указать путь к конфигу */
./xs D:\apps\myapp\xs.jsonУпражнения
Смените порт xs.json демо с 9080 на 19080, перезапустите и проверьте curl'ом.
http bound on 127.0.0.1:19080, а curl /json возвращает тот же JSON, что в главе.Пересоберите хост командой build.bat sqlite, запустите демо и убедитесь, что /api/list работает; затем верните вариант default и посмотрите, какую ошибку даст компиляция скрипта.
Зарегистрируйте в route.h демо маршрут /hello (GET), обработчик возвращает ваше имя. Проверяйте рестартом — горячая перезагрузка подождёт том 4; пока живём в модели «рестарт применяет».
curl /hello возвращает ожидаемое; в логе видно script loaded ... gen 2 (рестарт увеличивает счётчик поколений? Проверьте и найдите ответ в начале главы 3).Итоги
| Тезис | Вывод |
|---|---|
| Требования к среде | GCC + Python 3, и всё |
| Варианты сборки | build.bat [sqlite] [xtp]; атомарная замена только при успешной линковке |
| Порядок старта | config → engine → компиляция скрипта → ServiceInit → bind → running |
| Ключевые строки лога | gen N (поколение), workers=N, bound; строки с префиксом приложения — из вашего скрипта |
| Поиск конфигурации | xs.json ищется рядом с exe по умолчанию; путь можно передать явно |
- учебник xrt · среда разработки — детали GCC-инструментария, используемого сборкой хоста
- учебник xrt · отладка памяти — низкоуровневое оружие отладки (глава 6 вернётся к теме)