417 |
417 |
|
418 |
418 |
reused = with_lock do
|
419 |
419 |
if existing = Attachment
|
420 |
|
.lock
|
421 |
420 |
.where(digest: self.digest, filesize: self.filesize)
|
422 |
421 |
.where('id <> ? and disk_filename <> ?',
|
423 |
422 |
self.id, self.disk_filename)
|
424 |
423 |
.first
|
|
424 |
existing.with_lock do
|
425 |
425 |
|
426 |
|
original_diskfile = self.diskfile
|
427 |
|
existing_diskfile = existing.diskfile
|
|
426 |
original_diskfile = self.diskfile
|
|
427 |
existing_diskfile = existing.diskfile
|
428 |
428 |
|
429 |
|
if File.readable?(original_diskfile) &&
|
430 |
|
File.readable?(existing_diskfile) &&
|
431 |
|
FileUtils.identical?(original_diskfile, existing_diskfile)
|
|
429 |
if File.readable?(original_diskfile) &&
|
|
430 |
File.readable?(existing_diskfile) &&
|
|
431 |
FileUtils.identical?(original_diskfile, existing_diskfile)
|
432 |
432 |
|
433 |
|
self.update_columns disk_directory: existing.disk_directory,
|
434 |
|
disk_filename: existing.disk_filename
|
|
433 |
self.update_columns disk_directory: existing.disk_directory,
|
|
434 |
disk_filename: existing.disk_filename
|
|
435 |
end
|
435 |
436 |
end
|
436 |
437 |
end
|
437 |
438 |
end
|
438 |
439 |
if reused
|
439 |
440 |
File.delete(original_diskfile)
|
440 |
441 |
end
|
|
442 |
rescue ActiveRecord::StatementInvalid, ActiveRecord::RecordNotFound
|
|
443 |
# Catch and ignore lock errors. It is not critical if deduplication does
|
|
444 |
# not happen, therefore we do not retry.
|
|
445 |
# with_lock throws ActiveRecord::RecordNotFound if the record isnt there
|
|
446 |
# anymore, thats why this is caught and ignored as well.
|
441 |
447 |
end
|
442 |
448 |
|
443 |
449 |
|