FIX: under concurrent usage booting rails could cause plugin corruption

Previously on boot we were always removing and adding the same pre-generated
files and symlinks.

This change attempts to avoid writing any automatically generated content if
it is exactly what it should be on disk.

This corrects issues where running a rails console can temporarily corrupt
internal state in production.
This commit is contained in:
Sam Saffron 2020-03-04 16:48:06 +11:00
parent 97545ee4a0
commit c457d3bf28
No known key found for this signature in database
GPG Key ID: B9606168D2FFD9F5

View File

@ -543,9 +543,17 @@ class Plugin::Instance
Discourse::Utils.execute_command('mkdir', '-p', target)
target << name.gsub(/\s/, "_")
# TODO a cleaner way of registering and unregistering
Discourse::Utils.execute_command('rm', '-f', target)
Discourse::Utils.execute_command('ln', '-s', public_data, target)
symlink_is_correct = false
begin
symlink_is_correct = File.exists?(target) && File.readlink(target) == public_data
rescue Errno::EINVAL, Errno::ENOENT
end
if !symlink_is_correct
Discourse::Utils.execute_command('rm', '-f', target)
Discourse::Utils.execute_command('ln', '-s', public_data, target)
end
end
ensure_directory(Plugin::Instance.js_path)
@ -558,12 +566,22 @@ class Plugin::Instance
contents << (is_dir ? "depend_on('#{f}')" : "require_asset('#{f}')")
end
File.delete(js_file_path) if js_asset_exists?
if contents.present?
contents.insert(0, "<%")
contents << "%>"
write_asset(js_file_path, contents.join("\n"))
contents = contents.join("\n")
if File.exists?(js_file_path)
current_contents = File.read(js_file_path)
if current_contents != contents
File.write(js_file_path, conten)
end
else
write_asset(js_file_path, contents)
end
else
File.delete(js_file_path) if js_asset_exists?
end
end