Project

General

Profile

Patch #25590 » 0001-prevent-deadlocks-by-only-locking-the-exact-records-.patch

Jens Krämer, 2017-04-12 03:51

View differences:

app/models/attachment.rb
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

  
    (1-1/1)