We must catchup x.xx!

We must catchup x.xx! #

Иногда в логах возникает сообщение We must catchup x.xx! Это означает “Нам нужно догнать x.xx секунд”. Такая ошибка является серьезной. И связана с тем, что внешние скрипты, к которым обращается liquidsoap работают слишком долго, и не успевают ответить в положенный интервал времени, вынуждая liquidsoap догонять ушедшие часы.

Такое может быть при наличии источников динамического контента типа request.dymanic или get_process_lines когда скрипты долго отдают следующий url.

Есть еще один вариант запаздывания внутренних часов, on_metadata выполняется в основном потоке, поэтому посылка метаданных так же может тормозить основной поток. Один из вприантов решения этот добавить таймаут для выполнения функции обработчика метаданных, таким образом работа этой функции отправится в асинхронный поток, не тормозя основной.

Такое так же может быть при сложной обработке звука внутри скрипта liquidsoap.

ВАЖНО! Данная ошибка накапливается до определенного порога, и при превышении FIXME определенного порога радио остановится. При это в логах появится сообщение

Too much latency! Resetting active source...

РЕШЕНО! Для предотвращения подвисания основного потока при отправке метаданных внешним скриптам можно отправить сам процесс отправки метаданных в асинхронный поток. Пример кода


# функция выполняющаяся при смене метаданных.
# В неё приходят метаданные нового трека
def send_metadata(m) =
title = m["title"]
artist = m["artist"]
log(level=2,"Отправляем метаданные #{m['artist']} #{m['title']}")
end


# Будем играть треки из папки
radio = playlist('~/radio/my_mp3')

# защищаемся от пустоты в эфире
radio = mksafe(radio)

# отправляем метаданные
radio = on_metadata(fun(metadata) -> add_timeout(0., {send_metadata(metadata); 0.-1.}), radio)

# играем
output.pulseaudio(radio)