Atomicity is implemented by not running anything else, which is exactly why a script is useful and exactly why a slow one is an outage.
-- fine: a handful of commands, microseconds
local n = redis.call('INCR', KEYS[1])
if n == 1 then redis.call('EXPIRE', KEYS[1], ARGV[1]) end
return n
-- an outage: an unbounded loop over a key set
local keys = redis.call('KEYS', 'session:*')
for i, k in ipairs(keys) do redis.call('DEL', k) end
-- lua-time-limit does NOT kill it. it starts returning
-- BUSY to other clients, which is arguably worse.
The lua-time-limit behaviour is the part people get wrong: it is a threshold after which other clients receive an error, not a timeout that stops the script. Only SCRIPT KILL stops it, and only if the script has not yet written anything — after a write the only option is SHUTDOWN NOSAVE.