magent 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.0
1
+ 0.6.1
data/bin/magent CHANGED
@@ -91,7 +91,7 @@ class Controller
91
91
  if @options[:daemonize] && @options[:piddir]
92
92
  run_as_daemon
93
93
  else
94
- Magent::Processor.new(self.channel).run!
94
+ Magent::Processor.new(self.channel, @identity).run!
95
95
  end
96
96
  end
97
97
 
@@ -6,6 +6,7 @@ require 'mongo'
6
6
  require 'set'
7
7
  require 'uuidtools'
8
8
 
9
+ require 'magent/stats'
9
10
  require 'magent/failure'
10
11
 
11
12
  require 'magent/utils'
@@ -1,8 +1,10 @@
1
1
  module Magent
2
2
  class GenericChannel
3
3
  include Magent::Failure
4
+ include Magent::Stats
4
5
 
5
6
  attr_reader :name
7
+ attr_reader :current_job
6
8
 
7
9
  def initialize(name)
8
10
  @name = "magent.#{name}"
@@ -21,8 +23,8 @@ module Magent
21
23
  end
22
24
 
23
25
  def dequeue
24
- if m = self.next_message
25
- m["message"]
26
+ if @current_job = self.next_message
27
+ @current_job["message"]
26
28
  end
27
29
  end
28
30
 
@@ -1,8 +1,11 @@
1
1
  module Magent
2
2
  class Processor
3
- def initialize(channel)
3
+ def initialize(channel, identity = "#{channel.name}-#{Socket.gethostname.split('.')[0]}")
4
4
  @channel = channel
5
5
  @shutdown = false
6
+ @identity = identity
7
+
8
+ @channel.on_start(identity)
6
9
 
7
10
  # @actor.class.actions.each do |action|
8
11
  # if !@actor.respond_to?(action)
@@ -23,8 +26,12 @@ module Magent
23
26
 
24
27
  message = @channel.dequeue
25
28
  begin
29
+ t = Time.now
26
30
  if message && @channel.process!(message)
27
31
  puts "Processed #{message.inspect}"
32
+
33
+ @channel.on_job_processed(@channel.current_job, Time.now - t, @identity)
34
+
28
35
  delay = 0
29
36
  processed_messages += 1
30
37
  if processed_messages > 20
@@ -37,6 +44,7 @@ module Magent
37
44
  rescue SystemExit
38
45
  rescue Exception => e
39
46
  $stderr.puts "Error processing #{message.inspect} => #{e.message}"
47
+ @channel.on_job_failed(@identity)
40
48
  @channel.failed(:error => e.message, :message => message, :backtrace => e.backtrace, :date => Time.now.utc)
41
49
  ensure
42
50
  end
@@ -47,6 +55,8 @@ module Magent
47
55
 
48
56
  def shutdown!
49
57
  @shutdown = true
58
+ @channel.on_quit
59
+
50
60
  @channel.on_shutdown if @channel.respond_to?(:on_shutdown)
51
61
  $stderr.puts "Shutting down..."
52
62
  end
@@ -0,0 +1,52 @@
1
+ module Magent
2
+ module Stats
3
+ def stats_collection
4
+ @stats_collection ||= Magent.database.collection("magent.stats")
5
+ end
6
+
7
+ def stats
8
+ @stats ||= if doc = stats_collection.find({:_id => @name}, {}).next_document
9
+ doc
10
+ else
11
+ stats_collection.save({:_id => @name,
12
+ :created_at => Time.now.utc,
13
+ :total_errors => 0,
14
+ :total_jobs => 0,
15
+ :last_processed_job => {"duration" => 0, "method" => "", "priority" => 0},
16
+ :updated_at => Time.now.utc,
17
+ :updated_by => "",
18
+ :workers => {}
19
+ }, {:safe => true})
20
+
21
+ stats_collection.find({:_id => @name}, {}).next_document
22
+ end
23
+ end
24
+
25
+ def on_job_processed(last_job, duration, updated_by)
26
+ last_job["duration"] = ("%f" % duration)
27
+ updated_at = Time.now
28
+
29
+ updates = {}
30
+ updates[:$inc] = {:total_jobs => 1, :"workers.#{updated_by}.total_jobs" => 1}
31
+ updates[:$set] = {:updated_at => updated_at, :updated_by => updated_by,
32
+ :last_processed_job => last_job,
33
+ :"workers.#{updated_by}.last_update_at" => updated_at }
34
+
35
+ stats_collection.update({:_id => @name}, updates, {:multi => true})
36
+ end
37
+
38
+ def on_job_failed(updated_by)
39
+ stats_collection.update({:_id => @name}, {:$inc => {:total_errors => 1, :"workers.#{updated_by}.total_errors" => 1} })
40
+ end
41
+
42
+ def on_start(updated_by)
43
+ puts ">>> Current Stats: #{stats.inspect}"
44
+ stats_collection.update({:_id => @name}, {:$set => {:"workers.#{updated_by}.last_update_at" => Time.now.utc},
45
+ :$inc => {:"workers.#{updated_by}.total_restarts" => 1} }, {:safe => true, :multi => true})
46
+ end
47
+
48
+ def on_quit(updated_by)
49
+ stats_collection.update({:_id => @name}, {:set => {:"workers.#{updated_by}.quitted_at" => Time.now.utc} })
50
+ end
51
+ end
52
+ end
@@ -41,6 +41,11 @@ module MagentWeb
41
41
 
42
42
  get "/queues/:id/stats" do
43
43
  @queue = @database.collection(params[:id])
44
+ @channel_name = channel_name_for(params[:id])
45
+ channel = Magent::GenericChannel.new(@channel_name)
46
+
47
+ @stats_collection = channel.stats_collection
48
+ @stats = channel.stats
44
49
 
45
50
  haml :"queues/stats"
46
51
  end
@@ -49,7 +54,7 @@ module MagentWeb
49
54
  @errors_queue = @database.collection(params[:queue_id]+".errors")
50
55
  @channel_name = channel_name_for(params[:queue_id])
51
56
 
52
- channel = Magent::AsyncChannel.new(@channel_name)
57
+ channel = Magent::GenericChannel.new(@channel_name)
53
58
 
54
59
  doc = @errors_queue.find({:_id => params[:id]}).next_document
55
60
  channel.enqueue_error(doc)
@@ -3,7 +3,7 @@ module MagentWeb
3
3
  def queues
4
4
  q = []
5
5
  Magent.database.collections.each do |collection|
6
- if collection.name =~ /^magent\./ && collection.name !~ /errors$/
6
+ if collection.name =~ /^magent\./ && collection.name !~ /(errors|stats)$/
7
7
  q << collection
8
8
  end
9
9
  end
@@ -51,13 +51,13 @@ module MagentWeb
51
51
  Magent.database.command(:serverStatus => 1)
52
52
  end
53
53
 
54
- def humanize(v, quote = true)
54
+ def humanize(v, quote = false)
55
55
  if v.nil? && quote
56
56
  "null"
57
57
  elsif v.kind_of?(Hash)
58
58
  JSON.pretty_generate(v)
59
59
  elsif v.kind_of?(Array)
60
- JSON.pretty_generate(v)
60
+ v.map{|e| e.nil? ? "null" : e }.join("<br />")
61
61
  elsif v.kind_of?(Time)
62
62
  v.strftime("%d %B %Y %H:%M:%S").inspect
63
63
  elsif quote
@@ -16,14 +16,6 @@
16
16
 
17
17
 
18
18
  %div(data-role="content")
19
- -if skip == 0
20
- %h1
21
- Information
22
- -normalize_stats(@queue.stats).each do |k,v|
23
- %b
24
- &="#{k}="
25
- &=humanize v
26
- %br
27
19
  %h1
28
20
  Pending Jobs
29
21
  ==(#{@messages.count})
@@ -3,4 +3,15 @@
3
3
  %h1
4
4
  =@title ="Stats"
5
5
  %div(data-role="content")
6
+ %h3
7
+ Database Information
8
+ -normalize_stats(@queue.stats).each do |k,v|
9
+ %b
10
+ &="#{k}="
11
+ &=humanize v
12
+ %br
13
+ %h3
14
+ General Stats
15
+ =haml :"shared/values", :layout => false, :locals => {:hash => normalize_stats(@stats)}
16
+
6
17
  %div(data-role="footer")
@@ -2,12 +2,12 @@
2
2
  -k = humanize(key)
3
3
  -v = humanize(value)
4
4
 
5
- -if value.kind_of?(Hash) && value.size > 5
5
+ -if value.kind_of?(Hash)
6
6
  %div(data-role="collapsible" data-collapsed=true data-theme="b")
7
7
  %h2
8
8
  &=k
9
9
  = haml :"shared/values", :layout => false, :locals => {:hash => value}
10
- -elsif value.kind_of?(Array) && value.size > 5
10
+ -elsif value.kind_of?(Array)
11
11
  %div(data-role="collapsible" data-collapsed=true data-theme="b")
12
12
  %h2
13
13
  &=k
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{magent}
8
- s.version = "0.6.0"
8
+ s.version = "0.6.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["David A. Cuadrado"]
@@ -47,6 +47,7 @@ Gem::Specification.new do |s|
47
47
  "lib/magent/processor.rb",
48
48
  "lib/magent/push.rb",
49
49
  "lib/magent/railtie.rb",
50
+ "lib/magent/stats.rb",
50
51
  "lib/magent/utils.rb",
51
52
  "lib/magent/web_socket_channel.rb",
52
53
  "lib/magent/web_socket_server.rb",
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 6
8
- - 0
9
- version: 0.6.0
8
+ - 1
9
+ version: 0.6.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - David A. Cuadrado
@@ -194,6 +194,7 @@ files:
194
194
  - lib/magent/processor.rb
195
195
  - lib/magent/push.rb
196
196
  - lib/magent/railtie.rb
197
+ - lib/magent/stats.rb
197
198
  - lib/magent/utils.rb
198
199
  - lib/magent/web_socket_channel.rb
199
200
  - lib/magent/web_socket_server.rb