BeamMP-Server
BeamMP-Server copied to clipboard
[Bug] Reloading plugin creates duplicate event timers
OS (windows, linux, ...): windows BeamMP-Server Version: master
Describe the bug
Plugin auto-reloading on file changes does not clear timers created with CreateEventTimer
causing duplicate timers to be created every time the plugin reloads. This also causes a crash if the event handler function changes name when the plugin reloads.
To Reproduce Steps to reproduce the behavior:
- Create a timer using
CreateEventTimer
- Trigger a plugin reload by saving a file
- The event function will be called twice per-period due to duplicate event timers
Expected behavior Reloading plugins clears existing event timers so they will be recreated cleanly when the plugin restarts
Logs
[26/11/23 12:30:51] main.cpp:196 [INFO] ALL SYSTEMS STARTED SUCCESSFULLY, EVERYTHING IS OKAY
[26/11/23 12:30:52] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:30:54] LuaAPI.cpp:105 [LUA] Hello there
> status
BeamMP-Server Status:
Total Players: 0
Syncing Players: 0
Synced Players: 0
Connected Players: 0
Guests: 0
Cars: 0
Uptime: 10201ms (~0h)
Lua:
Queued results to check: 0
States: 2
Event timers: 1
Event handlers: 1
Subsystems:
Good/Starting/Bad: 11/0/0
Shutting down/Shut down: 0/0
Good: [ Main, Server, Heartbeat, LuaEngine, Config, PPSMonitor, ResourceManager, UpdateCheck, PluginMonitor, TCPNetwork, UDPNetwork ]
Starting: [ ]
Bad: [ ]
Shutting down: [ ]
Shut down: [ ]
[26/11/23 12:30:56] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:30:58] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:31:00] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:31:01] TPluginMonitor.cpp:41 [INFO] File "Resources\Server\TimerTest\main.lua" changed, reloading
[26/11/23 12:31:02] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:31:03] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:31:04] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:31:05] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:31:06] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:31:07] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:31:07] TPluginMonitor.cpp:41 [INFO] File "Resources\Server\TimerTest\main.lua" changed, reloading
[26/11/23 12:31:08] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:31:09] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:31:09] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:31:10] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:31:11] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:31:11] LuaAPI.cpp:105 [LUA] Hello there
[26/11/23 12:31:12] LuaAPI.cpp:105 [LUA] Hello there
> status
BeamMP-Server Status:
Total Players: 0
Syncing Players: 0
Synced Players: 0
Connected Players: 0
Guests: 0
Cars: 0
Uptime: 27491ms (~0h)
Lua:
Queued results to check: 0
States: 2
Event timers: 3
Event handlers: 1
Subsystems:
Good/Starting/Bad: 11/0/0
Shutting down/Shut down: 0/0
Good: [ Main, Server, Heartbeat, LuaEngine, Config, PPSMonitor, ResourceManager, UpdateCheck, PluginMonitor, TCPNetwork, UDPNetwork ]
Starting: [ ]
Bad: [ ]
Shutting down: [ ]
Shut down: [ ]
Additional Context Lua file used to reproduce the issue:
function SayHello()
print("Hello there")
end
MP.RegisterEvent("TestTimer", "SayHello")
MP.CreateEventTimer("TestTimer", 2000)
The way this currently is worked around is by always cancelling your event timers before starting them, much like unsubscribing event handlers in other languages before subscribing. Cancelling a nonexistent event timer is a no-op.
So, dirty fix:
function SayHello()
print("Hello there")
end
MP.RegisterEvent("TestTimer", "SayHello")
+ MP.CancelEventTimer("TestTimer")
MP.CreateEventTimer("TestTimer", 2000)
Fixing this would require the following changes to be made to the lua/plugin engine:
- [ ] Keep track of which event handler and event timer comes from which file (currently they're just lua chunks I'm pretty sure)
- [ ] Cancel event timers that are started by a specific file when that file is reloaded
You could also potentially add an event for onBeforeReload or something, but nobody would end up using that IMO.