Консоль не вешает вкладку под потоком логов сборки
Загрузка мира со сборкой модов печатает десятки тысяч строк: каждое исключение мода — стек на два десятка строк. Консоль рисовала их по одной и после каждой прокручивалась вниз, заставляя браузер пересчитывать раскладку всего списка. Десять тысяч строк блокировали вкладку на 29 секунд, и запуск сервера выглядел как зависшая панель. Строки копятся и выводятся пачкой раз в кадр: те же десять тысяч теперь занимают 14 мс. Узлы сверх предела списка не создаются вовсе, а на скрытой вкладке очередь ограничена, чтобы не расти в памяти. Заодно вывод игрового сервера больше не гоняется через словарь переводов: он английский, в словаре менеджера его нет, а перебор шаблонов регулярками на таком потоке стоит дорого. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -85,9 +85,15 @@ func (s *Server) handleLogs(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
// translatable отсеивает вывод самого игрового сервера: он на английском и в
|
||||
// словаре менеджера его нет. Перебирать ради него все шаблоны накладно —
|
||||
// загрузка мира со сборкой модов печатает десятки тысяч строк.
|
||||
func translatable(stream string) bool {
|
||||
return stream == "manager" || stream == "task"
|
||||
}
|
||||
|
||||
// translateLines переводит строки консоли на язык читающего. Буфер один на
|
||||
// всех, поэтому перевод делается на выходе, у каждого подключения свой. Вывод
|
||||
// самого игрового сервера через словарь проходит без изменений: он английский.
|
||||
// всех, поэтому перевод делается на выходе, у каждого подключения свой.
|
||||
func translateLines(r *http.Request, lines []pzserver.LogLine) []pzserver.LogLine {
|
||||
lang := i18n.FromRequest(r)
|
||||
if lang == i18n.Default {
|
||||
@@ -95,7 +101,9 @@ func translateLines(r *http.Request, lines []pzserver.LogLine) []pzserver.LogLin
|
||||
}
|
||||
out := make([]pzserver.LogLine, len(lines))
|
||||
for i, line := range lines {
|
||||
line.Text = i18n.T(lang, line.Text)
|
||||
if translatable(line.Stream) {
|
||||
line.Text = i18n.T(lang, line.Text)
|
||||
}
|
||||
out[i] = line
|
||||
}
|
||||
return out
|
||||
@@ -149,7 +157,9 @@ func (s *Server) handleLogStream(w http.ResponseWriter, r *http.Request) {
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
line.Text = i18n.T(lang, line.Text)
|
||||
if translatable(line.Stream) {
|
||||
line.Text = i18n.T(lang, line.Text)
|
||||
}
|
||||
if !writeSSE(w, line) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package api
|
||||
|
||||
import "testing"
|
||||
|
||||
// Вывод игрового сервера идёт мимо словаря: он английский, а перебор шаблонов
|
||||
// на десятках тысяч строк загрузки мира стоит дорого.
|
||||
func TestTranslatableOnlyManagerStreams(t *testing.T) {
|
||||
for _, stream := range []string{"manager", "task"} {
|
||||
if !translatable(stream) {
|
||||
t.Errorf("строки потока %q должны переводиться", stream)
|
||||
}
|
||||
}
|
||||
for _, stream := range []string{"stdout", "stderr", ""} {
|
||||
if translatable(stream) {
|
||||
t.Errorf("строки потока %q переводить незачем", stream)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user