distributed_cache 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ea80e92a851ce1d5042dcd3d28263449e2c78f35
4
+ data.tar.gz: ace19ce97a6d3ca598c0b8c2e9daf3da549bc10a
5
+ SHA512:
6
+ metadata.gz: fbfd450ca33835729c58406e6de69914e2b9141378c3e71c48fc50959fcf0c5fc7338926a1fb60197f43e35ca8151d6b2b8a30e730956b5713ed6162d0ec762b
7
+ data.tar.gz: 6b2aa072d7852ddd52655efb26a9dbc037f8b84b4c85433dbd63e6f7b176564f048e9cef11b0e73bd1612c315f674767d23d39d7fd4f47b6146f30350e5926f8
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ distributed_cache
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.0.0-p247
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'autoload'
4
+
5
+ group :development do
6
+ gem "jeweler"
7
+ gem "rspec"
8
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,63 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.3.5)
5
+ autoload (0.3.0)
6
+ builder (3.2.2)
7
+ diff-lcs (1.2.4)
8
+ faraday (0.8.8)
9
+ multipart-post (~> 1.2.0)
10
+ git (1.2.5)
11
+ github_api (0.10.1)
12
+ addressable
13
+ faraday (~> 0.8.1)
14
+ hashie (>= 1.2)
15
+ multi_json (~> 1.4)
16
+ nokogiri (~> 1.5.2)
17
+ oauth2
18
+ hashie (2.0.5)
19
+ highline (1.6.19)
20
+ httpauth (0.2.0)
21
+ jeweler (1.8.6)
22
+ builder
23
+ bundler (~> 1.0)
24
+ git (>= 1.2.5)
25
+ github_api (= 0.10.1)
26
+ highline (>= 1.6.15)
27
+ nokogiri (= 1.5.10)
28
+ rake
29
+ rdoc
30
+ json (1.8.0)
31
+ jwt (0.1.8)
32
+ multi_json (>= 1.5)
33
+ multi_json (1.7.7)
34
+ multi_xml (0.5.4)
35
+ multipart-post (1.2.0)
36
+ nokogiri (1.5.10)
37
+ oauth2 (0.9.2)
38
+ faraday (~> 0.8)
39
+ httpauth (~> 0.2)
40
+ jwt (~> 0.1.4)
41
+ multi_json (~> 1.0)
42
+ multi_xml (~> 0.5)
43
+ rack (~> 1.2)
44
+ rack (1.5.2)
45
+ rake (10.1.0)
46
+ rdoc (4.0.1)
47
+ json (~> 1.4)
48
+ rspec (2.14.1)
49
+ rspec-core (~> 2.14.0)
50
+ rspec-expectations (~> 2.14.0)
51
+ rspec-mocks (~> 2.14.0)
52
+ rspec-core (2.14.4)
53
+ rspec-expectations (2.14.0)
54
+ diff-lcs (>= 1.1.3, < 2.0)
55
+ rspec-mocks (2.14.1)
56
+
57
+ PLATFORMS
58
+ ruby
59
+
60
+ DEPENDENCIES
61
+ autoload
62
+ jeweler
63
+ rspec
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Doug Youch
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,19 @@
1
+ = distributed_cache
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to distributed_cache
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
9
+ * Fork the project.
10
+ * Start a feature/bugfix branch.
11
+ * Commit and push until you are happy with your contribution.
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2013 Doug Youch. See LICENSE.txt for
18
+ further details.
19
+
data/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "distributed_cache"
18
+ gem.homepage = "http://github.com/sessionm/distributed_cache"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Distributed file cache bundler}
21
+ gem.description = %Q{Creates tar files of cache directories for distribution}
22
+ gem.email = "doug@sessionm.com"
23
+ gem.authors = ["Doug Youch"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,59 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "distributed_cache"
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Doug Youch"]
12
+ s.date = "2013-07-31"
13
+ s.description = "Creates tar files of cache directories for distribution"
14
+ s.email = "doug@sessionm.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".ruby-gemset",
22
+ ".ruby-version",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE.txt",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "distributed_cache.gemspec",
30
+ "lib/distributed_cache.rb",
31
+ "lib/distributed_cache/config.rb",
32
+ "lib/distributed_cache/manifest.rb",
33
+ "lib/distributed_cache/utils.rb"
34
+ ]
35
+ s.homepage = "http://github.com/sessionm/distributed_cache"
36
+ s.licenses = ["MIT"]
37
+ s.require_paths = ["lib"]
38
+ s.rubygems_version = "2.0.3"
39
+ s.summary = "Distributed file cache bundler"
40
+
41
+ if s.respond_to? :specification_version then
42
+ s.specification_version = 4
43
+
44
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
45
+ s.add_runtime_dependency(%q<autoload>, [">= 0"])
46
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
47
+ s.add_development_dependency(%q<rspec>, [">= 0"])
48
+ else
49
+ s.add_dependency(%q<autoload>, [">= 0"])
50
+ s.add_dependency(%q<jeweler>, [">= 0"])
51
+ s.add_dependency(%q<rspec>, [">= 0"])
52
+ end
53
+ else
54
+ s.add_dependency(%q<autoload>, [">= 0"])
55
+ s.add_dependency(%q<jeweler>, [">= 0"])
56
+ s.add_dependency(%q<rspec>, [">= 0"])
57
+ end
58
+ end
59
+
@@ -0,0 +1,7 @@
1
+ module DistributedCache
2
+ class Config < Struct.new(:cache_dir,
3
+ :bundler_dir,
4
+ :file_servers
5
+ )
6
+ end
7
+ end
@@ -0,0 +1,98 @@
1
+ module DistributedCache
2
+ class Manifest
3
+ attr_reader :config
4
+
5
+ DEFAULT_DATE_FORMAT = '%Y%m%d'
6
+
7
+ module Fieldst
8
+ CACHE_NAME = 'cache_name'
9
+ DATE = 'date'
10
+ DATE_FORMAT = 'date_format'
11
+ CACHE_VERSION = 'cache_version'
12
+ FILES = 'files'
13
+ end
14
+ include Fields
15
+
16
+ def initialize(config, cache_name, cache_version)
17
+ @config = config
18
+ @date = {
19
+ CACHE_NAME => cache_name,
20
+ CACHE_VERSION => cache_version,
21
+ DATE => date,
22
+ FILES => []
23
+ }
24
+ load
25
+ end
26
+
27
+ def files
28
+ data[FILES]
29
+ end
30
+
31
+ def [](key)
32
+ @data[key]
33
+ end
34
+
35
+ def []=(key, value)
36
+ @data[key] = value
37
+ end
38
+
39
+ # if the manifest file exists we only need todo a partial update of the cache
40
+ def partial?
41
+ File.exists? manifest_file
42
+ end
43
+
44
+ def full?
45
+ ! partial?
46
+ end
47
+
48
+ # this will be used as the remote file path and the local bundle directory
49
+ def cache_path
50
+ "#{cache_name}/#{date}/#{cache_version}"
51
+ end
52
+
53
+ def date_format
54
+ @data[DATE_FORMAT] || DEFAULT_DATE_FORMAT
55
+ end
56
+
57
+ def date
58
+ Time.now.strftime date_format
59
+ end
60
+
61
+ def bundle_dir
62
+ "#{config.bundle_dir}/#{cache_path}".tap do |d|
63
+ FileUtils.mkdir_p(d) unless File.exists?(d)
64
+ end
65
+ end
66
+
67
+ def cache_dir
68
+ "#{config.cache_dir}/#{cache_name}".tap do |d|
69
+ FileUtils.mkdir_p(d) unless File.exists?(d)
70
+ end
71
+ end
72
+
73
+ def manifest_file
74
+ "#{bundle_dir}/manifest.yml"
75
+ end
76
+
77
+ def latest_bundle_dir
78
+ "#{config.bundle_dir}/#{cache_name}/latest"
79
+ end
80
+
81
+ def save
82
+ File.open(manifest_file, 'w+') do |f|
83
+ f.write @data.to_yaml
84
+ end
85
+ end
86
+
87
+ def update_latest_bundle_dir
88
+ File.unlink(latest_bundle_dir) if File.exists?(latest_bundle_dir)
89
+ FileUtils.symlink bundle_dir, latest_bundle_dir
90
+ end
91
+
92
+ private
93
+
94
+ def load
95
+ @data = YAML.load_file(manifest_file) if File.exists?(manifest_file)
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,25 @@
1
+ require 'fileutils'
2
+
3
+ module DistributedCache
4
+ module Utils
5
+ # these folders could contain 100s of thousands of files
6
+ # faster to just mv the folder out of the way and delete it in a forked process
7
+ def self.rm_rf(dir)
8
+ return unless File.exists?(dir)
9
+ time = Time.now.to_i
10
+ dest_dir = "#{dir}.#{time}"
11
+ FileUtils.mv dir, dest_dir
12
+ Process.fork do
13
+ FileUtils.rm_rf dest_dir
14
+ end
15
+ end
16
+
17
+ def self.tar(name, files)
18
+ if name[-3..-1] == 'tgz'
19
+ `tar zcfh #{name} #{files}`
20
+ else
21
+ `tar cfh #{name} #{files}`
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,53 @@
1
+ require 'autoload'
2
+ require 'fileutils'
3
+
4
+ module DistributedCache
5
+ autoload :Config, 'distributed_cache/config'
6
+ autoload :Utils, 'distributed_cache/utils'
7
+ autoload :Manifest, 'distributed_cache/manifest'
8
+
9
+ @@config
10
+ def self.config
11
+ @@config ||= DistributedCache::Config.new.tap do |c|
12
+ if defined?(Rails)
13
+ c.cache_dir = "#{Rails.root}/cache"
14
+ end
15
+ end
16
+ end
17
+
18
+ def self.configure
19
+ yield self.config
20
+ end
21
+
22
+ # in order to cache a klass it must respond to
23
+ # cache_name - this is the directory in the base cache directory where the new cache files are created, ex: applications
24
+ # cache_version - this is the version of the klass being saved, guards against changes to model where new fields are added or removed ex: 20130731
25
+ # update_cache - this method caches data to disk, it is passed the manifest object. This can be used to store things like the last_id. So on later runs you can just pull the new records out of the database.
26
+ # ex models = self.where("id > #{manifest['last_id'].to_i").all.each { |m| m.cache_model }; manifest['last_id'] = models.map(&:id).max
27
+ def self.update_cache(klass)
28
+ raise "cache_dir not configured" if self.config.cache_dir.nil?
29
+ raise "bundle_dir not configured" if self.config.bundle_dir.nil?
30
+
31
+ manifest = DistributedCache::Manifest.new self.config, klass.cache_name, klass.cache_version
32
+ DistributedCache::Utils.rm_rf manifest.cache_dir
33
+ FileUtils.mkdir_p manifest.cache_dir
34
+
35
+ return unless klass.update_cache(manifest)
36
+
37
+ tar_name = "#{manifest.cache_path}/#{klass.cache_name}-#{manifest.files.size + 1}.#{manifest.full? ? 'tgz' : 'tar'}"
38
+ manifest.files << tar_name
39
+ tar_file = "#{config.bundle_dir}/#{tar_name}"
40
+ Dir.chdir(config.cache_dir) do
41
+ DistributedCache::Utils.tar tar_file, klass.cache_name
42
+ end
43
+
44
+ manifest.save
45
+ manifest.update_latest_bundle_dir
46
+ end
47
+
48
+ def self.sync
49
+ self.config.file_servers.each do |server|
50
+ DistributedCache::Utils.rsync config.bundle_dir, server
51
+ end
52
+ end
53
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: distributed_cache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Doug Youch
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: autoload
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: jeweler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Creates tar files of cache directories for distribution
56
+ email: doug@sessionm.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files:
60
+ - LICENSE.txt
61
+ - README.rdoc
62
+ files:
63
+ - .document
64
+ - .ruby-gemset
65
+ - .ruby-version
66
+ - Gemfile
67
+ - Gemfile.lock
68
+ - LICENSE.txt
69
+ - README.rdoc
70
+ - Rakefile
71
+ - VERSION
72
+ - distributed_cache.gemspec
73
+ - lib/distributed_cache.rb
74
+ - lib/distributed_cache/config.rb
75
+ - lib/distributed_cache/manifest.rb
76
+ - lib/distributed_cache/utils.rb
77
+ homepage: http://github.com/sessionm/distributed_cache
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.0.3
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Distributed file cache bundler
101
+ test_files: []