Skip to content

Commit e965ec4

Browse files
committed
ConfigHandler: also use global mutex for reading config files
This is necessary for preventing files from being read while they are being written or about to be written by another config handler (which could result in parsing errors, data loss and locking issues)
1 parent e738186 commit e965ec4

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

modules/DependencyControl/ConfigHandler.moon

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,34 +114,48 @@ Reload your automation scripts to generate a new configuration file.]]
114114
@file = nil
115115
return true
116116

117-
readFile: (file = @file) =>
117+
readFile: (file = @file, useLock = true, waitLockTime) =>
118+
if useLock
119+
time, err = @getLock waitLockTime
120+
unless time
121+
-- handle\close!
122+
return false, errors.failedLock\format "reading", err
123+
118124
mode, file = fileOps.attributes file, "mode"
119125
if mode == nil
126+
@releaseLock! if useLock
120127
return false, file
121128
elseif not mode
129+
@releaseLock! if useLock
130+
@logger\trace traceMsgs.fileNotFound, @file
122131
return nil
123132

124133
handle, err = io.open file, "r"
125134
unless handle
135+
@releaseLock! if useLock
126136
return false, err
127137

128138
data = handle\read "*a"
129139
success, result = pcall json.decode, data
130140
unless success
141+
handle\close!
131142
-- JSON parse error usually points to a corrupted config file
132143
-- Rename the broken file to allow generating a new one
133144
-- so the user can continue his work
134-
handle\close!
135145
@logger\trace errors.jsonDecode, result
136146
backup = @file .. ".corrupted"
137147
fileOps.copy @file, backup
138148
fileOps.remove @file, false, true
149+
150+
@releaseLock! if useLock
139151
return false, errors.configCorrupted\format backup
140152

153+
handle\close!
154+
@releaseLock! if useLock
155+
141156
if "table" != type result
142157
return false, errors.jsonRoot\format type result
143158

144-
handle\close!
145159
return result
146160

147161
load: =>
@@ -190,7 +204,7 @@ Reload your automation scripts to generate a new configuration file.]]
190204
@userConfig = nil
191205
return @write concertWrite, waitLockTime
192206

193-
write: (concertWrite, waitLockTime = 5000) =>
207+
write: (concertWrite, waitLockTime) =>
194208
return false, errors.noFile unless @file
195209

196210
-- get a lock to avoid concurrent config file access
@@ -199,8 +213,8 @@ Reload your automation scripts to generate a new configuration file.]]
199213
return false, errors.failedLockWrite\format err
200214

201215
-- read the config file
202-
config, err = @readFile!
203-
if err
216+
config, err = @readFile @file, false
217+
if config == false
204218
@releaseLock!
205219
return false, errors.writeFailedRead\format err
206220
config or= {}
@@ -235,7 +249,7 @@ Reload your automation scripts to generate a new configuration file.]]
235249

236250
return true
237251

238-
getLock: (waitTimeout, checkInterval = 100) =>
252+
getLock: (waitTimeout = 5000, checkInterval = 50) =>
239253
return 0 if @hasLock
240254
success = mutex.tryLock!
241255
if success

0 commit comments

Comments
 (0)