kiqit 0.0.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/.gitignore +4 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +3 -0
  4. data/README.md +193 -0
  5. data/Rakefile +9 -1
  6. data/init.rb +2 -0
  7. data/kiqit.gemspec +12 -11
  8. data/lib/kiqit/args_parser.rb +56 -0
  9. data/lib/kiqit/config.rb +11 -0
  10. data/lib/kiqit/job_creator.rb +28 -0
  11. data/lib/kiqit/payload_helper.rb +20 -0
  12. data/lib/kiqit/plugins.rb +17 -0
  13. data/lib/kiqit/railtie.rb +5 -0
  14. data/lib/kiqit/version.rb +1 -1
  15. data/lib/kiqit/workers/active_record/lone_worker.rb +19 -0
  16. data/lib/kiqit/workers/active_record/worker.rb +15 -0
  17. data/lib/kiqit/workers/base.rb +21 -0
  18. data/lib/kiqit/workers/objects/lone_worker.rb +16 -0
  19. data/lib/kiqit/workers/objects/worker.rb +13 -0
  20. data/lib/kiqit.rb +30 -2
  21. data/lib/object_perform_later.rb +36 -0
  22. data/lib/resque_mailer_patch.rb +17 -0
  23. data/lib/sidekiq/plugins/later/method.rb +88 -0
  24. data/license +20 -0
  25. data/spec/lib/kiqit/args_parser_spec.rb +96 -0
  26. data/spec/lib/kiqit/config_spec.rb +11 -0
  27. data/spec/lib/kiqit/job_creator_spec.rb +23 -0
  28. data/spec/lib/kiqit/payload_helper_spec.rb +21 -0
  29. data/spec/lib/kiqit/plugins_spec.rb +33 -0
  30. data/spec/lib/kiqit/workers/active_record/worker_spec.rb +5 -0
  31. data/spec/lib/kiqit/workers/objects/worker_spec.rb +74 -0
  32. data/spec/lib/object_perform_later_spec.rb +141 -0
  33. data/spec/lib/perform_later_spec.rb +5 -0
  34. data/spec/lib/sidekiq/plugins/later/method_spec.rb +121 -0
  35. data/spec/spec_helper.rb +35 -0
  36. data/spec/support/database_connection.rb +1 -0
  37. data/spec/support/database_models.rb +30 -0
  38. data/spec/support/db/.blank.sqlite3 +0 -0
  39. data/spec/support/db/test.sqlite3 +0 -0
  40. metadata +180 -110
  41. data/.rvmrc +0 -1
data/.gitignore CHANGED
@@ -1,4 +1,8 @@
1
+ .rvmrc
1
2
  *.gem
2
3
  .bundle
3
4
  Gemfile.lock
4
5
  pkg/*
6
+ .tags
7
+ .tags_sorted_by_file
8
+ coverage/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
data/README.md CHANGED
@@ -0,0 +1,193 @@
1
+ [![Build Status](https://secure.travis-ci.org/KensoDev/kiqit.png)](https://secure.travis-ci.org/KensoDev/kiqit)
2
+
3
+ ## Overview
4
+ Kiqit is a gem meant to work with the [Sidekiq](http://github.com/mperham/sidekiq) queue system. It was adapted from the Perform Later gem.
5
+
6
+ Usually, when working with Sidekiq, you need separate "Worker" classes and you also need to do `Sidekiq.enqueue` whenever you want to add a task to the queue.
7
+
8
+ That can be a real hassle if you are adding Sidekiq to an existing project, it can also add quite a bit of code to your system.
9
+
10
+ `kiqit` fills this need, it offers a suite to handle all of your queuing needs, both for Objects and for ActiveRecord models.
11
+
12
+ ## Why?
13
+ *Why* should you queue something for later?
14
+
15
+ You should queue something whenever the method handles some heavy lifting, some timely actions like API, 3rd party HTTP requests and more.
16
+
17
+ The basic logic is that whatever you don't need to do NOW, you should do later, this will make your site faster and the users will feel it.
18
+
19
+ ## Real life use case
20
+ At [Gogobot](http://gogobot.com) whenever you post a review, there's major score calculation going on. This can sometimes take up to a minute, depending on the user graph.
21
+
22
+ The user should not wait for this on submit, it can be queued into later execution.
23
+
24
+ ## Installation
25
+ gem install kiqit
26
+
27
+ If you are using bundler, simply add
28
+ `gem "kiqit"` to your Gemfile
29
+
30
+
31
+ ## Configuration
32
+ In an initializer, all you need to say is whether you want perform later to be enabled or not, typically, it will be something like this
33
+
34
+ ```ruby
35
+ unless Rails.env.test?
36
+ Kiqit.config.enabled = true # this will default to false if unset
37
+ end
38
+ ```
39
+
40
+ ## Usage
41
+
42
+ ### ActiveRecord
43
+
44
+ `kiqit` comes with a special method you can use on ActiveRecord models.
45
+
46
+
47
+ ```ruby
48
+
49
+ class User < ActiveRecord::Base
50
+ def long_running_method
51
+ # Your code here
52
+ end
53
+ later :long_running_method
54
+
55
+ def long_running_method_2
56
+ # Your code here
57
+ end
58
+ later :long_running_method_2, queue: :some_queue_name
59
+
60
+ def lonely_long_running_method
61
+ # Your code here
62
+ end
63
+ later :lonely_long_running_method, :loner => true, queue: :some_queue_name
64
+
65
+ def delayed_long_running_method
66
+ # Your code here
67
+ end
68
+ later :delayed_long_running_method, :delay => 30, queue: :some_queue_name
69
+ end
70
+
71
+ ```
72
+
73
+ ```ruby
74
+ u = User.find(some_user_id)
75
+ u.long_running_method # Method will be queued into the :generic queue
76
+ u.long_running_method_2 # Method will be queued into :some_queue_name queue
77
+ u.lonely_long_running_method # Method will be queued into the :some_queue_name queue, only a single instance of this method can exist in the queue.
78
+ u.delayed_long_running_method # Method will be queued into :some_queue_name queue only after 30 seconds have passed.
79
+ ```
80
+
81
+ You can of course choose to run the method off the queue, just prepend `now_` to the method name and it will be executed in sync.
82
+
83
+ ```ruby
84
+ u = User.find(some_user_id)
85
+ u.now_long_running_method
86
+ ```
87
+
88
+ ### Objects/Classes
89
+
90
+ If you want class methods to be queued, you will have to use the `kiqit` special method.
91
+
92
+ ```ruby
93
+ class SomeClass
94
+ def self.some_heavy_lifting_method
95
+ # Your code here
96
+ end
97
+
98
+ def self.some_more_heavy_lifting(user_id)
99
+ # Your code here
100
+ end
101
+ end
102
+
103
+ SomeClass.kiqit(:queue_name, :some_heavy_lifting_method)
104
+ SomeClass.kiqit(:queue_name, :some_more_heavy_lifting, user_id)
105
+
106
+
107
+ ```
108
+
109
+ If you want the method to be a loner (only a single instance in the queue), you will need to use the `kiqit!` method.
110
+
111
+ ```ruby
112
+ SomeClass.kiqit!(:queue_name, :some_more_heavy_lifting, user_id)
113
+ ```
114
+
115
+ ## The params parser
116
+ `kiqit` has a special class called `ArgsParser`, this class is in charge of *translating* the args you are passing into params that can actually be serialized to JSON cleanly.
117
+
118
+ Examples:
119
+
120
+ ```ruby
121
+ user = User.find(1)
122
+ Kiqit::ArgsParser.params_to_sidekiq(user) => 'AR:#User:1'
123
+
124
+ hotel = Hotel.find(1)
125
+ Kiqit::ArgsParser.params_to_sidekiq(hotel) => 'AR:#Hotel:1'
126
+
127
+ hash = { name: "something", other: "something else" }
128
+ Kiqit::ArgsParser.params_to_sidekiq(hash)
129
+ => ---
130
+ :name: something
131
+ :other: something else
132
+ # Hashes are translated into YAML
133
+ ```
134
+
135
+ Basically, the `ArgsParser` class allows you to keep passing any args you want to your methods without worrying about whether they serialize cleanly or not.
136
+
137
+ `ArgsParser` also patched `sidekiq-mailer` so you can pass in AR objects to mailers as well.
138
+
139
+ ## The custom finder
140
+ I found the need to add a custom finder to the args parser.
141
+
142
+ ### Why?
143
+ At Gogobot for example, we use slave databases, those sometimes have lag, so when the finder is executed it returns nil, even though the record is actually on the master.
144
+
145
+ So, I added support for custom finders.
146
+
147
+ #### Example:
148
+
149
+ ```ruby
150
+ class CustomFinder
151
+ def self.find(klass, id)
152
+ Octopus.using(:master) {
153
+ klass.where(id: id).first
154
+ } unless klass.where(id: id).first
155
+ end
156
+ end
157
+ ```
158
+
159
+ Then in an initializer
160
+
161
+ ```ruby
162
+ Kiqit::Plugins.add_finder(CustomFinder)
163
+ ```
164
+
165
+ You can also remove the finder in runtime
166
+
167
+ ```ruby
168
+ Kiqit::Plugins.clear_finder!
169
+ ```
170
+
171
+ So, at Gogobot for example, we will fall back to master if the record was not found on the slave DB.
172
+
173
+
174
+ ## Contribute / Bug reports
175
+
176
+ If you have an issue with this gem, please open an issue in the main repo, it will help tons if you could supply a failing spec with that, so I can better track where the bug is coming from, if not, no worries, just report I will do my best to address it as fast and efficient as I can.
177
+
178
+ If you want to contribute (awesome), open a feature branch, base it on master.
179
+
180
+ Be as descriptive as you can in the pull request description, just to be clear what problem you are solving or what feature are you adding.
181
+
182
+ ## Authors
183
+
184
+ Avi Tzurel ([@kensodev](http://twitter.com/kensodev)) http://www.kensodev.com
185
+ Tom Caspy
186
+
187
+ ## Contributors
188
+
189
+ * Felipe Lima ([@felipecsl](http://twitter.com/felipecsl))
190
+ http://blog.felipel.com/
191
+
192
+ Felipe did awesome work on making sure `kiqit` can work with any args and any number of args passed into the methods.
193
+ Felipe now has commit rights to the repo.
data/Rakefile CHANGED
@@ -1 +1,9 @@
1
- require "bundler/gem_tasks"
1
+ require 'rspec/core/rake_task'
2
+
3
+ desc 'Default: run specs.'
4
+ task :default => :spec
5
+
6
+ desc "Run specs"
7
+ RSpec::Core::RakeTask.new do |t|
8
+
9
+ end
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ # init
2
+ require 'kiqit'
data/kiqit.gemspec CHANGED
@@ -5,11 +5,11 @@ require "kiqit/version"
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "kiqit"
7
7
  s.version = Kiqit::VERSION
8
- s.authors = ["Avi Tzurel"]
9
- s.email = ["avi@kensodev.com"]
10
- s.homepage = "http://www.kensodev.com"
11
- s.summary = %q{your SideKiq helper}
12
- s.description = %q{Kiqit is a set of helpers to use with the SideKiq gem, like an async method and more}
8
+ s.authors = ["Avi Tzurel", "Tom Caspy"]
9
+ s.email = ["avi@kensodev.com", "tom@kensodev.com"]
10
+ s.homepage = "http://www.github.com/kensodev/kiqit"
11
+ s.summary = %q{Queue any method in any class or instance with no need for additional Worker class and no extra code}
12
+ s.description = %q{Queue any method in any class or instance with no need for additional Worker class and no extra code}
13
13
 
14
14
  s.rubyforge_project = "kiqit"
15
15
 
@@ -18,11 +18,12 @@ Gem::Specification.new do |s|
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
20
 
21
- s.add_development_dependency 'rails', '~> 3.0'
21
+ s.add_dependency 'sidekiq'
22
+ s.add_dependency 'activerecord'
22
23
 
23
- s.add_development_dependency 'sidekiq', '~> 2.2.0'
24
- s.add_development_dependency 'rspec'
24
+ s.add_development_dependency 'rake'
25
25
  s.add_development_dependency 'rspec-rails'
26
- s.add_development_dependency 'simplecov'
27
- s.add_development_dependency 'redis', '~> 2.2.0'
28
- end
26
+ s.add_development_dependency 'rspec'
27
+ s.add_development_dependency 'sqlite3'
28
+ s.add_development_dependency 'fakeredis'
29
+ end
@@ -0,0 +1,56 @@
1
+ require 'json'
2
+
3
+ module Kiqit
4
+ class ArgsParser
5
+ # inspired by DelayedJob
6
+ CLASS_STRING_FORMAT = /^CLASS\:([A-Z][\w\:]+)$/
7
+ AR_STRING_FORMAT = /^AR\:([A-Z][\w\:]+)\:(\d+)$/
8
+ YAML_STRING_FORMAT = /\A---/
9
+
10
+ def self.args_to_sidekiq(args)
11
+ return nil unless args
12
+ return arg_to_sidekiq(args) unless args.is_a?(Array)
13
+ return args.map { |o| arg_to_sidekiq o }
14
+ end
15
+
16
+ def self.args_from_sidekiq(args)
17
+ args = args.map { |o|
18
+ if o
19
+ o = args_from_sidekiq(o) if o.is_a?(Array)
20
+ case o
21
+ when CLASS_STRING_FORMAT
22
+ $1.constantize
23
+ when AR_STRING_FORMAT
24
+ runner_class = $1.constantize
25
+ id = $2
26
+
27
+ if Kiqit::Plugins.finder_class
28
+ Kiqit::Plugins.finder_class.find(runner_class, id)
29
+ else
30
+ runner_class.where(id: id).first
31
+ end
32
+ when YAML_STRING_FORMAT
33
+ YAML.load(o)
34
+ else
35
+ o
36
+ end
37
+ end
38
+ } if args
39
+ end
40
+
41
+ private
42
+
43
+ def self.arg_to_sidekiq(arg)
44
+ case arg
45
+ when ActiveRecord::Base
46
+ "AR:#{arg.class.name}:#{arg.id}"
47
+ when Class, Module
48
+ "CLASS:#{arg.name}"
49
+ when Hash
50
+ arg.to_yaml
51
+ else
52
+ arg
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,11 @@
1
+ module Kiqit
2
+ class Config
3
+ def self.enabled=(value)
4
+ @enabled = value
5
+ end
6
+
7
+ def self.enabled?
8
+ !!@enabled
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ module Kiqit
2
+ class JobCreator
3
+
4
+ attr_reader :queue, :worker, :klass_name, :id, :method
5
+ attr_accessor :args
6
+
7
+ def initialize(queue, worker, klass_name, id, method, *args)
8
+ @queue = queue
9
+ @worker = worker
10
+ @klass_name = klass_name
11
+ @id = id
12
+ @method = method
13
+ @args = args
14
+ end
15
+
16
+ def enqueue(delay=nil)
17
+ params = {}
18
+ if delay
19
+ delay = delay.is_a?(Hash) ? delay[:delay] : delay
20
+ params["at"] = (Time.now + delay).to_i
21
+ end
22
+
23
+ params.merge!({"queue" => queue, "class" => worker, "args" => [klass_name, id, method, *args]})
24
+
25
+ Sidekiq::Client.push(params)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ module Kiqit
2
+ class PayloadHelper
3
+ # Public: Get Digest for the loner key.
4
+ #
5
+ # klass - Class name.
6
+ # method - Method name.
7
+ # Args - Args to send on the method
8
+ #
9
+ # Examples =>
10
+ # PayloadHelper.get_digest("SomeClass", "some_method", "arg1", "arg2")
11
+ #
12
+ def self.get_digest(klass, method, *args)
13
+ args = args.flatten
14
+ payload = { :class => klass, :method => method.to_s, :args => args }.to_s
15
+ digest = Digest::MD5.hexdigest("#{payload}")
16
+
17
+ "loner:#{digest}"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module Kiqit
2
+ class Plugins
3
+ def self.finder_class
4
+ @@finder_class ||= nil
5
+ end
6
+
7
+ def self.add_finder(klass)
8
+ if klass.respond_to?(:find)
9
+ @@finder_class = klass
10
+ end
11
+ end
12
+
13
+ def self.clear_finder!
14
+ @@finder_class = nil
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ module Kiqit
2
+ class Railtie < ::Rails::Railtie
3
+ config.perf_later = Kiqit::Config
4
+ end
5
+ end
data/lib/kiqit/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Kiqit
2
- VERSION = "0.0.1"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -0,0 +1,19 @@
1
+ module Kiqit
2
+ module Workers
3
+ module ActiveRecord
4
+ class LoneWorker < Kiqit::Workers::Base
5
+ def perform(klass, id, method, *args)
6
+ # Remove the loner flag from redis
7
+ digest = Kiqit::PayloadHelper.get_digest(klass, method, args)
8
+ Sidekiq.redis.del(digest)
9
+
10
+ args = Kiqit::ArgsParser.args_from_sidekiq(args)
11
+ runner_klass = klass.constantize
12
+ record = runner_klass.find(id)
13
+
14
+ perform_job(record, method, args)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ module Kiqit
2
+ module Workers
3
+ module ActiveRecord
4
+ class Worker < Kiqit::Workers::Base
5
+ def perform(klass, id, method, *args)
6
+ args = Kiqit::ArgsParser.args_from_sidekiq(args)
7
+ runner_klass = klass.constantize
8
+ record = runner_klass.find(id)
9
+
10
+ perform_job(record, method, args)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ module Kiqit
2
+ module Workers
3
+ class Base
4
+
5
+ include Sidekiq::Worker
6
+
7
+ protected
8
+ def perform_job(object, method, arguments)
9
+ unless arguments.empty?
10
+ if arguments.size == 1
11
+ object.send(method, arguments.first)
12
+ else
13
+ object.send(method, *arguments)
14
+ end
15
+ else
16
+ object.send(method)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ module Kiqit
2
+ module Workers
3
+ module Objects
4
+ class LoneWorker < Kiqit::Workers::Base
5
+ def perform(klass_name, method, *args)
6
+ digest = Kiqit::PayloadHelper.get_digest(klass_name, method, args)
7
+ Sidekiq.redis.del(digest)
8
+
9
+ arguments = Kiqit::ArgsParser.args_from_sidekiq(args)
10
+
11
+ perform_job(klass_name.constantize, method, arguments)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ module Kiqit
2
+ module Workers
3
+ module Objects
4
+ class Worker < Kiqit::Workers::Base
5
+ def perform(klass_name, method, *args)
6
+ arguments = Kiqit::ArgsParser.args_from_sidekiq(args)
7
+
8
+ perform_job(klass_name.constantize, method, arguments)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
data/lib/kiqit.rb CHANGED
@@ -1,5 +1,33 @@
1
- require "kiqit/version"
1
+ require 'sidekiq'
2
+ require 'active_support/dependencies'
3
+ require 'kiqit/version'
4
+ require 'kiqit/config'
5
+ require 'kiqit/payload_helper'
6
+ require 'kiqit/args_parser'
7
+ require 'kiqit/plugins'
8
+ require 'kiqit/job_creator'
9
+ require 'active_record'
10
+ require 'object_perform_later'
11
+ require 'kiqit/workers/base'
12
+ require 'kiqit/workers/active_record/worker'
13
+ require 'kiqit/workers/active_record/lone_worker'
14
+ require 'kiqit/workers/objects/worker'
15
+ require 'kiqit/workers/objects/lone_worker'
2
16
 
3
17
  module Kiqit
4
- # Your code goes here...
18
+ def self.config
19
+ Kiqit::Config
20
+ end
21
+ end
22
+
23
+ module Sidekiq
24
+ module Plugins
25
+ module Later
26
+ autoload :Method, 'sidekiq/plugins/later/method'
27
+ end
28
+ end
29
+ end
30
+
31
+ ActiveSupport.on_load(:active_record) do
32
+ include Sidekiq::Plugins::Later::Method
5
33
  end
@@ -0,0 +1,36 @@
1
+ module ObjectKiqit
2
+ def kiqit(queue, method, *args)
3
+ return perform_now(method, args) unless Kiqit.config.enabled?
4
+
5
+ worker = Kiqit::Workers::Objects::Worker
6
+ kiqit_enqueue(worker, queue, method, args)
7
+ end
8
+
9
+ def kiqit!(queue, method, *args)
10
+ return perform_now(method, args) unless Kiqit.config.enabled?
11
+
12
+ return "EXISTS!" if loner_exists(method, args)
13
+
14
+ worker = Kiqit::Workers::Objects::LoneWorker
15
+ kiqit_enqueue(worker, queue, method, args)
16
+ end
17
+
18
+ private
19
+ def loner_exists(method, *args)
20
+ digest = Kiqit::PayloadHelper.get_digest(self.name, method, args)
21
+
22
+ !Sidekiq.redis{|i| i.setnx(digest, 'EXISTS')}
23
+ end
24
+
25
+ def kiqit_enqueue(worker, queue, method, args)
26
+ args = Kiqit::ArgsParser.args_to_sidekiq(args)
27
+ params = {"queue" => queue, "class" => worker, "args" => [self.name, method, *args]}
28
+ Sidekiq::Client.push(params)
29
+ end
30
+
31
+ def perform_now(method, args)
32
+ args.size == 1 ? send(method, args.first) : send(method, *args)
33
+ end
34
+ end
35
+
36
+ Object.send(:include, ObjectKiqit)
@@ -0,0 +1,17 @@
1
+ module Sidekiq
2
+ module Mailer
3
+ module ClassMethods
4
+ def perform(action, *args)
5
+ args = Kiqit::ArgsParser.args_from_sidekiq(args)
6
+ self.send(:new, action, *args).message.deliver
7
+ end
8
+ end
9
+
10
+ class MessageDecoy
11
+ def deliver
12
+ args = Kiqit::ArgsParser.args_to_sidekiq(@args)
13
+ sidekiq.enqueue(@mailer_class, @method_name, *args)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,88 @@
1
+ module Sidekiq::Plugins::Later::Method
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+ def later(method_name, opts={})
6
+ alias_method "now_#{method_name}", method_name
7
+ return unless Kiqit.config.enabled?
8
+
9
+ define_method "#{method_name}" do |*args|
10
+ loner = opts.fetch(:loner, false)
11
+ queue = opts.fetch(:queue, :generic)
12
+ delay = opts.fetch(:delay, false)
13
+ klass = Kiqit::Workers::ActiveRecord::Worker
14
+ klass = Kiqit::Workers::ActiveRecord::LoneWorker if loner
15
+ args = Kiqit::ArgsParser.args_to_sidekiq(args)
16
+ digest = Kiqit::PayloadHelper.get_digest(klass, method_name, args)
17
+
18
+ if loner
19
+ return "AR EXISTS!" if Sidekiq.redis{|i| i.get(digest).present?}
20
+ Sidekiq.redis{|i| i.set(digest, 'EXISTS')}
21
+ end
22
+
23
+ job = Kiqit::JobCreator.new(queue, klass, send(:class).name, send(:id), "now_#{method_name}", *args)
24
+ job.enqueue(delay)
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ def kiqit(queue, method, *args)
31
+ return perform_now(method, args) if plugin_disabled?
32
+
33
+ worker = Kiqit::Workers::ActiveRecord::Worker
34
+ job = Kiqit::JobCreator.new(queue, worker, self.class.name, self.id, method, *args)
35
+ enqueue_in_sidekiq_or_send(job)
36
+ end
37
+
38
+ def kiqit!(queue, method, *args)
39
+ return perform_now(method, args) if plugin_disabled?
40
+ return "AR EXISTS!" if loner_exists(method, args)
41
+
42
+ worker = Kiqit::Workers::ActiveRecord::LoneWorker
43
+ job = Kiqit::JobCreator.new(queue, worker, self.class.name, self.id, method, *args)
44
+ enqueue_in_sidekiq_or_send(job)
45
+ end
46
+
47
+ def kiqit_in(delay, queue, method, *args)
48
+ return perform_now(method, args) if plugin_disabled?
49
+
50
+ worker = Kiqit::Workers::ActiveRecord::Worker
51
+ job = Kiqit::JobCreator.new(queue, worker, self.class.name, self.id, method, *args)
52
+ enqueue_in_sidekiq_or_send(job, delay)
53
+ end
54
+
55
+ def kiqit_in!(delay, queue, method, *args)
56
+ return perform_now(method, args) if plugin_disabled?
57
+
58
+ worker = Kiqit::Workers::ActiveRecord::LoneWorker
59
+ job = Kiqit::JobCreator.new(queue, worker, self.class.name, self.id, method, *args)
60
+ enqueue_in_sidekiq_or_send(job, delay)
61
+ end
62
+
63
+
64
+
65
+ private
66
+ def loner_exists(method, args)
67
+ args = Kiqit::ArgsParser.args_to_sidekiq(args)
68
+ digest = Kiqit::PayloadHelper.get_digest(self.class.name, method, args)
69
+
70
+ return true unless Sidekiq.redis{ |i| i.get(digest).blank?}
71
+ Sidekiq.redis{|i| i.set(digest, 'EXISTS')}
72
+
73
+ return false
74
+ end
75
+
76
+ def enqueue_in_sidekiq_or_send(job, delay=nil)
77
+ job.args = Kiqit::ArgsParser.args_to_sidekiq(job.args)
78
+ job.enqueue(delay)
79
+ end
80
+
81
+ def plugin_disabled?
82
+ !Kiqit.config.enabled?
83
+ end
84
+
85
+ def perform_now(method, args)
86
+ return self.send(method, *args)
87
+ end
88
+ end