activejob_backport 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.md +17 -0
  5. data/lib/active_job.rb +39 -0
  6. data/lib/active_job/arguments.rb +81 -0
  7. data/lib/active_job/base.rb +21 -0
  8. data/lib/active_job/callbacks.rb +144 -0
  9. data/lib/active_job/configured_job.rb +16 -0
  10. data/lib/active_job/core.rb +89 -0
  11. data/lib/active_job/enqueuing.rb +75 -0
  12. data/lib/active_job/execution.rb +41 -0
  13. data/lib/active_job/gem_version.rb +15 -0
  14. data/lib/active_job/logging.rb +121 -0
  15. data/lib/active_job/queue_adapter.rb +29 -0
  16. data/lib/active_job/queue_adapters.rb +17 -0
  17. data/lib/active_job/queue_adapters/backburner_adapter.rb +26 -0
  18. data/lib/active_job/queue_adapters/delayed_job_adapter.rb +23 -0
  19. data/lib/active_job/queue_adapters/inline_adapter.rb +15 -0
  20. data/lib/active_job/queue_adapters/qu_adapter.rb +29 -0
  21. data/lib/active_job/queue_adapters/que_adapter.rb +23 -0
  22. data/lib/active_job/queue_adapters/queue_classic_adapter.rb +40 -0
  23. data/lib/active_job/queue_adapters/resque_adapter.rb +41 -0
  24. data/lib/active_job/queue_adapters/sidekiq_adapter.rb +35 -0
  25. data/lib/active_job/queue_adapters/sneakers_adapter.rb +34 -0
  26. data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +25 -0
  27. data/lib/active_job/queue_adapters/test_adapter.rb +37 -0
  28. data/lib/active_job/queue_name.rb +39 -0
  29. data/lib/active_job/railtie.rb +23 -0
  30. data/lib/active_job/test_case.rb +7 -0
  31. data/lib/active_job/test_helper.rb +196 -0
  32. data/lib/active_job/version.rb +8 -0
  33. data/lib/activejob_backport.rb +1 -0
  34. data/lib/global_id.rb +6 -0
  35. data/lib/global_id/global_id.rb +93 -0
  36. data/lib/global_id/identification.rb +13 -0
  37. data/lib/global_id/locator.rb +83 -0
  38. data/lib/rails/generators/job/job_generator.rb +24 -0
  39. data/lib/rails/generators/job/templates/job.rb +9 -0
  40. metadata +124 -0
@@ -0,0 +1,8 @@
1
+ require_relative 'gem_version'
2
+
3
+ module ActiveJob
4
+ # Returns the version of the currently loaded Active Job as a <tt>Gem::Version</tt>
5
+ def self.version
6
+ gem_version
7
+ end
8
+ end
@@ -0,0 +1 @@
1
+ require 'active_job'
data/lib/global_id.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'global_id/global_id'
2
+
3
+ class GlobalID
4
+ autoload :Locator, 'global_id/locator'
5
+ autoload :Identification, 'global_id/identification'
6
+ end
@@ -0,0 +1,93 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext/string/inflections' # For #model_class constantize
3
+ require 'active_support/core_ext/array/access'
4
+ require 'active_support/core_ext/object/try' # For #find
5
+ require 'uri'
6
+
7
+ class GlobalID
8
+ class << self
9
+ attr_reader :app
10
+
11
+ def create(model, options = {})
12
+ app = options.fetch :app, GlobalID.app
13
+ raise ArgumentError, "An app is required to create a GlobalID. Pass the :app option or set the default GlobalID.app." unless app
14
+ new URI("gid://#{app}/#{model.class.name}/#{model.id}"), options
15
+ end
16
+
17
+ def find(gid, options = {})
18
+ parse(gid, options).try(:find, options)
19
+ end
20
+
21
+ def parse(gid, options = {})
22
+ gid.is_a?(self) ? gid : new(gid, options)
23
+ rescue URI::Error
24
+ parse_encoded_gid(gid, options)
25
+ end
26
+
27
+ def app=(app)
28
+ @app = validate_app(app)
29
+ end
30
+
31
+ def validate_app(app)
32
+ URI.parse('gid:///').hostname = app
33
+ rescue URI::InvalidComponentError
34
+ raise ArgumentError, 'Invalid app name. ' \
35
+ 'App names must be valid URI hostnames: alphanumeric and hyphen characters only.'
36
+ end
37
+
38
+ private
39
+ def parse_encoded_gid(gid, options)
40
+ new(Base64.urlsafe_decode64(repad_gid(gid)), options) rescue nil
41
+ end
42
+
43
+ # We removed the base64 padding character = during #to_param, now we're adding it back so decoding will work
44
+ def repad_gid(gid)
45
+ padding_chars = gid.length.modulo(4).zero? ? 0 : (4 - gid.length.modulo(4))
46
+ gid + ('=' * padding_chars)
47
+ end
48
+ end
49
+
50
+ attr_reader :uri, :app, :model_name, :model_id
51
+
52
+ def initialize(gid, options = {})
53
+ extract_uri_components gid
54
+ end
55
+
56
+ def find(options = {})
57
+ Locator.locate self, options
58
+ end
59
+
60
+ def model_class
61
+ model_name.constantize
62
+ end
63
+
64
+ def ==(other)
65
+ other.is_a?(GlobalID) && @uri == other.uri
66
+ end
67
+
68
+ def to_s
69
+ @uri.to_s
70
+ end
71
+
72
+ def to_param
73
+ # remove the = padding character for a prettier param -- it'll be added back in parse_encoded_gid
74
+ Base64.urlsafe_encode64(to_s).sub(/=+$/, '')
75
+ end
76
+
77
+ private
78
+ PATH_REGEXP = %r(\A/([^/]+)/([^/]+)\z)
79
+
80
+ # Pending a URI::GID to handle validation
81
+ def extract_uri_components(gid)
82
+ @uri = gid.is_a?(URI) ? gid : URI.parse(gid)
83
+ raise URI::BadURIError, "Not a gid:// URI scheme: #{@uri.inspect}" unless @uri.scheme == 'gid'
84
+
85
+ if @uri.path =~ PATH_REGEXP
86
+ @app = @uri.host
87
+ @model_name = $1
88
+ @model_id = $2
89
+ else
90
+ raise URI::InvalidURIError, "Expected a URI like gid://app/Person/1234: #{@uri.inspect}"
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,13 @@
1
+ require 'active_support/concern'
2
+
3
+ class GlobalID
4
+ module Identification
5
+ extend ActiveSupport::Concern
6
+
7
+ def to_global_id
8
+ @global_id ||= GlobalID.create(self)
9
+ end
10
+ alias to_gid to_global_id
11
+
12
+ end
13
+ end
@@ -0,0 +1,83 @@
1
+ class GlobalID
2
+ module Locator
3
+ class << self
4
+ # Takes either a GlobalID or a string that can be turned into a GlobalID
5
+ #
6
+ # Options:
7
+ # * <tt>:only</tt> - A class, module or Array of classes and/or modules that are
8
+ # allowed to be located. Passing one or more classes limits instances of returned
9
+ # classes to those classes or their subclasses. Passing one or more modules in limits
10
+ # instances of returned classes to those including that module. If no classes or
11
+ # modules match, +nil+ is returned.
12
+ def locate(gid, options = {})
13
+ if gid = GlobalID.parse(gid)
14
+ locator_for(gid).locate gid if find_allowed?(gid.model_class, options[:only])
15
+ end
16
+ end
17
+
18
+ # Tie a locator to an app.
19
+ # Useful when different apps collaborate and reference each others' Global IDs.
20
+ #
21
+ # The locator can be either a block or a class.
22
+ #
23
+ # Using a block:
24
+ #
25
+ # GlobalID::Locator.use :foo do |gid|
26
+ # FooRemote.const_get(gid.model_name).find(gid.model_id)
27
+ # end
28
+ #
29
+ # Using a class:
30
+ #
31
+ # GlobalID::Locator.use :bar, BarLocator.new
32
+ #
33
+ # class BarLocator
34
+ # def locate(gid)
35
+ # @search_client.search name: gid.model_name, id: gid.model_id
36
+ # end
37
+ # end
38
+ def use(app, locator = nil, &locator_block)
39
+ raise ArgumentError, 'No locator provided. Pass a block or an object that responds to #locate.' unless locator || block_given?
40
+
41
+ GlobalID.validate_app(app)
42
+
43
+ @locators[normalize_app(app)] = locator || BlockLocator.new(locator_block)
44
+ end
45
+
46
+ private
47
+ def locator_for(gid)
48
+ @locators.fetch(normalize_app(gid.app)) { default_locator }
49
+ end
50
+
51
+ def find_allowed?(model_class, only = nil)
52
+ only ? Array(only).any? { |c| model_class <= c } : true
53
+ end
54
+
55
+ def normalize_app(app)
56
+ app.to_s.downcase
57
+ end
58
+ end
59
+
60
+ private
61
+ @locators = {}
62
+
63
+ class ActiveRecordFinder
64
+ def locate(gid)
65
+ gid.model_class.find gid.model_id
66
+ end
67
+ end
68
+
69
+ def self.default_locator
70
+ ActiveRecordFinder.new
71
+ end
72
+
73
+ class BlockLocator
74
+ def initialize(block)
75
+ @locator = block
76
+ end
77
+
78
+ def locate(gid)
79
+ @locator.call(gid)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,24 @@
1
+ require 'rails/generators/named_base'
2
+
3
+ module Rails
4
+ module Generators # :nodoc:
5
+ class JobGenerator < Rails::Generators::NamedBase # :nodoc:
6
+ desc 'This generator creates an active job file at app/jobs'
7
+
8
+ class_option :queue, type: :string, default: 'default', desc: 'The queue name for the generated job'
9
+
10
+ check_class_collision suffix: 'Job'
11
+
12
+ hook_for :test_framework
13
+
14
+ def self.default_generator_root
15
+ File.dirname(__FILE__)
16
+ end
17
+
18
+ def create_job_file
19
+ template 'job.rb', File.join('app/jobs', class_path, "#{file_name}_job.rb")
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ <% module_namespacing do -%>
2
+ class <%= class_name %>Job < ActiveJob::Base
3
+ queue_as :<%= options[:queue] %>
4
+
5
+ def perform(*args)
6
+ # Do something later
7
+ end
8
+ end
9
+ <% end -%>
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activejob_backport
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - David Heinemeier Hansson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 4.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 4.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
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: Declare job classes that can be run by a variety of queueing backends.
56
+ email: david@loudthinking.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - CHANGELOG.md
62
+ - MIT-LICENSE
63
+ - README.md
64
+ - lib/active_job.rb
65
+ - lib/active_job/arguments.rb
66
+ - lib/active_job/base.rb
67
+ - lib/active_job/callbacks.rb
68
+ - lib/active_job/configured_job.rb
69
+ - lib/active_job/core.rb
70
+ - lib/active_job/enqueuing.rb
71
+ - lib/active_job/execution.rb
72
+ - lib/active_job/gem_version.rb
73
+ - lib/active_job/logging.rb
74
+ - lib/active_job/queue_adapter.rb
75
+ - lib/active_job/queue_adapters.rb
76
+ - lib/active_job/queue_adapters/backburner_adapter.rb
77
+ - lib/active_job/queue_adapters/delayed_job_adapter.rb
78
+ - lib/active_job/queue_adapters/inline_adapter.rb
79
+ - lib/active_job/queue_adapters/qu_adapter.rb
80
+ - lib/active_job/queue_adapters/que_adapter.rb
81
+ - lib/active_job/queue_adapters/queue_classic_adapter.rb
82
+ - lib/active_job/queue_adapters/resque_adapter.rb
83
+ - lib/active_job/queue_adapters/sidekiq_adapter.rb
84
+ - lib/active_job/queue_adapters/sneakers_adapter.rb
85
+ - lib/active_job/queue_adapters/sucker_punch_adapter.rb
86
+ - lib/active_job/queue_adapters/test_adapter.rb
87
+ - lib/active_job/queue_name.rb
88
+ - lib/active_job/railtie.rb
89
+ - lib/active_job/test_case.rb
90
+ - lib/active_job/test_helper.rb
91
+ - lib/active_job/version.rb
92
+ - lib/activejob_backport.rb
93
+ - lib/global_id.rb
94
+ - lib/global_id/global_id.rb
95
+ - lib/global_id/identification.rb
96
+ - lib/global_id/locator.rb
97
+ - lib/rails/generators/job/job_generator.rb
98
+ - lib/rails/generators/job/templates/job.rb
99
+ homepage: https://github.com/ankane/activejob_backport
100
+ licenses:
101
+ - MIT
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: 1.9.3
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.2.2
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: Job framework with pluggable queues.
123
+ test_files: []
124
+ has_rdoc: