[О блоге] [наверх] [пред] [2022-11-25 23:16:11+03:00] [8357328821a1a6859a268197a618554b875a87c6]
Темы: [bittorrent]

BitTorrent клиент основанный на github.com/anacrolix/torrent

В прошлом после я написал о плюсах сабжевой библиотеки, но очень не
хотелось писать собственный frontend/клиент. А то, уж что я только не
переписываю под свои потребности последнее время.

Но когда я полез менять список DHT bootstrap нод, когда пошёл добавлять
возможность установки IPv6 адреса (в дополнение к IPv4), то пошло поехало
и вот я уже почти полностью cmd/torrent и переписал. Мне не нравится что
состояние скачанных кусочков хранится в одной БД на все торренты. Я хочу
по отдельности, как это было во всех прошлых клиентах. Благо, API
библиотеки позволяет написать свою piece completion реализацию. Я просто
скопировал основанную на BoltDB и сделал так, чтобы имя файла БД было с
хэшом от торрента. Сработало. Но надо конечно будет переделать на
хранение просто bitfield структуры.

Проверка всего этого, просмотр вообще всех issue проекта, показал что в
целом он вроде бы действительно очень и очень хорошо и эффективно со
всем справляется. Уже часть торрентов поставил seeder-оваться через
него. Работает реально лучше чем aria2. И это речь и про IPv6 и про DHT.
Вот только нет никакой возможности понять в каком состоянии находится
торрент: проверяется ли он с диска или нет. Судя по всему, библиотека
так просто устроена, что она просто говорит качать нужные кусочки, а
дальше уже, напротив piece completion БД, проверяется готовы ли они или
нет. Можно подписаться на события происходящие с кусочками, но если файл
уже полностью был проверен, то они вообще не возникают и можно только
косвенно понять что файл полностью скачан. Если просто добавить все
торренты для seed-а, то они честно в параллельных горутинах начинают
проверяться и сразу же параллельно раздаваться. Это конечно происходит
один раз, до создания piece completion БД, но делается полностью не
последовательно и поэтому медленно -- мои диски трещали не один час
из-за этого.

Как быть с frontend-ом для этого? Делать свой RPC и через него общаться?
К чёрту. Просто сделал FIFO файл, по аналогии с suckless проектами и по
аналогии как я делал в tofuproxy (432f7635faed298751cef04f0102deee68ea942f).
"cat list" буквально просто выдаст вывод аналогичный тому что был в
godiana (0c40b3f99ee554b301bd40b1b4d4c6390c746834) -- я прям copy-paste
кода оттуда сделал, раз всё равно ж написано. Пока это единственный FIFO
сейчас имеющийся.

Думаю что через FIFO буду и добавлять torrent-ы, так как сейчас любое
изменение требует перезапуска программы. Типа запускаем демон, а дальше
просто "cat torrent-list > fifos/add". И через FIFO (уже отработано в
tofuproxy) удалять их. Точно не уверен, но API вроде бы позволяет и
ставить на паузу их. И аналогично можно будет показывать информацию о
peer-ах и скачанных файлов.

По сути, вроде бы все мои хотелки с точки зрения useability будут
удовлетворены. Кроме одного: не нашёл возможности сохранять состояние
DHT. Но особо тут проблем и не вижу никаких. Не даром же я bootstrap
ноду то поднимал. И API не позволяет задавать целевую директорию
per-torrent. Но я код storage уже облазил и это не сложно будет
добавить, хотя и саму библиотеку придётся менять для этого.

Вот теперь я начинаю не любить Go. Был бы любой другой язык, то я долго
бы возился с добавлением одного только DHT/IPv6 адреса и даже мысли бы
не возникло переписать это всё с нуля для своих useability хотелок. А
тут затягивает и не можешь остановиться. Пока ещё никуда наработки не
выложил, так как надо бы закончить всю тему с FIFO и причесать перед
коммитом.

    [оставить комментарий]