magent 0.6.2 → 0.7.0

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.
@@ -1,22 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $:.unshift File.dirname(__FILE__)+"/../../lib/"
4
- require 'magent'
5
-
6
- id = "#{rand(16)}#{rand(16)}#{rand(16)}#{rand(16)}"
7
-
8
- values = (1..5).to_a.map { rand(10) }
9
- puts values.join(" + ")
10
- Magent.push("workers", :sum, id, *values)
11
-
12
- channel = Magent::GenericChannel.new("+#{id}")
13
-
14
- loop do
15
- v = channel.dequeue;
16
- if v
17
- $stdout.puts v.inspect
18
- break
19
- end
20
- sleep 0.1
21
- end
22
-
@@ -1,30 +0,0 @@
1
- $:.unshift File.dirname(__FILE__)+"/../../lib/"
2
- require 'magent'
3
-
4
- # Use: magent /path/to/this/file
5
-
6
- class Worker
7
- include Magent::Actor
8
- channel_name "workers"
9
- expose :sum
10
-
11
- def sum(payload)
12
- id, *args = payload
13
-
14
- s = args.inject(0) { |v, a| a += v }
15
- send_to_client(id, {:method => :sum, :result => s})
16
- end
17
-
18
- private
19
- def send_to_client(id, message)
20
- c = Magent::GenericChannel.new("+#{id}")
21
- c.enqueue(message)
22
- end
23
- end
24
-
25
- Magent.register(Worker.new)
26
-
27
- if $0 == __FILE__
28
- Magent::Processor.new(Worker.channel).run!
29
- end
30
-
@@ -1,33 +0,0 @@
1
- $:.unshift File.dirname(__FILE__)+"/../../lib/"
2
- require 'magent'
3
-
4
- Magent.push("errors", :fail, "this is a fail")
5
-
6
- class Error
7
- include Magent::Actor
8
-
9
- channel_name "errors"
10
- expose :fail
11
-
12
- def fail(payload)
13
- @count ||= 0
14
- errors = self.class.channel.errors
15
-
16
- errors.each do |error|
17
- @count += 1
18
- $stderr.puts "Retrying: #{error["method"]}(#{error["payload"].inspect})"
19
- self.class.channel.retry_error(error)
20
- end
21
-
22
- if @count == 0
23
- raise payload.inspect
24
- end
25
- end
26
- end
27
-
28
- Magent.register(Error.new)
29
-
30
- if $0 == __FILE__
31
- Magent::Processor.new(Error.channel).run!
32
- end
33
-
@@ -1,41 +0,0 @@
1
- $:.unshift File.dirname(__FILE__)+"/../../lib/"
2
- require 'rubygems'
3
- require 'magent'
4
- require 'mongo_mapper'
5
-
6
-
7
- MongoMapper.database = "test"
8
- Magent.database = "test"
9
-
10
- class Thing
11
- include MongoMapper::Document
12
- include Magent::Async
13
-
14
- key :_id, String
15
- key :name
16
-
17
- def process_something(arg)
18
- puts "Processing: #{arg}"
19
- end
20
-
21
- def process_nothing
22
- puts "Processing..."
23
- end
24
-
25
- def self.foo
26
- puts "MAX PRIORITY"
27
- end
28
- end
29
-
30
-
31
- thing = Thing.create(:_id => "foo")
32
-
33
- # 3 messages
34
- thing.async.process_something("testing").commit!
35
- thing.async.process_nothing.commit!
36
- Thing.async.find(thing.id).process_something("testing2").commit!
37
- Thing.async.foo.commit!(1)
38
-
39
- Magent::Processor.new(Magent::AsyncChannel.new(:default)).run!
40
-
41
-
@@ -1,38 +0,0 @@
1
- $:.unshift File.dirname(__FILE__)+"/../../lib/"
2
- require 'rubygems'
3
- require 'magent'
4
-
5
- # Use: magent /path/to/this/file
6
-
7
- Magent.push("bots", :echo, "hello, world")
8
- Magent.push("bots", :do_task, "File", :exist?, "/etc/passwd")
9
- Magent.push("bots", :echo, "Press ctrl+c to close")
10
- Magent.push("bots", :do_not_exist, "you should not see this message")
11
-
12
- class Bot
13
- include Magent::Actor
14
- channel_name "bots"
15
- expose :echo, :do_task
16
-
17
- def echo(payload)
18
- $stderr.puts payload.inspect
19
- end
20
-
21
- def do_task(payload)
22
- klass, *args = payload
23
-
24
- result = Object.module_eval(klass).send(*args)
25
- $stderr.puts "RESULT: #{result}"
26
- end
27
-
28
- at_least_every 15 do
29
- puts "Hi there!, you'll see this message again in ~15 seconds"
30
- end
31
- end
32
-
33
- Magent.register(Bot.new)
34
-
35
- if $0 == __FILE__
36
- Magent::Processor.new(Bot.channel).run!
37
- end
38
-
@@ -1,27 +0,0 @@
1
- $:.unshift File.dirname(__FILE__)+"/../../lib/"
2
- require 'magent'
3
-
4
- Magent.push("stats", :calc)
5
- Magent.push("stats", :calc)
6
- Magent.push("stats", :calc)
7
- Magent.push("stats", :calc)
8
-
9
- class Stats
10
- include Magent::Actor
11
-
12
- channel_name "stats"
13
- expose :calc
14
-
15
- def calc(payload)
16
- $stderr.puts "messages in queue: #{self.class.channel.queue_count}"
17
- $stderr.puts "total messages count: #{self.class.channel.message_count}"
18
- $stderr.puts "total errors: #{self.class.channel.error_count}"
19
- end
20
- end
21
-
22
- Magent.register(Stats.new)
23
-
24
- if $0 == __FILE__
25
- Magent::Processor.new(Stats.channel).run!
26
- end
27
-
@@ -1,82 +0,0 @@
1
- module Magent
2
- module Actor
3
- def self.included(klass)
4
- klass.class_eval do
5
- extend Actor::ClassMethods
6
- include Actor::InstanceMethods
7
- end
8
- end
9
-
10
- module ClassMethods
11
- def expose(*methods)
12
- methods.each do |m|
13
- actions << m.to_s
14
- end
15
- end
16
-
17
- def channel_name(name = nil)
18
- @channel_name ||= (name || Magent::Utils.underscore(self.name)).to_s
19
- end
20
-
21
- def actions
22
- @actions ||= Set.new
23
- end
24
-
25
- def can_handle?(action)
26
- actions.include?(action.to_s)
27
- end
28
-
29
- def channel
30
- @channel ||= begin
31
- ActorChannel.new(self.channel_name)
32
- end
33
- end
34
-
35
- def tasks
36
- @tasks ||= []
37
- end
38
-
39
- def at_least_every(seconds, &block)
40
- tasks << {:every => seconds, :last_time => Time.now, :block => block}
41
- end
42
- end
43
-
44
- module InstanceMethods
45
- def _run_tasks
46
- tasks = self.class.tasks
47
-
48
- return false if tasks.empty?
49
- performed = false
50
-
51
- tasks.each do |task|
52
- delta = Time.now - task[:last_time]
53
-
54
- if delta >= task[:every]
55
- task[:last_time] = Time.now
56
- begin
57
- instance_eval(&task[:block])
58
- rescue Exception => e
59
- $stderr.puts "Failed periodical task: #{e.message}"
60
- $stderr.puts e.backtrace.join("\n\t")
61
- end
62
- performed = true
63
- end
64
- end
65
-
66
- performed
67
- end
68
- end
69
- end # Actor
70
-
71
- def self.register(actor)
72
- @current_actor = actor
73
- end
74
-
75
- def self.current_actor
76
- @current_actor
77
- end
78
-
79
- def self.current_channel
80
- self.current_actor.channel
81
- end
82
- end
@@ -1,34 +0,0 @@
1
- module Magent
2
- class ActorChannel < GenericChannel
3
- def push(message, args)
4
- enqueue([message, args])
5
- end
6
-
7
- def process!(message)
8
- @actor = Magent.current_actor
9
-
10
- @method, @payload = message
11
- return false if @method.nil?
12
-
13
- sucess = @actor._run_tasks
14
-
15
- $stderr.puts "#{@actor.class}##{@method}(#{@payload.inspect})"
16
- if @actor.class.can_handle?(@method)
17
- @actor.send(@method, @payload)
18
- return true
19
- else
20
- $stderr.puts "Unknown action: #{@method} (payload=#{@payload.inspect})"
21
- end
22
-
23
- @method, @payload = nil
24
-
25
- sucess
26
- end
27
-
28
- def on_shutdown
29
- if @method
30
- self.enqueue(@method, @payload)
31
- end
32
- end
33
- end # Channel
34
- end
@@ -1,13 +0,0 @@
1
- module Magent
2
- def self.push(channel_name, method, *args)
3
- self.channel(channel_name.to_s).push(method, args)
4
- end
5
-
6
- def self.channel(name)
7
- self.channels[name] ||= ActorChannel.new(name)
8
- end
9
-
10
- def self.channels
11
- @channels ||= {}
12
- end
13
- end
@@ -1,16 +0,0 @@
1
- module Magent
2
- class WebSocketChannel < Magent::GenericChannel
3
- def self.push(message)
4
- self.instance.enqueue(message)
5
- self.instance
6
- end
7
-
8
- def self.dequeue
9
- self.instance.dequeue
10
- end
11
-
12
- def self.instance
13
- @channel ||= self.new(Magent.config["websocket_channel"]||"magent.websocket")
14
- end
15
- end
16
- end
@@ -1,107 +0,0 @@
1
- require 'magent/web_socket_channel'
2
- module Magent
3
- class WebSocketServer
4
- def initialize(options = {})
5
- options = {:host => "0.0.0.0", :port => 34567}.merge(options)
6
-
7
- $stdout.puts ">> Server running and up! #{options}}" if options[:debug]
8
-
9
- EventMachine.run do
10
- setup
11
-
12
- EM.run do
13
- EventMachine.add_periodic_timer(options.delete(:interval)||10) do
14
- while message = Magent::WebSocketChannel.dequeue
15
- if (channel = @channels[message["channel_id"]])
16
- channel.push(message.to_json)
17
- end
18
- end
19
- end
20
- end
21
-
22
- EventMachine::WebSocket.start(options) do |ws|
23
- ws.onopen do
24
- ws.onmessage do |msg|
25
- data = JSON.parse(msg) rescue {}
26
-
27
- if !handle_message(ws, data)
28
- case data["id"]
29
- when 'start'
30
- if data["channel_id"].present? && (channel_id = validate_channel_id(data["channel_id"]))
31
- key = generate_unique_key(data["key"])
32
- @channels[channel_id] ||= EM::Channel.new
33
- @channel_ids[key] = channel_id
34
-
35
- sid = @channels[channel_id].subscribe { |msg| ws.send(msg) }
36
-
37
- @sids[key] = sid
38
- ws.onclose do
39
- @channel_ids.delete(key)
40
- @channels[channel_id].unsubscribe(sid)
41
- @sids.delete(key)
42
- end
43
-
44
- ws.send({:id => "ack", :key => key}.to_json)
45
- send(:on_ack, ws, channel_id) if respond_to?(:on_ack)
46
- else
47
- ws.close_connection
48
- end
49
- when 'chatmessage'
50
- key = data["key"]
51
- return invalid_key(ws) if key.blank? || @sids[key].blank?
52
-
53
- channel_id = @channel_ids[key]
54
-
55
- if channel_id
56
- chat_message = {:id => 'chatmessage', :from => user_name(key, @sids[key]), :message => data["message"]}
57
-
58
- @channels[channel_id].push(validate_chat_message(channel_id, chat_message).to_json)
59
- else
60
- ws.send({:id => 'announcement', :type => "error", :message => "cannot find the channel"}.to_json)
61
- end
62
- end
63
- end # if
64
- end
65
- end
66
- end # EM::WebSocket
67
- end
68
- end
69
-
70
- def self.start(options = {})
71
- self.new(options)
72
- end
73
-
74
- def setup
75
- @channel = EM::Channel.new
76
- @channels = {}
77
- @channel_ids = {}
78
- @sids = {}
79
- end
80
-
81
- protected
82
- def invalid_key(ws)
83
- ws.send({:id => 'announcement', :type => "error", :message => "you must provide your unique key"}.to_json)
84
- end
85
-
86
- def handle_message(ws, data)
87
- false
88
- end
89
-
90
- def validate_chat_message(channel_id, chat_message)
91
- chat_message
92
- end
93
-
94
- protected
95
- def generate_unique_key(default = nil)
96
- default || UUIDTools::UUID.random_create.hexdigest
97
- end
98
-
99
- def validate_channel_id(id)
100
- return id if !id.blank?
101
- end
102
-
103
- def user_name(socket_key, sid)
104
- "Guest #{sid}"
105
- end
106
- end # Class
107
- end