Очень тяжёлая доработка бота
Вчера немного доработал SiteKnockerBot. Сделал выгрузку лога в CSV (заодно и разобрался, как в TG отправлять файлы с помощью php curl) вместо обычных сообщений, а также предусмотрел возможность логгирования запросов и ответов в случае необходимости. И ещё немного поменял настройки бота, чтобы уменьшить число ложных собрани срабатываний (но толком не помогло: сегодня утром опять случилось). Хотя на первый взгляд, доработки казались очень простыми: выяснить, как в Go получить полный текст HTTP-запроса и ответа, создать несколько полей в таблицах и обеспечить запись туда, проблемы сыпались одна за другой. Постоянно были какие-то проблемы с сохранением запросов в таблицу. В Go строке нельзя взять и присвоить nil, и я долго не мог понять, как сохранить в базу null. Пытался применить NullString, но не работало. Так и сдался, применил костыль с двумя вариантами sql-запроса.
После этого дописал генерацию CSV-файла уже на PHP (на нём написана интерфейсная часть бота, которая отвечает на запросы пользователя), но и тут посыпались проблемы, и весьма серьёзные: начал падать сам PHP с segmentation fault. Долго не мог понять, почему. Попробовал скопировать тот код, который мне сгенерировал ChatGPT при ответе на вопрос, как отправить файл в Telegram — всё работает. Добавляю с минимальными изменениями в бот — нет. Ошибка оказалась предельно дурацкой: я передавал класс CurlFile в curl_setopt не как элемент хеш массива с параметрами, а вместо него. Но на то, чтобы это найти, ушло часа полтора.
Кстати, тут надо бы изучить получше, что именно приводит к segmentation fault: сама передача этого класса в качестве параметра или ошибочное добавление к нему лишних полей, а также выяснить, осталось ли это в последних версиях, и сделать bug report разработчкам самого PHP.
Потом опять начались проблемы с сохранением в базу данных, но уже не на локали, а на сервере. Опять долго не мог понять, почему, думал, дело в боте. Оказалось, что нет, в кодировке таблицы в MySQL: нужно было поменять её с utf8 на utf8mb4. И только после этого всё почти заработало. Но вылез last minute bug: я решил вынести количество запрашиваемых с сервера байтов из hard-coded в заголовке Range в константу. И тут внезапно полезли проблемы на ровном месте. Как известно, Go — строго типизированный язык, и там присоединить число к строке, написав что-то вроде "Range: 0-"+MAX_LEN нельзя. (Это вам не JavaScript). Я по привычке из Python или PHP написал string(MAX_LEN) и думал, что всё в порядке. Но потом с удивлением обнаружил то, что резко выросло число ошибок со статусом 416, которые я не видел прежде. В том числе и а на моих собственных сайтах, для которых я включил сохранение отладочной информации. И там я увидел, что в заголовке Range вместо 128000 стоит непонятный Unicode-символ. Оказывается, в отличие от скриптовых языков, Go преобразует число в Unicode-символ, а не строковое представление. Стал это исправлять, но было уже 5 часов, голова соображала плохо, и ещё несколько раз допускал глупые ошибки, прежде чем сделал всё как надо.
В общем, день закончился с очень противоречивыми впечатлениями: с одной стороны, доволен, что всё же сделал задуманное. С другой — злостью на себя, что провозился так долго и не поиграл в The Council, и вообще лёг спать слишком поздно, тогда как завтра надо было рано вставать. С третьей — понимаю, что дело просто в недостатке опыта, так как на Go я пишу редко и мало (по сути, только этот бот и пара задач на CodinGame).
После этого дописал генерацию CSV-файла уже на PHP (на нём написана интерфейсная часть бота, которая отвечает на запросы пользователя), но и тут посыпались проблемы, и весьма серьёзные: начал падать сам PHP с segmentation fault. Долго не мог понять, почему. Попробовал скопировать тот код, который мне сгенерировал ChatGPT при ответе на вопрос, как отправить файл в Telegram — всё работает. Добавляю с минимальными изменениями в бот — нет. Ошибка оказалась предельно дурацкой: я передавал класс CurlFile в curl_setopt не как элемент хеш массива с параметрами, а вместо него. Но на то, чтобы это найти, ушло часа полтора.
Кстати, тут надо бы изучить получше, что именно приводит к segmentation fault: сама передача этого класса в качестве параметра или ошибочное добавление к нему лишних полей, а также выяснить, осталось ли это в последних версиях, и сделать bug report разработчкам самого PHP.
Потом опять начались проблемы с сохранением в базу данных, но уже не на локали, а на сервере. Опять долго не мог понять, почему, думал, дело в боте. Оказалось, что нет, в кодировке таблицы в MySQL: нужно было поменять её с utf8 на utf8mb4. И только после этого всё почти заработало. Но вылез last minute bug: я решил вынести количество запрашиваемых с сервера байтов из hard-coded в заголовке Range в константу. И тут внезапно полезли проблемы на ровном месте. Как известно, Go — строго типизированный язык, и там присоединить число к строке, написав что-то вроде "Range: 0-"+MAX_LEN нельзя. (Это вам не JavaScript). Я по привычке из Python или PHP написал string(MAX_LEN) и думал, что всё в порядке. Но потом с удивлением обнаружил то, что резко выросло число ошибок со статусом 416, которые я не видел прежде. В том числе и а на моих собственных сайтах, для которых я включил сохранение отладочной информации. И там я увидел, что в заголовке Range вместо 128000 стоит непонятный Unicode-символ. Оказывается, в отличие от скриптовых языков, Go преобразует число в Unicode-символ, а не строковое представление. Стал это исправлять, но было уже 5 часов, голова соображала плохо, и ещё несколько раз допускал глупые ошибки, прежде чем сделал всё как надо.
В общем, день закончился с очень противоречивыми впечатлениями: с одной стороны, доволен, что всё же сделал задуманное. С другой — злостью на себя, что провозился так долго и не поиграл в The Council, и вообще лёг спать слишком поздно, тогда как завтра надо было рано вставать. С третьей — понимаю, что дело просто в недостатке опыта, так как на Go я пишу редко и мало (по сути, только этот бот и пара задач на CodinGame).