far.Timer и сборка мусора

Здесь обсуждается всё, что касается макросов.
Shmuel
Posts: 7246
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 48 times
Been thanked: 636 times

far.Timer и сборка мусора

Post by Shmuel »

Сейчас сделал изменение в поведении far.Timer. Некоторые конструкции с таймером будут работать не так как раньше.
Например: lua:far.Timer(3000, far.Show, 6, 7, 8)
Раньше это выводило меню каждые 3 секунды до конца сессии Фара.
Теперь будет выводить до ближайшей сборки мусора, поскольку возвращаемое значение (хэндл таймера) нигде не хранится.
Это новое поведение аналогично поведению, например, io.open и другим функциям, возвращающим объекты.

Желательно протестировать на ваших макросах.
Меня возможно несколько дней не будет, так что в случае чего, я доверяю Far Group откатить этот коммит.
User avatar
John Doe
Бюрократ
Posts: 14582
Joined: Wed 27 Apr, 2005 20:42
Location: github.com/FarManagerLegacy
Has thanked: 92 times
Been thanked: 514 times
Contact:

LuaFAR — библиотека для создания плагинов на языке Lua

Post by John Doe »

Shmuel wrote: Sun 19 Jan, 2025 20:58 Это новое поведение аналогично поведению, например, io.open и другим функциям, возвращающим объекты.
Мне не кажется что эта аналогия тут подходит: если хэндл файла нигде не хранится, значит операций с этим файлом быть уже никак не может, а значит это действительно мусор.

Таймер же исполняется периодично, и ему не важно существует ли где-то внешняя ссылка на его объект: когда (и если) он станет не нужен, его нужно закрыть явно.
Shmuel wrote: Sun 19 Jan, 2025 20:58 Раньше это выводило меню каждые 3 секунды до конца сессии Фара.

Code: Select all

Macro {
  -- ...
  action=function()
    local timer = far.Timer( --...
    -- ...
  end;
}
Здесь та же ситуация, таймер будет собран сборщиком мусора.
Получается что избежать этого можно только сохранив таймер в _G. И это странно: получается любой относительно долгоживущий таймер придётся куда-то сохранять.

Учитывая, что мусор может собирается грубо говоря в произвольный момент, и я не нахожу ни одного примера, как можно было бы с пользой использовать это нововведение.
https://t.me/FarManager — Telegram чат
Shmuel
Posts: 7246
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 48 times
Been thanked: 636 times

LuaFAR — библиотека для создания плагинов на языке Lua

Post by Shmuel »

John Doe wrote: Sun 19 Jan, 2025 21:24 когда (и если) он станет не нужен, его нужно закрыть явно.
А как вы его закроете явно (не из обработчика), если его хэндл нигде не хранится?
John Doe wrote: Sun 19 Jan, 2025 21:24 Получается что избежать этого можно только сохранив таймер в _G.
Нет, можно и в локальной переменной вне функции action.
John Doe wrote: Sun 19 Jan, 2025 21:24 я не нахожу ни одного примера, как можно было бы с пользой использовать это нововведение.
Прочтите полностью многострочный коммент к коммиту по приведенной ссылке.
User avatar
John Doe
Бюрократ
Posts: 14582
Joined: Wed 27 Apr, 2005 20:42
Location: github.com/FarManagerLegacy
Has thanked: 92 times
Been thanked: 514 times
Contact:

LuaFAR — библиотека для создания плагинов на языке Lua

Post by John Doe »

Shmuel wrote: Sun 19 Jan, 2025 21:34 А как вы его закроете явно (не из обработчика), если его хэндл нигде не хранится?
Ответ простой: если логика скрипта требует закрытия таймера "извне", значит я сохраню хендл там, где у меня будет к нему доступ.
Если я этого не делаю, значит мне извне закрывать его не нужно (он закрывается изнутри)
Shmuel wrote: Sun 19 Jan, 2025 21:34 Прочтите полностью многострочный коммент к коммиту по приведенной ссылке.
Reason: reloading macros didn't release timers and their associated code.
Это безусловно важный случай.
Но неужели нельзя разрулить это автоматически?
Хранить все ссылки на все таймеры где-нибудь в Registry, а при перезагрузке очищать.
(это лишь гипотетический пример)
https://t.me/FarManager — Telegram чат
Shmuel
Posts: 7246
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 48 times
Been thanked: 636 times

LuaFAR — библиотека для создания плагинов на языке Lua

Post by Shmuel »

John Doe wrote: Sun 19 Jan, 2025 21:47 Но неужели нельзя разрулить это автоматически?
Хранить все ссылки на все таймеры где-нибудь в Registry, а при перезагрузке очищать.
(это лишь гипотетический пример)
Часто у проблем бывает более одного решения.
То решение, которое я выбрал, оно типа "стандартное" для Lua.
Ваш гипотетический пример больше похож на заплатку.

Давайте подождём несколько дней, возможно будет больше обратной связи, примеров и т.д. Откатить никогда не поздно.
Shmuel
Posts: 7246
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 48 times
Been thanked: 636 times

LuaFAR — библиотека для создания плагинов на языке Lua

Post by Shmuel »

Возникла идея альтернативной реализации:
В реализации far.Timer создавать таблицу-environment для обработчика и помещать в эту таблицу хэндл таймера. Тогда время жизни хэндла будет совпадать с временем жизни обработчика. Это надо будет попробовать (но не знаю, когда получится).
User avatar
John Doe
Бюрократ
Posts: 14582
Joined: Wed 27 Apr, 2005 20:42
Location: github.com/FarManagerLegacy
Has thanked: 92 times
Been thanked: 514 times
Contact:

LuaFAR — библиотека для создания плагинов на языке Lua

Post by John Doe »

Shmuel wrote: Sun 19 Jan, 2025 22:08 Давайте подождём несколько дней, возможно будет больше обратной связи, примеров и т.д. Откатить никогда не поздно.
Давайте подождём, почему нет.

Но вроде всё очевидно:
  • влияние на короткоживущие таймеры не будет вовсе (и например никто не заметит если 1/1000 раз таймер не сработает).
  • "долгоживущие" же согласно вашей инструкции необходимо скорректировать, добавив "внешние" ссылки.
    Если не скорректировать, то при сборке мусора они будут отваливаться. Опять же, если сборка мусора происходит не часто, то за пару дней можно и не заметить.
Shmuel wrote: Sun 19 Jan, 2025 22:08 То решение, которое я выбрал, оно типа "стандартное" для Lua.
"Стандартно" объект, доступа к которому нет, считается мусором, поскольку самостоятельно он не функционирует.
Программисту об этом беспокоиться не надо, поскольку всё очевидно из кода - нет обращений к объекту, значит он уже не нужен.

Всё несколько иначе при использовании ffi: здесь нам приходится задумываться о времени жизни "объектов", поскольку оперируем мы ими на самом низком уровне, в обход стандартных механизмов.
Автоматизировать это никак нельзя: интерпретатор Lua мысли не читает.

Случай с таймером не такой, здесь заранее известно в какой момент объект надо уничтожить, и это легко автоматизировать.
Нет никакой выгоды от того, что это сейчас вдруг возложено на программиста.
Shmuel wrote: Sun 19 Jan, 2025 22:44 Возникла идея альтернативной реализации:
Почему бы и нет.
Но если мой гипотетический вариант тоже рабочий, то не вижу принципиальной разницы.
https://t.me/FarManager — Telegram чат
User avatar
buniak_a_h
Posts: 4565
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 242 times
Been thanked: 674 times
Contact:

LuaFAR — библиотека для создания плагинов на языке Lua

Post by buniak_a_h »

Может быть повлияет следующее соображение (из другой темы):
buniak_a_h wrote: Mon 20 Jan, 2025 05:46 … … …
Т.к. я отлаживал скрипт, то я регулярно делал перезагрузку макросов. А получается, что при перезагрузке (а) имеющийся таймер продолжает работать, и (б) создаётся новый. За день перезагружу макросы раз 50 - вот вам и 50 одновременно работающих таймеров.
Да, какая-то тут засада…
Last edited by buniak_a_h on Mon 20 Jan, 2025 06:02, edited 1 time in total.
Shmuel
Posts: 7246
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 48 times
Been thanked: 636 times

LuaFAR — библиотека для создания плагинов на языке Lua

Post by Shmuel »

buniak_a_h wrote: Mon 20 Jan, 2025 05:47 (а) имеющийся таймер продолжает работать, и (б) создаётся новый
Не только имеющийся таймер продолжает работать, но он продолжает работать со своим старым обработчиком, который в свою очередь может вызывать другие старые (т.е. существовавшие до перезагрузки) функции. Всё, что прямо или косвенно связано с хэндлом таймера, не выгружается. Вплоть до того, что почти весь образ "старого" макрофайла не выгружается из памяти.

Ваш случай и навёл меня на мысль, что эту ситуацию нужно исправлять. Возможно вчерашнее исправление не окончательное, посмотрим.
User avatar
John Doe
Бюрократ
Posts: 14582
Joined: Wed 27 Apr, 2005 20:42
Location: github.com/FarManagerLegacy
Has thanked: 92 times
Been thanked: 514 times
Contact:

LuaFAR — библиотека для создания плагинов на языке Lua

Post by John Doe »

Shmuel wrote: Mon 20 Jan, 2025 08:16 Возможно вчерашнее исправление не окончательное, посмотрим.
Да, не стоит дожидаться тут сборки мусора, лучше закрывать все старые таймеры в момент перезагрузки.
https://t.me/FarManager — Telegram чат
Shmuel
Posts: 7246
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 48 times
Been thanked: 636 times

LuaFAR — библиотека для создания плагинов на языке Lua

Post by Shmuel »

John Doe wrote: Mon 20 Jan, 2025 09:33 Да, не стоит дожидаться тут сборки мусора, лучше закрывать все старые таймеры в момент перезагрузки.
На практике при перезагрузке макросов происходит сборка мусора, но да, лучше явно добавить в LuaMacro вызов collectgarbage("collect").
User avatar
buniak_a_h
Posts: 4565
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 242 times
Been thanked: 674 times
Contact:

LuaFAR — библиотека для создания плагинов на языке Lua

Post by buniak_a_h »

John Doe wrote: Mon 20 Jan, 2025 09:33 … … …, лучше закрывать все старые таймеры в момент перезагрузки.
Ну да, я уж хотел повесить обработку ExitFAR - повесить туда закрытие таймера.
User avatar
SUSim
Posts: 1736
Joined: Thu 18 Feb, 2010 17:32
Has thanked: 15 times
Been thanked: 45 times

LuaFAR — библиотека для создания плагинов на языке Lua

Post by SUSim »

Мне придется переделать несколько макросов:
так как, пользовался лайф-хаком - запуском макроса из тела основного макроса по Таймеру, чтобы он точно отработал после окончания родительского макроса.

НО ЭТО СТАЛО ПОЛЕЗНЫМ ;)
можно избавится от лишнего! где я ленился дебагить... заработало = хорошо...

СБОРЩИК МУСОРА СРАБАТЫВАЕТ В СЕРЕДИНЕ РАБОТЫ ТАЙМЕРА который сам должен был удалиться - получаем сообщение об ошибке - ТАЙМЕРА НЕТ А БЫЛ ВЫЗОВ УДАЛЕНИЯ ЕГО. хорошо то, что фар-луа-макрос остаются в работе, но напрягает сообщение в неопределенный момент.
Last edited by SUSim on Mon 20 Jan, 2025 17:59, edited 3 times in total.
SimSU ··· ·· -- ··· ··-
User avatar
SUSim
Posts: 1736
Joined: Thu 18 Feb, 2010 17:32
Has thanked: 15 times
Been thanked: 45 times

LuaFAR — библиотека для создания плагинов на языке Lua

Post by SUSim »

Хорошо что читал тему, и сотрудникам рекомендовал не обновлять сам FAR...

ЗЫ: кстати, ВРОДЕ БЫ, еще при перезагрузке макросов, не удаляются еще и макросы повешенные на события...
Last edited by SUSim on Mon 20 Jan, 2025 17:55, edited 3 times in total.
SimSU ··· ·· -- ··· ··-
Shmuel
Posts: 7246
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 48 times
Been thanked: 636 times

LuaFAR — библиотека для создания плагинов на языке Lua

Post by Shmuel »

SUSim, я какое-то время не смогу обсуждать вопросы по существу, надеюсь что через несколько дней смогу.
Post Reply

Return to “Обсуждение макросов”