qpush 0.1.8 → 0.1.10

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5b7af474af17142a61d366bd6f9112b2abede127
4
- data.tar.gz: 7ad15b8b50d6a129f5dff7ec7039f554fc7f11d0
3
+ metadata.gz: ca96ec0ea37c952b0dc88b82129fae5f60ab604a
4
+ data.tar.gz: f6d0ef10bf31c71e9a8a67d91830fb007500a8dd
5
5
  SHA512:
6
- metadata.gz: f85e768b6f01d936fe3a156abee7a815d7a5a9965a970c9d62caffed9ca08262b74410fcef22d91c1f98cfb5b69226f8466d37e52cbae8a4c17fdc32ebb40aca
7
- data.tar.gz: 86c720933d37d2bfbd3a9633c07bf5c691e8c85aaceaba3cbe280fd9bc05ec06c63948fdf755a20aa698117897f53d6ea0909acb060a061e60aa7239afb1320a
6
+ metadata.gz: 453061fe039e72dea482d0ba003fab94de6a20ffb18f8076ea0eb68e36fc72c3182018bafb5ee4e2f0c616c9c8cee32be3fa4765103c8b368fe69c269ec0587e
7
+ data.tar.gz: 32bb65924fe5b3189d5f4f7d24d46fc5cda3cd3812458e3f54d5eacc5ccd2fb7cbe147005319468cb1d87565c8fd8eb2d6fd0e06a024444cd44e0ad9eb8417c9
@@ -1,243 +1 @@
1
1
  c
2
- job.valid?
3
- job.setup
4
- job
5
- c
6
- json
7
- c
8
- self.config
9
- config
10
- Server.config
11
- c
12
- Server.config
13
- c
14
- QPush::Server.config
15
- c
16
- QPush::Server.config
17
- c
18
- job.perform
19
- job = Job.new(JSON.parse(json))
20
- json
21
- c
22
- delays.count
23
- delays.any?
24
- delays
25
- @conn
26
- c
27
- valid?
28
- c
29
- configs
30
- c
31
- configs
32
- c
33
- valid?
34
- config
35
- c
36
- valid?
37
- @configs
38
- configs
39
- c
40
- configs ? true : false
41
- configs
42
- c
43
- valid?
44
- quit
45
- job.klass
46
- job.errors
47
- job.valid?
48
- c
49
- jobs
50
- c
51
- request.path_info
52
- c
53
- hash
54
- c
55
- @jobs.compact[@start, @count]
56
- @jobs.compact
57
- @jobs.compact!
58
- @count
59
- @start
60
- @jobs
61
- c
62
- @count
63
- @start
64
- @jobs
65
- c
66
- Delay.call(@job, :delay)
67
- c
68
- Delay.call(@job)
69
- c
70
- @stats.each_key { |key| puts key }
71
- @stats.each_key { |key| @stats[key].to_i }
72
- @stats
73
- c
74
- @stats
75
- c
76
- quit
77
- Perform.call(@job)
78
- c
79
- Perform.call(@job)
80
- c
81
- @job
82
- invalid_job && return unless @job.valid?
83
- c
84
- job
85
- c
86
- @fails = @fails.compact[@start, @count]
87
- @fails
88
- @Fails
89
- @fails.compact!
90
- @fails.compact![@start..@count]
91
- @fails.compact![@start, @count]
92
- @fails.any?
93
- @count
94
- @start
95
- @fails
96
- c
97
- @fails
98
- c
99
- @fails
100
- c
101
- percent
102
- quit
103
- y
104
- q
105
- (100.00 - ((stats[:failed].to_f / stats[:performed].to_f) * 100.00)).round(2)
106
- 100.00 - ((stats[:failed].to_f / stats[:performed].to_f) * 100.00)
107
- stats[:failed].to_f / stats[:performed].to_f
108
- stats[:failed].to_f
109
- stats[:failed].to_i / stats[:performed].to_i
110
- (stats[:failed] / stats[:performed])
111
- stats[:performed]
112
- stats[:failed]
113
- percent
114
- c
115
- conn.lrange("#{QPush.config.perform_namespace}:last_10", 0, 10)
116
- c
117
- json
118
- c
119
- conn.get("#{namespace}:#{s}")
120
- stats
121
- c
122
- nil.to_i
123
- stats
124
- quit
125
- Dir[Dir.pwd + "/lib/qpush/jobs/*.rb"]
126
- Dir[Dir.pwd + "/lib/jobs/*.rb"]
127
- Dir.pwd
128
- File.dirname(__FILE__)
129
- Dir["#{File.dirname(__FILE__)}/qpush/jobs/*.rb"]
130
- Dir[File.join(QPush.config.jobs_path, "*.rb")]
131
- $LOAD_PATH.unshift(QPush.config.jobs_path)
132
- $LOAD_PATH
133
- File.dirname(__FILE__)
134
- Dir[File.dirname(__FILE__) + "#{QPush.config.jobs_path}/*.rb"]
135
- QPush.config.jobs_path
136
- Dir["#{QPush.config.jobs_path}/*.rb"]
137
- quit
138
- puts e
139
- puts s
140
- c
141
- puts e
142
- puts s
143
- s
144
- jobs.compact!
145
- jobs.compact![s, e]
146
- jobs
147
- quit
148
- jobs
149
- c
150
- jobs
151
- quit
152
- job_hash
153
- quit
154
- delayed_jobs
155
- delay_jobs
156
- c
157
- conn.zrange(QPush.config.delay_namespace, 0, -1, with_scores: true)
158
- delayed_jobs
159
- quit
160
- conn.get("#{@namespace}:#{stat}")
161
- "#{@namespace}:#{stat}"
162
- c
163
- name
164
- c
165
- self.name
166
- quit
167
- job
168
- delays.each { |job| PerformJob.call(Job.new(job)) }
169
- cccccccccccc
170
- elcccccccccccccccccccc
171
- delaysdelays.each {|job| PerformJob.call(Job.new(job))}
172
- quit
173
- Server.connection_pool
174
- Qued::QPush.redis
175
- QPush.redis
176
- c
177
- QueueJob.new(job).call
178
- job.valid? && job.queueable?
179
- job.valid?
180
- return false unless job.valid? && job.queueable?
181
- job
182
- quit
183
- @start_at < Time.now.to_i && !@cron.empty?
184
- @start_at > Time.now.to_i && @cron.empty?
185
- @start_at < Time.now.to_i && @cron.empty?
186
- QueueJob.new(self).call
187
- quit
188
- job.valid?
189
- job.save
190
- test
191
- quit
192
- job.save
193
- job
194
- job = Job.new(options)
195
- options
196
- quit
197
- cron?
198
- delay?
199
- queue?
200
- quit
201
- c
202
- job_type.call
203
- quit
204
- job_type.call
205
- quit
206
- performer
207
- performer = retrieve_job_type
208
- quit
209
- self
210
- performer.call
211
- performer
212
- performer = retrieve_job_type
213
- performer.call
214
- performer
215
- retrieve_job_type
216
- performer
217
- c
218
- quit
219
- performer.call
220
- performer
221
- performer = retrieve_job_type
222
- valid?
223
- c
224
- @job.queue?
225
- @job.delay?
226
- @job.cron?
227
- @job
228
- job_success
229
- measure_run_time { @job.run }
230
- @job.run
231
- c
232
- quit
233
- log_success
234
- job_success && log_success
235
- c
236
- @job.run
237
- @job = Job.new(JSON.parse(json))
238
- c
239
- @job = Job.new(JSON.parse(json))
240
- json
241
- quit
242
- json
243
- son
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # QPush
1
+ #<center><img src="https://s21.postimg.org/85ce7g93b/qpush.png" alt="Drawing" width="250"/></center>
2
2
  [![Code Climate](https://codeclimate.com/github/nsweeting/qpush/badges/gpa.svg)](https://codeclimate.com/github/nsweeting/qpush)
3
3
 
4
4
  Fast and simple job queue microservice for Ruby. **Please consider it under development at the moment.**
@@ -77,12 +77,14 @@ At a minimum, we must provide the job with a 'klass'. There are many more option
77
77
 
78
78
  #### Building Jobs
79
79
 
80
- Jobs are simply plain old ruby objects that contain a 'call' method. If you provide a hash for the 'args' of the job, the job will be initialized with them. Below is an example of a simple mailing job utilizing the 'mail' gem.
80
+ Jobs are simply ruby objects that include the QPush::Job module and contain a 'call' method. If you provide a hash for the 'args' of the job, the job will be initialized with them. Below is an example of a simple mailing job utilizing the 'mail' gem.
81
81
 
82
82
  ```ruby
83
83
  require 'mail'
84
84
 
85
85
  class MailJob
86
+ include QPush::Job
87
+
86
88
  def initialize(options = {})
87
89
  @mail = Mail.new(options)
88
90
  end
@@ -1,5 +1,5 @@
1
1
  class FailJob
2
- include QPush::Server::JobRegister
2
+ include QPush::Job
3
3
 
4
4
  def initialize(options)
5
5
  @option = options
@@ -1,6 +1,6 @@
1
1
  class TestJob
2
- include QPush::Server::JobRegister
3
-
2
+ include QPush::Job
3
+
4
4
  def call
5
5
  puts 'Hello from TestJob'
6
6
  end
@@ -1,5 +1,4 @@
1
1
  # External
2
- require 'byebug'
3
2
  require 'securerandom'
4
3
  require 'json'
5
4
  require 'redis'
@@ -3,6 +3,7 @@ module QPush
3
3
  def job(options)
4
4
  job = Client::Job.new(options)
5
5
  job.queue
6
+ job
6
7
  end
7
8
  end
8
9
 
@@ -1,11 +1,42 @@
1
1
  module QPush
2
2
  module Base
3
3
  KEY = 'qpush:v1'.freeze
4
+ SUB_KEYS = [:delay,
5
+ :queue,
6
+ :perform,
7
+ :stats,
8
+ :heart,
9
+ :crons,
10
+ :history,
11
+ :morgue].freeze
4
12
 
5
- class RedisPool
6
- def self.create(pool, url)
7
- ::ConnectionPool.new(size: pool) do
8
- ::Redis.new(url: url)
13
+ module RedisHelper
14
+ def self.included(base)
15
+ base.extend(ClassMethods)
16
+ end
17
+
18
+ module ClassMethods
19
+ def redis
20
+ redis_pool.with do |conn|
21
+ yield conn
22
+ end
23
+ end
24
+
25
+ def redis_pool
26
+ @redis_pool ||= build_pool(config.redis_pool, config.redis_url)
27
+ end
28
+
29
+ def build_pool(pool, url)
30
+ ConnectionPool.new(size: pool) do
31
+ Redis.new(url: url)
32
+ end
33
+ end
34
+
35
+ def build_keys(namespace, priorities)
36
+ name = "#{QPush::Base::KEY}:#{namespace}"
37
+ keys = Hash[QPush::Base::SUB_KEYS.collect { |key| [key, "#{name}:#{key}"] }]
38
+ keys[:perform_list] = (1..priorities).collect { |num| "#{keys[:perform]}:#{num}" }
39
+ keys
9
40
  end
10
41
  end
11
42
  end
@@ -1,7 +1,26 @@
1
1
  # QPush Base
2
2
  require 'qpush/base'
3
3
 
4
- # Qpush Client Base
5
- require 'qpush/client/config'
6
- require 'qpush/client/job'
7
- require 'qpush/client/redis'
4
+ module QPush
5
+ module Client
6
+ include QPush::Base::ConfigHelper
7
+ include QPush::Base::RedisHelper
8
+
9
+ class << self
10
+ def config
11
+ @config ||= Config.new
12
+ end
13
+ end
14
+
15
+ class Config < QPush::Base::Config; end
16
+
17
+ class Job < QPush::Base::Job
18
+ def queue
19
+ Client.redis do |conn|
20
+ conn.hincrby("#{QPush::Base::KEY}:#{@namespace}:stats", 'queued', 1)
21
+ conn.lpush("#{QPush::Base::KEY}:#{@namespace}:queue", to_json)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -2,13 +2,14 @@
2
2
  require 'sequel'
3
3
  require 'object_validator'
4
4
  require 'parse-cron'
5
- require 'forwardable'
5
+ require 'logger'
6
6
 
7
7
  # QPush Base
8
8
  require 'qpush/base'
9
9
 
10
10
  # Qpush Server Base
11
11
  require 'qpush/server/apis'
12
+ require 'qpush/server/worker'
12
13
  require 'qpush/server/config'
13
14
  require 'qpush/server/database'
14
15
  require 'qpush/server/delay'
@@ -21,8 +22,6 @@ require 'qpush/server/logger'
21
22
  require 'qpush/server/manager'
22
23
  require 'qpush/server/perform'
23
24
  require 'qpush/server/queue'
24
- require 'qpush/server/redis'
25
- require 'qpush/server/worker'
26
25
 
27
26
  # QPush Server Apis
28
27
  require 'qpush/server/apis/delay'
@@ -3,15 +3,14 @@ module QPush
3
3
  module Apis
4
4
  class Setup < Base
5
5
  def call
6
- invalid_job && return unless @job.valid?
7
- setup_job
6
+ @job.valid? ? setup_job : invalid_job
8
7
  end
9
8
 
10
9
  private
11
10
 
12
11
  def setup_job
13
- Perform.call(@job) if @job.perform_job?
14
- Delay.call(@job, :delay) if @job.delay_job?
12
+ @job.perform if @job.perform_job?
13
+ @job.delay if @job.delay_job?
15
14
  end
16
15
 
17
16
  def invalid_job
@@ -17,9 +17,7 @@ module QPush
17
17
  end
18
18
 
19
19
  def stat_increment
20
- Server.redis do |c|
21
- c.hincrby(Server.keys[:stats], 'success', 1)
22
- end
20
+ Server.redis { |c| c.hincrby(Server.keys[:stats], 'success', 1) }
23
21
  end
24
22
 
25
23
  def log_success
@@ -1,43 +1,19 @@
1
1
  module QPush
2
2
  module Server
3
3
  include QPush::Base::ConfigHelper
4
+ include QPush::Base::RedisHelper
4
5
 
5
6
  class << self
6
- attr_accessor :worker, :keys
7
+ attr_accessor :keys
7
8
 
8
9
  def config
9
10
  @config ||= Config.new
10
11
  end
11
-
12
- def build_worker
13
- worker = WorkerConfig.new
14
- yield worker
15
- worker
16
- end
17
- end
18
-
19
- class WorkerConfig
20
- DEFAULTS = {
21
- namespace: 'default',
22
- priorities: 5,
23
- queue_threads: 2,
24
- perform_threads: 2,
25
- delay_threads: 1 }.freeze
26
-
27
- attr_accessor :perform_threads, :queue_threads, :delay_threads,
28
- :namespace, :priorities
29
-
30
- def initialize(options = {})
31
- options = DEFAULTS.merge(options)
32
- options.each { |key, value| send("#{key}=", value) }
33
- end
34
-
35
- def for_keys
36
- { namespace: @namespace, priorities: @priorities }
37
- end
38
12
  end
39
13
 
40
14
  class Config < QPush::Base::Config
15
+ include ObjectValidator::Validate
16
+
41
17
  SERVER_DEFAULTS = {
42
18
  database_url: ENV['DATABASE_URL'],
43
19
  database_pool: 10,
@@ -50,6 +26,24 @@ module QPush
50
26
  super
51
27
  SERVER_DEFAULTS.each { |key, value| send("#{key}=", value) }
52
28
  end
29
+
30
+ def validate!
31
+ return if valid?
32
+ fail ServerError, errors.full_messages.join(' ')
33
+ end
34
+ end
35
+
36
+ class ConfigValidator
37
+ include ObjectValidator::Validator
38
+
39
+ validates :redis, with: { proc: proc { Server.redis { |c| c.ping && c.quit } },
40
+ msg: 'could not be connected with' }
41
+ validates :workers, with: { proc: proc { |c| c.workers.is_a?(Array) && c.workers.count > 0 },
42
+ msg: 'is not a valid Array of WorkerConfigs' }
43
+ validates :configs, with: { proc: proc { |c| c.workers.all? { |w| w.is_a?(WorkerConfig) } },
44
+ msg: 'are not valid WorkerConfig objects' }
45
+ validates :jobs_path, with: { proc: proc { |c| Dir.exist?(Dir.pwd + c.jobs_path) },
46
+ msg: 'is not a valid directory' }
53
47
  end
54
48
  end
55
49
  end
@@ -1,14 +1,22 @@
1
1
  module QPush
2
+ module Job
3
+ class << self
4
+ def included(base)
5
+ _register_job(base)
6
+ Server.log.info("* Job loaded: #{base.name}")
7
+ end
8
+
9
+ def _register_job(base)
10
+ Server.jobs << base.name
11
+ Server.redis { |c| c.sadd("#{QPush::Base::KEY}:jobs", base.name) }
12
+ end
13
+ end
14
+ end
15
+
2
16
  module Server
3
- module JobRegister
4
- class << self
5
- def included(base)
6
- _register_job(base)
7
- end
8
-
9
- def _register_job(base)
10
- Server.redis { |c| c.sadd("#{QPush::Base::KEY}:jobs", base.name) }
11
- end
17
+ class << self
18
+ def jobs
19
+ @jobs ||= []
12
20
  end
13
21
  end
14
22
 
@@ -69,7 +77,7 @@ module QPush
69
77
  include ObjectValidator::Validator
70
78
 
71
79
  validates :klass,
72
- with: { proc: proc { |j| Object.const_defined?(j.klass) },
80
+ with: { proc: proc { |j| Server.jobs.include?(j.klass) },
73
81
  msg: 'has not been defined' }
74
82
  validates :cron,
75
83
  with: { proc: proc { |j| j.cron.empty? ? true : CronParser.new(j.cron) },
@@ -7,11 +7,12 @@ module QPush
7
7
  @argv = argv
8
8
  end
9
9
 
10
- # Parses commmand line options and starts the Manager object
10
+ # Provides the main entrypoint for starting a QPush server.
11
11
  #
12
12
  def start
13
13
  start_message
14
14
  setup_options
15
+ validate!
15
16
  setup_jobs
16
17
  boot_manager
17
18
  end
@@ -39,12 +40,21 @@ module QPush
39
40
  parser.parse!(@argv)
40
41
  end
41
42
 
43
+ # Validates our server and worker configuration.
44
+ #
45
+ def validate!
46
+ Server.config.validate!
47
+ Server.config.workers.each { |w| w.validate! }
48
+ end
49
+
42
50
  # Requires all base jobs as well as user jobs.
43
51
  #
44
52
  def setup_jobs
45
53
  JobLoader.call
46
54
  end
47
55
 
56
+ # Boots our manager
57
+ #
48
58
  def boot_manager
49
59
  manager = Manager.new(Server.config.workers)
50
60
  manager.start
@@ -1,5 +1,3 @@
1
- require 'logger'
2
-
3
1
  module QPush
4
2
  module Server
5
3
  class << self
@@ -4,8 +4,6 @@ module QPush
4
4
  # of them to start and shutdown.
5
5
  #
6
6
  class Manager
7
- include ObjectValidator::Validate
8
-
9
7
  attr_accessor :configs
10
8
  attr_reader :forks
11
9
 
@@ -21,7 +19,6 @@ module QPush
21
19
  # sleep so that our Workers can do their thing.
22
20
  #
23
21
  def start
24
- validate!
25
22
  start_messages
26
23
  flush_spaces
27
24
  create_workers
@@ -55,34 +52,12 @@ module QPush
55
52
  Server.log.info("* Worker count: #{@configs.count}")
56
53
  end
57
54
 
58
- # Validates our data before starting our Workers. Also instantiates our
59
- # connection pool by pinging Redis.
60
- #
61
- def validate!
62
- return if valid?
63
- fail ServerError, errors.full_messages.join(' ')
64
- end
65
-
66
55
  # Removes the list of namespaces used by our server from Redis. This
67
56
  # prepares it for the new list that will be created by our workers.
68
57
  #
69
58
  def flush_spaces
70
- Server.redis { |c| c.del(QPush::Base::KEY + ':namespaces') }
59
+ Server.redis { |c| c.del("#{QPush::Base::KEY}:namespaces") }
71
60
  end
72
61
  end
73
-
74
- # The ManagerValidator ensures the data for our manager is valid before
75
- # attempting to start it.
76
- #
77
- class ManagerValidator
78
- include ObjectValidator::Validator
79
-
80
- validates :redis, with: { proc: proc { Server.redis { |c| c.ping && c.quit } },
81
- msg: 'could not be connected with' }
82
- validates :configs, with: { proc: proc { |m| m.configs.count > 0 },
83
- msg: 'were not defined' }
84
- validates :configs, with: { proc: proc { |m| m.configs.each { |c| c.is_a?(WorkerConfig) } },
85
- msg: 'are not valid WorkerConfig objects' }
86
- end
87
62
  end
88
63
  end
@@ -1,20 +1,26 @@
1
-
2
1
  module QPush
3
2
  module Server
4
- # The Worker manages our workers - Queue, Delay, Perform and Heartbeat.
5
- # Each of these workers is alloted a number of threads. Each worker
3
+ class << self
4
+ attr_accessor :worker
5
+
6
+ # A convenience method used to create new WorkerConfig objects for use
7
+ # in our server configuration.
8
+ #
9
+ def build_worker
10
+ worker = WorkerConfig.new
11
+ yield worker
12
+ worker
13
+ end
14
+ end
15
+
16
+ # The Worker manages our actions - Queue, Delay, Perform and Heartbeat.
17
+ # Each of these actions is alloted a number of threads. Each action
6
18
  # object maintains control of these threads through the aptly named start
7
19
  # and shutdown methods.
8
20
  #
9
21
  class Worker
10
- extend Forwardable
11
- include ObjectValidator::Validate
12
-
13
22
  attr_reader :config, :pid, :id
14
23
 
15
- def_delegators :@config, :perform_threads, :delay_threads, :queue_threads,
16
- :priorities, :base_threads, :namespace
17
-
18
24
  def initialize(id, config)
19
25
  @id = id
20
26
  @pid = Process.pid
@@ -27,11 +33,10 @@ module QPush
27
33
  # Starts our new worker.
28
34
  #
29
35
  def start
30
- validate!
31
36
  assign_globals
32
37
  register_space
33
38
  start_message
34
- build_threads
39
+ build_actions
35
40
  start_threads
36
41
  end
37
42
 
@@ -45,42 +50,56 @@ module QPush
45
50
 
46
51
  private
47
52
 
48
- # Forks the worker and creates the actual threads (@threads) for
49
- # our Queue and Retry objects. We then start them and join them to the
50
- # main process.
53
+ # Assign the globals that are required for our worker to function.
51
54
  #
52
- def start_threads
53
- @actions.each do |action|
54
- @threads << Thread.new { action.start }
55
+ def assign_globals
56
+ Server.keys = Server.build_keys(@config.namespace, @config.priorities)
57
+ Server.worker = self
58
+ end
59
+
60
+ # Registers our workers namespace on Redis
61
+ #
62
+ def register_space
63
+ Server.redis do |c|
64
+ c.sadd("#{QPush::Base::KEY}:namespaces", @config.namespace)
55
65
  end
56
- @threads.map(&:join)
66
+ end
67
+
68
+ # Information about the start process
69
+ #
70
+ def start_message
71
+ Server.log.info("* Worker #{@id} started | pid: #{@pid} | namespace: #{@config.namespace}")
57
72
  end
58
73
 
59
74
  # Instantiates our Queue, Perform, Delay and Heartbeat objects based on
60
- # the number of threads specified for each process type. We store these
75
+ # the number of threads specified for each action type. We store these
61
76
  # objects as an array in @actions.
62
77
  #
63
- def build_threads
64
- base_threads.each do |thread|
65
- thread[:count].times do
66
- @actions << thread[:klass].new
78
+ def build_actions
79
+ base_actions.each do |action|
80
+ action[:count].times do
81
+ @actions << action[:klass].new
67
82
  end
68
83
  end
69
84
  end
70
85
 
71
- def base_threads
86
+ def base_actions
72
87
  [
73
- { klass: Perform, count: perform_threads },
74
- { klass: Queue, count: queue_threads },
75
- { klass: Delay, count: delay_threads },
88
+ { klass: Perform, count: @config.perform_threads },
89
+ { klass: Queue, count: @config.queue_threads },
90
+ { klass: Delay, count: @config.delay_threads },
76
91
  { klass: Heartbeat, count: 1 }
77
92
  ]
78
93
  end
79
94
 
80
- # Information about the start process
95
+ # Creates threads for each of the action objects, We then start them and
96
+ # join them to the main process.
81
97
  #
82
- def start_message
83
- Server.log.info("* Worker #{@id} started | pid: #{@pid} | namespace: #{namespace}")
98
+ def start_threads
99
+ @actions.each do |action|
100
+ @threads << Thread.new { action.start }
101
+ end
102
+ @threads.map(&:join)
84
103
  end
85
104
 
86
105
  # Information about the shutdown process
@@ -88,40 +107,40 @@ module QPush
88
107
  def shutdown_message
89
108
  Server.log.info("* Worker #{@id} shutdown | pid: #{@pid}")
90
109
  end
110
+ end
91
111
 
92
- # Validates our data before starting the worker.
93
- #
94
- def validate!
95
- return if valid?
96
- fail ServerError, errors.full_messages.join(' ')
97
- end
112
+ class WorkerConfig
113
+ include ObjectValidator::Validate
98
114
 
99
- def assign_globals
100
- Server.keys = RedisKeys.build(@config.namespace, @config.priorities)
101
- Server.worker = self
115
+ DEFAULTS = {
116
+ namespace: 'default',
117
+ priorities: 5,
118
+ queue_threads: 2,
119
+ perform_threads: 2,
120
+ delay_threads: 1 }.freeze
121
+
122
+ attr_accessor :perform_threads, :queue_threads, :delay_threads,
123
+ :namespace, :priorities
124
+
125
+ def initialize(options = {})
126
+ options = DEFAULTS.merge(options)
127
+ options.each { |key, value| send("#{key}=", value) }
102
128
  end
103
129
 
104
- # Registers our workers namespace on Redis
105
- #
106
- def register_space
107
- Server.redis do |c|
108
- c.sadd(QPush::Base::KEY + ':namespaces', namespace)
109
- end
130
+ def validate!
131
+ return if valid?
132
+ fail ServerError, errors.full_messages.join(' ')
110
133
  end
111
134
  end
112
135
 
113
- # The WorkerValidator ensures the data for our worker is
114
- # valid before attempting to use it.
115
- #
116
- class WorkerValidator
136
+ class WorkerConfigValidator
117
137
  include ObjectValidator::Validator
118
138
 
119
- validates :config, type: QPush::Server::WorkerConfig
120
- validates :perform_threads, type: Integer, greater_than: 0
121
- validates :queue_threads, type: Integer, greater_than: 0
122
- validates :delay_threads, type: Integer, greater_than: 0
123
139
  validates :namespace, type: String
124
- validates :priorities, type: Integer, greater_than: 4
140
+ validates :priorities, greater_than: 4
141
+ validates :queue_threads, greater_than: 0
142
+ validates :perform_threads, greater_than: 0
143
+ validates :delay_threads, greater_than: 0
125
144
  end
126
145
  end
127
146
  end
@@ -1,4 +1,4 @@
1
1
  module QPush
2
- VERSION = '0.1.8'
2
+ VERSION = '0.1.10'
3
3
  CODENAME = 'Sun Soaked Salamander'
4
4
  end
@@ -7,7 +7,6 @@ require 'qpush/base'
7
7
  # Web Base
8
8
  require 'qpush/web/config'
9
9
  require 'qpush/web/get'
10
- require 'qpush/web/redis'
11
10
  require 'qpush/web/server'
12
11
 
13
12
  # Web Apis
@@ -1,15 +1,12 @@
1
1
  module QPush
2
2
  module Web
3
3
  include QPush::Base::ConfigHelper
4
+ include QPush::Base::RedisHelper
4
5
 
5
6
  class << self
6
7
  def config
7
8
  @config ||= Config.new
8
9
  end
9
-
10
- def keys
11
- @keys ||= QPush::Web::RedisKeys.new
12
- end
13
10
  end
14
11
 
15
12
  class Config < QPush::Base::Config; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qpush
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicholas Sweeting
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-26 00:00:00.000000000 Z
11
+ date: 2016-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -200,7 +200,6 @@ files:
200
200
  - bin/qpush-server
201
201
  - bin/qpush-web
202
202
  - bin/setup
203
- - dump.rdb
204
203
  - jobs/fail_job.rb
205
204
  - jobs/test_job.rb
206
205
  - lib/qpush.rb
@@ -209,9 +208,6 @@ files:
209
208
  - lib/qpush/base/job.rb
210
209
  - lib/qpush/base/redis.rb
211
210
  - lib/qpush/client.rb
212
- - lib/qpush/client/config.rb
213
- - lib/qpush/client/job.rb
214
- - lib/qpush/client/redis.rb
215
211
  - lib/qpush/jobs/queue_delayed.rb
216
212
  - lib/qpush/server.rb
217
213
  - lib/qpush/server/apis.rb
@@ -236,7 +232,6 @@ files:
236
232
  - lib/qpush/server/manager.rb
237
233
  - lib/qpush/server/perform.rb
238
234
  - lib/qpush/server/queue.rb
239
- - lib/qpush/server/redis.rb
240
235
  - lib/qpush/server/worker.rb
241
236
  - lib/qpush/version.rb
242
237
  - lib/qpush/web.rb
@@ -267,7 +262,6 @@ files:
267
262
  - lib/qpush/web/public/js/app.js
268
263
  - lib/qpush/web/public/js/shims.js
269
264
  - lib/qpush/web/public/tsconfig.json
270
- - lib/qpush/web/redis.rb
271
265
  - lib/qpush/web/server.rb
272
266
  - lib/qpush/web/server.ru
273
267
  - qpush.gemspec
data/dump.rdb DELETED
Binary file
@@ -1,13 +0,0 @@
1
- module QPush
2
- module Client
3
- include QPush::Base::ConfigHelper
4
-
5
- class << self
6
- def config
7
- @config ||= Config.new
8
- end
9
- end
10
-
11
- class Config < QPush::Base::Config; end
12
- end
13
- end
@@ -1,12 +0,0 @@
1
- module QPush
2
- module Client
3
- class Job < QPush::Base::Job
4
- def queue
5
- Client.redis do |conn|
6
- conn.hincrby("#{QPush::Base::KEY}:#{@namespace}:stats", 'queued', 1)
7
- conn.lpush("#{QPush::Base::KEY}:#{@namespace}:queue", to_json)
8
- end
9
- end
10
- end
11
- end
12
- end
@@ -1,16 +0,0 @@
1
- module QPush
2
- module Client
3
- class << self
4
- def redis
5
- redis_pool.with do |conn|
6
- yield conn
7
- end
8
- end
9
-
10
- def redis_pool
11
- @redis_pool ||= QPush::Base::RedisPool.create(Client.config.redis_pool,
12
- Client.config.redis_url)
13
- end
14
- end
15
- end
16
- end
@@ -1,34 +0,0 @@
1
- module QPush
2
- module Server
3
- class << self
4
- def redis
5
- redis_pool.with do |conn|
6
- yield conn
7
- end
8
- end
9
-
10
- def redis_pool
11
- @redis_pool ||= QPush::Base::RedisPool.create(Server.config.redis_pool,
12
- Server.config.redis_url)
13
- end
14
- end
15
-
16
- module RedisKeys
17
- KEYS = [:delay,
18
- :queue,
19
- :perform,
20
- :stats,
21
- :heart,
22
- :crons,
23
- :history,
24
- :morgue]
25
-
26
- def self.build(namespace, priorities)
27
- name = "#{QPush::Base::KEY}:#{namespace}"
28
- keys = Hash[KEYS.collect { |key| [key, "#{name}:#{key}"] }]
29
- keys[:perform_list] = (1..5).collect { |num| "#{keys[:perform]}:#{num}" }
30
- keys
31
- end
32
- end
33
- end
34
- end
@@ -1,48 +0,0 @@
1
- module QPush
2
- module Web
3
- class << self
4
- def redis
5
- redis_pool.with do |conn|
6
- yield conn
7
- end
8
- end
9
-
10
- def redis_pool
11
- @redis_pool ||= QPush::Base::RedisPool.create(Web.config.redis_pool,
12
- Web.config.redis_url)
13
- end
14
- end
15
-
16
- class RedisKeys
17
- KEYS = [:delay,
18
- :queue,
19
- :perform,
20
- :stats,
21
- :heart,
22
- :crons,
23
- :history,
24
- :morgue]
25
-
26
- attr_reader :delay, :queue, :perform, :stats, :heart,
27
- :crons, :history, :morgue
28
-
29
- def initialize(options = {})
30
- @namespace = options[:namespace] || 'default'
31
- @priorities = options[:priorities] || 5
32
- build_keyspaces
33
- end
34
-
35
- def perform_list
36
- @perform_list ||= (1..@priorities).collect { |num| "#{perform}:#{num}" }
37
- end
38
-
39
- private
40
-
41
- def build_keyspaces
42
- KEYS.each do |key|
43
- instance_variable_set("@#{key}", "#{QPush::Base::KEY}:#{@namespace}:#{key}")
44
- end
45
- end
46
- end
47
- end
48
- end