Guest User

Untitled

a guest
Apr 25th, 2018
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.32 KB | None | 0 0
  1. # alternacache.rb
  2.  
  3. # =Notes:
  4. # It is also possible to make the ChecksumCache class a singleton, as there's
  5. # little reason to have more than one of these per-process and this might
  6. # have important benefits if the backend store is a network daemon somewhere.
  7. #
  8. # Ruby's built-in singleton module also takes care of thread safety issues for
  9. # you, whereas this example uses @cache_obj ||= ChecksumCache.new which is
  10. # thread-UNsafe.
  11.  
  12. class Chef
  13. # if you want to cache other things in the future, extract superclass,
  14. # name it Cache and you're done. bam.
  15. class Cache
  16. include Singleton
  17. include Chef::Mixin::ConvertToClassName
  18.  
  19. def initialize
  20. reset!
  21. end
  22.  
  23. def reset!(backend=nil, backend_opts=nil)
  24. backend ||= Chef::Config[:cache_type]
  25. backend_opts ||= Chef::Config[:cache_options]
  26. # 08methodnotmissing can convert CamelCase to snake_case
  27. begin
  28. require "moneta/#{convert_to_snake_case(backend, Moneta)}"
  29. rescue LoadError => e
  30. Chef::Log.fatal "could not find moneta backend #{backend}"
  31. raise e
  32. end
  33.  
  34. backend_class = Moneta.const_get(backend)
  35. @moneta = backend_class.new(backend_opts)
  36. end
  37. end
  38.  
  39. class ChecksumCache < Cache
  40.  
  41. def self.checksum_for_file(*args)
  42. instance.checksum_for_file(*args)
  43. end
  44.  
  45. def checksum_for_file(file)
  46. fstat = File.stat(file)
  47. key = filename_to_keyname(file)
  48. find_checksum(key, fstat) || generate_checksum(key, fstat)
  49. end
  50.  
  51. private
  52.  
  53. def find_checksum(key, fstat)
  54. cached_value = @moneta.fetch(key)
  55. if cached_value && file_unchanged?(cached_value, fstat)
  56. cached_value["checksum"]
  57. else
  58. false
  59. end
  60. end
  61.  
  62. def generate_checksum(file, key, fstat)
  63. digest = Digest::SHA256.new
  64. IO.foreach(file) {|line| digest.update(line) }
  65. checksum = digest.hexdigest
  66. @moneta.store(key, { "mtime" => fstat.mtime.to_f, "checksum" => checksum }
  67. checksum
  68. end
  69.  
  70. def file_unchanged?(cached_value, stat)
  71. cached_value["mtime"] == stat.mtime.to_f
  72. end
  73.  
  74. def filename_to_keyname(filename)
  75. "chef-file#{filename.gsub(/(#{File::SEPARATOR}|\.)/, '-')}"
  76. end
  77.  
  78. end
  79. end
  80.  
  81. class Chef
  82. module Mixin
  83. module Checksum
  84.  
  85. def checksum(file)
  86. ChecksumCache.checksum_for_file(file)
  87. end
  88.  
  89. end
  90. end
  91. end
Add Comment
Please, Sign In to add comment