wakame 0.4.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.
Files changed (147) hide show
  1. data/History.txt +20 -0
  2. data/README.rdoc +63 -0
  3. data/Rakefile +86 -0
  4. data/VERSION +1 -0
  5. data/app_generators/wakame/templates/README +0 -0
  6. data/app_generators/wakame/templates/Rakefile +18 -0
  7. data/app_generators/wakame/templates/bin/wakame-agent +9 -0
  8. data/app_generators/wakame/templates/bin/wakame-master +9 -0
  9. data/app_generators/wakame/templates/bin/wakameadm +9 -0
  10. data/app_generators/wakame/templates/cluster/resources/apache_app/apache_app.rb +54 -0
  11. data/app_generators/wakame/templates/cluster/resources/apache_app/conf/apache2.conf +46 -0
  12. data/app_generators/wakame/templates/cluster/resources/apache_app/conf/envvars-app +7 -0
  13. data/app_generators/wakame/templates/cluster/resources/apache_app/conf/sites-app.conf +23 -0
  14. data/app_generators/wakame/templates/cluster/resources/apache_app/conf/system-app.conf +67 -0
  15. data/app_generators/wakame/templates/cluster/resources/apache_app/init.d/apache2-app +192 -0
  16. data/app_generators/wakame/templates/cluster/resources/apache_lb/apache_lb.rb +56 -0
  17. data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/apache2.conf +46 -0
  18. data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/envvars-lb +6 -0
  19. data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/sites-lb.conf +54 -0
  20. data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/system-lb.conf +75 -0
  21. data/app_generators/wakame/templates/cluster/resources/apache_lb/init.d/apache2-lb +192 -0
  22. data/app_generators/wakame/templates/cluster/resources/apache_www/apache_www.rb +50 -0
  23. data/app_generators/wakame/templates/cluster/resources/apache_www/conf/apache2.conf +47 -0
  24. data/app_generators/wakame/templates/cluster/resources/apache_www/conf/envvars-www +7 -0
  25. data/app_generators/wakame/templates/cluster/resources/apache_www/conf/sites-www.conf +23 -0
  26. data/app_generators/wakame/templates/cluster/resources/apache_www/conf/system-www.conf +63 -0
  27. data/app_generators/wakame/templates/cluster/resources/apache_www/init.d/apache2-www +192 -0
  28. data/app_generators/wakame/templates/cluster/resources/ec2_elastic_ip/ec2_elastic_ip.rb +39 -0
  29. data/app_generators/wakame/templates/cluster/resources/mysql_master/conf/my.cnf +154 -0
  30. data/app_generators/wakame/templates/cluster/resources/mysql_master/init.d/mysql +185 -0
  31. data/app_generators/wakame/templates/cluster/resources/mysql_master/mysql_master.rb +174 -0
  32. data/app_generators/wakame/templates/config/boot.rb +85 -0
  33. data/app_generators/wakame/templates/config/cluster.rb +64 -0
  34. data/app_generators/wakame/templates/config/environments/common.rb +0 -0
  35. data/app_generators/wakame/templates/config/environments/ec2.rb +3 -0
  36. data/app_generators/wakame/templates/config/environments/stand_alone.rb +0 -0
  37. data/app_generators/wakame/templates/config/init.d/wakame-agent +72 -0
  38. data/app_generators/wakame/templates/config/init.d/wakame-master +73 -0
  39. data/app_generators/wakame/wakame_generator.rb +124 -0
  40. data/bin/wakame +18 -0
  41. data/contrib/imagesetup.sh +77 -0
  42. data/lib/ext/eventmachine.rb +86 -0
  43. data/lib/ext/shellwords.rb +172 -0
  44. data/lib/ext/uri.rb +15 -0
  45. data/lib/wakame/action.rb +156 -0
  46. data/lib/wakame/actions/destroy_instances.rb +39 -0
  47. data/lib/wakame/actions/launch_cluster.rb +31 -0
  48. data/lib/wakame/actions/migrate_service.rb +65 -0
  49. data/lib/wakame/actions/propagate_instances.rb +95 -0
  50. data/lib/wakame/actions/reload_service.rb +21 -0
  51. data/lib/wakame/actions/scaleout_when_high_load.rb +44 -0
  52. data/lib/wakame/actions/shutdown_cluster.rb +22 -0
  53. data/lib/wakame/actions/shutdown_vm.rb +19 -0
  54. data/lib/wakame/actions/start_service.rb +64 -0
  55. data/lib/wakame/actions/stop_service.rb +49 -0
  56. data/lib/wakame/actions/util.rb +71 -0
  57. data/lib/wakame/actor/daemon.rb +37 -0
  58. data/lib/wakame/actor/service_monitor.rb +21 -0
  59. data/lib/wakame/actor/system.rb +46 -0
  60. data/lib/wakame/actor.rb +33 -0
  61. data/lib/wakame/agent.rb +226 -0
  62. data/lib/wakame/amqp_client.rb +219 -0
  63. data/lib/wakame/command/action_status.rb +62 -0
  64. data/lib/wakame/command/actor.rb +23 -0
  65. data/lib/wakame/command/clone_service.rb +12 -0
  66. data/lib/wakame/command/launch_cluster.rb +15 -0
  67. data/lib/wakame/command/migrate_service.rb +21 -0
  68. data/lib/wakame/command/propagate_service.rb +24 -0
  69. data/lib/wakame/command/shutdown_cluster.rb +15 -0
  70. data/lib/wakame/command/status.rb +81 -0
  71. data/lib/wakame/command.rb +31 -0
  72. data/lib/wakame/command_queue.rb +44 -0
  73. data/lib/wakame/configuration.rb +93 -0
  74. data/lib/wakame/daemonize.rb +96 -0
  75. data/lib/wakame/event.rb +232 -0
  76. data/lib/wakame/event_dispatcher.rb +154 -0
  77. data/lib/wakame/graph.rb +79 -0
  78. data/lib/wakame/initializer.rb +162 -0
  79. data/lib/wakame/instance_counter.rb +78 -0
  80. data/lib/wakame/logger.rb +12 -0
  81. data/lib/wakame/manager/commands.rb +134 -0
  82. data/lib/wakame/master.rb +369 -0
  83. data/lib/wakame/monitor/agent.rb +50 -0
  84. data/lib/wakame/monitor/service.rb +183 -0
  85. data/lib/wakame/monitor.rb +69 -0
  86. data/lib/wakame/packets.rb +160 -0
  87. data/lib/wakame/queue_declare.rb +14 -0
  88. data/lib/wakame/rule.rb +116 -0
  89. data/lib/wakame/rule_engine.rb +202 -0
  90. data/lib/wakame/runner/administrator_command.rb +112 -0
  91. data/lib/wakame/runner/agent.rb +81 -0
  92. data/lib/wakame/runner/master.rb +93 -0
  93. data/lib/wakame/scheduler.rb +251 -0
  94. data/lib/wakame/service.rb +914 -0
  95. data/lib/wakame/template.rb +189 -0
  96. data/lib/wakame/trigger.rb +66 -0
  97. data/lib/wakame/triggers/instance_count_update.rb +45 -0
  98. data/lib/wakame/triggers/load_history.rb +107 -0
  99. data/lib/wakame/triggers/maintain_ssh_known_hosts.rb +43 -0
  100. data/lib/wakame/triggers/process_command.rb +34 -0
  101. data/lib/wakame/triggers/shutdown_unused_vm.rb +16 -0
  102. data/lib/wakame/util.rb +569 -0
  103. data/lib/wakame/vm_manipulator.rb +186 -0
  104. data/lib/wakame.rb +59 -0
  105. data/tasks/ec2.rake +127 -0
  106. data/tests/cluster.json +3 -0
  107. data/tests/conf/a +1 -0
  108. data/tests/conf/b +1 -0
  109. data/tests/conf/c +1 -0
  110. data/tests/setup_agent.rb +39 -0
  111. data/tests/setup_master.rb +28 -0
  112. data/tests/test_actor.rb +54 -0
  113. data/tests/test_agent.rb +218 -0
  114. data/tests/test_amqp_client.rb +94 -0
  115. data/tests/test_graph.rb +36 -0
  116. data/tests/test_master.rb +167 -0
  117. data/tests/test_monitor.rb +47 -0
  118. data/tests/test_rule_engine.rb +127 -0
  119. data/tests/test_scheduler.rb +123 -0
  120. data/tests/test_service.rb +60 -0
  121. data/tests/test_template.rb +67 -0
  122. data/tests/test_uri_amqp.rb +19 -0
  123. data/tests/test_util.rb +71 -0
  124. data/wakame_generators/resource/resource_generator.rb +54 -0
  125. data/wakame_generators/resource/templates/apache_app/apache_app.rb +60 -0
  126. data/wakame_generators/resource/templates/apache_app/conf/apache2.conf +46 -0
  127. data/wakame_generators/resource/templates/apache_app/conf/envvars-app +7 -0
  128. data/wakame_generators/resource/templates/apache_app/conf/sites-app.conf +23 -0
  129. data/wakame_generators/resource/templates/apache_app/conf/system-app.conf +67 -0
  130. data/wakame_generators/resource/templates/apache_app/init.d/apache2-app +192 -0
  131. data/wakame_generators/resource/templates/apache_lb/apache_lb.rb +67 -0
  132. data/wakame_generators/resource/templates/apache_lb/conf/apache2.conf +46 -0
  133. data/wakame_generators/resource/templates/apache_lb/conf/envvars-lb +6 -0
  134. data/wakame_generators/resource/templates/apache_lb/conf/sites-lb.conf +54 -0
  135. data/wakame_generators/resource/templates/apache_lb/conf/system-lb.conf +75 -0
  136. data/wakame_generators/resource/templates/apache_lb/init.d/apache2-lb +192 -0
  137. data/wakame_generators/resource/templates/apache_www/apache_www.rb +56 -0
  138. data/wakame_generators/resource/templates/apache_www/conf/apache2.conf +47 -0
  139. data/wakame_generators/resource/templates/apache_www/conf/envvars-www +7 -0
  140. data/wakame_generators/resource/templates/apache_www/conf/sites-www.conf +23 -0
  141. data/wakame_generators/resource/templates/apache_www/conf/system-www.conf +63 -0
  142. data/wakame_generators/resource/templates/apache_www/init.d/apache2-www +192 -0
  143. data/wakame_generators/resource/templates/ec2_elastic_ip/ec2_elastic_ip.rb +39 -0
  144. data/wakame_generators/resource/templates/mysql_master/conf/my.cnf +154 -0
  145. data/wakame_generators/resource/templates/mysql_master/init.d/mysql +185 -0
  146. data/wakame_generators/resource/templates/mysql_master/mysql_master.rb +119 -0
  147. metadata +289 -0
@@ -0,0 +1,31 @@
1
+
2
+ module Wakame
3
+ module Command
4
+ class CommandArgumentError < StandardError; end
5
+
6
+ def self.included(klass)
7
+ klass.class_eval {
8
+ class << self
9
+ def command_name
10
+ @command_name ||= Util.snake_case(self.to_s.split('::').last)
11
+ end
12
+
13
+ def command_name=(name)
14
+ @command_name=name
15
+ end
16
+ end
17
+ }
18
+ end
19
+
20
+
21
+ def parse(args)
22
+ end
23
+
24
+ def run(rule)
25
+ end
26
+
27
+ def print_result
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,44 @@
1
+
2
+ require 'drb/drb'
3
+ require 'thread'
4
+
5
+ module Wakame
6
+ class CommandQueue
7
+ attr_reader :master
8
+
9
+ def initialize(master)
10
+ @master = master
11
+ @queue = Queue.new
12
+ @result_queue = Queue.new
13
+
14
+ DRb.start_service(Wakame.config.drb_command_server_uri, self)
15
+ #@drb_server = DRb.start_drbserver(Wakame.config.drb_command_server_uri, self)
16
+ end
17
+
18
+ def shutdown
19
+ DRb.stop_service()
20
+ #@drb_server.stop_service()
21
+ end
22
+
23
+ def deq_cmd()
24
+ @queue.deq
25
+ end
26
+
27
+ def enq_result(res)
28
+ @result_queue.enq(res)
29
+ end
30
+
31
+ def send_cmd(cmd)
32
+ begin
33
+ #cmd = Marshal.load(cmd)
34
+ @queue.enq(cmd)
35
+ ED.fire_event(Event::CommandReceived.new(cmd))
36
+ return @result_queue.deq()
37
+ rescue => e
38
+ Wakame.log.error("#{self.class}:")
39
+ Wakame.log.error(e)
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,93 @@
1
+
2
+
3
+ require 'ostruct'
4
+
5
+ module Wakame
6
+ # System wide configuration parameters
7
+ class Configuration < OpenStruct
8
+
9
+ PARAMS = {
10
+ #:config_template_root => nil,
11
+ #:config_tmp_root => nil,
12
+ :config_root => nil,
13
+ :cluster_class => 'WebCluster',
14
+ :load_paths => [],
15
+ :ssh_private_key => nil,
16
+ :drb_command_server_uri => 'druby://localhost:12345',
17
+ :amqp_server_uri => nil,
18
+ :unused_vm_live_period => 60 * 10,
19
+ :eventmachine_use_epoll => true
20
+ }
21
+
22
+ def initialize(env=WAKAME_ENV)
23
+ super(PARAMS)
24
+ if root_path.nil?
25
+ root_path = Object.const_defined?(:WAKAME_ROOT) ? WAKAME_ROOT : '../'
26
+ end
27
+
28
+ @root_path = root_path
29
+
30
+ self.class.const_get(env).new.process(self)
31
+ end
32
+
33
+ def environment
34
+ ::WAKAME_ENV.to_sym
35
+ end
36
+ alias :vm_environment :environment
37
+
38
+ def environment_path(key=environment)
39
+ File.expand_path("config/environments/#{Util.snake_case(key.to_s)}.rb", root_path)
40
+ end
41
+
42
+ def root_path
43
+ ::WAKAME_ROOT
44
+ end
45
+
46
+ def tmp_path
47
+ File.join(root_path, 'tmp')
48
+ end
49
+
50
+ def ssh_known_hosts
51
+ File.join(self.config_root, "ssh", "known_hosts")
52
+ end
53
+
54
+ def config_tmp_root
55
+ File.join(self.config_root, "tmp")
56
+ end
57
+
58
+ def framework_root_path
59
+ defined?(::WAKAME_FRAMEWORK_ROOT) ? ::WAKAME_FRAMEWORK_ROOT : "#{root_path}/vendor/wakame"
60
+ end
61
+
62
+ def framework_paths
63
+ paths = %w(lib)
64
+
65
+ paths.map{|dir| File.join(framework_root_path, dir) }.select{|path| File.directory?(path) }
66
+ end
67
+ #
68
+ class DefaultSet
69
+ def process(config)
70
+ end
71
+ end
72
+
73
+ class EC2 < DefaultSet
74
+ def process(config)
75
+ super(config)
76
+ config.config_root = File.join(config.root_path, 'tmp', 'config')
77
+
78
+ config.ssh_private_key = '/home/wakame/config/root.id_rsa'
79
+
80
+ end
81
+ end
82
+
83
+ class StandAlone < DefaultSet
84
+ def process(config)
85
+ super(config)
86
+ config.config_root = File.join(config.root_path, 'tmp', 'config')
87
+ config.amqp_server_uri = 'amqp://localhost/'
88
+ end
89
+ end
90
+
91
+ end
92
+
93
+ end
@@ -0,0 +1,96 @@
1
+
2
+
3
+ require 'daemons/daemonize'
4
+ require 'fileutils'
5
+
6
+ module Process
7
+ # Returns +true+ the process identied by +pid+ is running.
8
+ def running?(pid)
9
+ Process.getpgid(pid) != -1
10
+ rescue Errno::ESRCH
11
+ false
12
+ end
13
+ module_function :running?
14
+ end
15
+
16
+
17
+ module Wakame
18
+ module Daemonize
19
+ # Change privileges of the process
20
+ # to the specified user and group.
21
+ def change_privilege(user, group=user)
22
+ Wakame.log.info("Changing process privilege to #{user}:#{group}")
23
+
24
+ uid, gid = Process.euid, Process.egid
25
+ target_uid = Etc.getpwnam(user).uid
26
+ target_gid = Etc.getgrnam(group).gid
27
+
28
+ if uid != target_uid || gid != target_gid
29
+ if pid_file && File.exist?(pid_file) && uid == 0
30
+ File.chown(target_uid, target_gid, pid_file)
31
+ end
32
+
33
+ # Change process ownership
34
+ Process.initgroups(user, target_gid)
35
+ Process::GID.change_privilege(target_gid)
36
+ Process::UID.change_privilege(target_uid)
37
+ end
38
+ rescue Errno::EPERM => e
39
+ Wakame.log.error("Couldn't change user and group to #{user}:#{group}: #{e}")
40
+ end
41
+
42
+ def pid_file
43
+ @options[:pid_file]
44
+ end
45
+
46
+ def pid
47
+ File.exist?(pid_file) ? open(pid_file).read.to_i : nil
48
+ end
49
+
50
+ def setup_pidfile
51
+ #raise 'Please implement pid_file() method' unless respond_to? :pid_file
52
+
53
+ unless File.exist?(File.dirname(pid_file))
54
+ FileUtils.mkpath(File.dirname(pid_file))
55
+ end
56
+
57
+ open(pid_file, "w") { |f| f.write(Process.pid) }
58
+ File.chmod(0644, pid_file)
59
+ end
60
+
61
+ def daemonize(log_path)
62
+ # Cleanup stale pidfile or prevent from multiple process running.
63
+ if File.exist?(pid_file)
64
+ if pid && Process.running?(pid)
65
+ raise "#{pid_file} already exists, seems like it's already running (process ID: #{pid}). " +
66
+ "Stop the process or delete #{pid_file}."
67
+ else
68
+ Wakame.log.info "Deleting the stale PID file: #{pid_file}"
69
+ remove_pidfile
70
+ end
71
+ end
72
+
73
+ ::Daemonize.daemonize(log_path, File.basename($0.to_s))
74
+
75
+ setup_pidfile
76
+ #Signal.trap('HUP') {}
77
+ end
78
+
79
+ def on_restart(&blk)
80
+ @on_restart = blk
81
+ end
82
+
83
+ def restart
84
+ raise '' if @on_restart.nil?
85
+
86
+ @on_restart.call
87
+ end
88
+
89
+ def remove_pidfile
90
+ File.delete(pid_file) if pid_file && File.exists?(pid_file)
91
+ rescue => e
92
+ Wakame.log.error(e)
93
+ end
94
+
95
+ end
96
+ end
@@ -0,0 +1,232 @@
1
+ require 'wakame/util'
2
+
3
+ module Wakame
4
+ module Event
5
+ class Base
6
+ attr_accessor :time
7
+
8
+ def initialize
9
+ @time = Time.now
10
+ end
11
+
12
+ def log_message
13
+ end
14
+ end
15
+
16
+
17
+ class ClusterStatusChanged < Base
18
+ attr_reader :instance_id, :status
19
+ def initialize(instance_id, status)
20
+ super()
21
+ @instance_id = instance_id
22
+ @status = status
23
+ end
24
+
25
+ def log_message
26
+ "#{instance_id}, #{@status}"
27
+ end
28
+
29
+ end
30
+
31
+ class ServiceStatus < Base
32
+ attr_reader :instance_id, :property
33
+ def initialize(instance_id, property)
34
+ super()
35
+ @instance_id = instance_id
36
+ @property = property
37
+ end
38
+ end
39
+
40
+ class ServiceStatusChanged < ServiceStatus
41
+ attr_reader :status, :previous_status
42
+ def initialize(instance_id, property, new_status, prev_status)
43
+ super(instance_id, property)
44
+ @status = new_status
45
+ @previous_status = prev_status
46
+ end
47
+
48
+ def log_message
49
+ "#{instance_id}, #{@previous_status} -> #{@status}"
50
+ end
51
+ end
52
+
53
+ class ServiceOnline < ServiceStatus
54
+ end
55
+ class ServiceOffline < ServiceStatus
56
+ end
57
+ class ServiceFailed < ServiceStatus
58
+ attr_reader :message
59
+ def initialize(instance_id, property, message)
60
+ super(instance_id, property)
61
+ @message = message
62
+ end
63
+ end
64
+
65
+ class AgentEvent < Base
66
+ attr_reader :agent
67
+ def initialize(agent)
68
+ super()
69
+ @agent = agent
70
+ end
71
+ end
72
+
73
+ class AgentPong < AgentEvent
74
+ end
75
+
76
+ class AgentTimedOut < AgentEvent
77
+ end
78
+ class AgentMonitored < AgentEvent
79
+ end
80
+ class AgentUnMonitored < AgentEvent
81
+ end
82
+ class AgentStatusChanged < AgentEvent
83
+ end
84
+
85
+
86
+ class ServiceUnboundAgent < Base
87
+ attr_reader :service, :agent
88
+ def initialize(service, agent)
89
+ super()
90
+ @service = service
91
+ @agent = agent
92
+ end
93
+ end
94
+ class ServiceBoundAgent < Base
95
+ attr_reader :service, :agent
96
+ def initialize(service, agent)
97
+ super()
98
+ @service = service
99
+ @agent = agent
100
+ end
101
+ end
102
+
103
+ class ServiceBoundCluster < Base
104
+ attr_reader :service, :service_cluster
105
+ def initialize(svc_inst, cluster)
106
+ super()
107
+ @service = svc_inst
108
+ @service_cluster = cluster
109
+ end
110
+ end
111
+
112
+ class ServiceUnboundCluster < Base
113
+ attr_reader :service, :service_cluster
114
+ def initialize(svc_inst, cluster)
115
+ super()
116
+ @service = svc_inst
117
+ @service_cluster = cluster
118
+ end
119
+ end
120
+
121
+ class ServiceDestroied < Base
122
+ attr_reader :service
123
+ def initialize(svc_inst)
124
+ super()
125
+ @service = svc_inst
126
+ end
127
+ end
128
+
129
+ class ServicePropagated < Base
130
+ attr_reader :service
131
+ def initialize(svc_inst)
132
+ super()
133
+ @service = svc_inst
134
+ end
135
+ end
136
+
137
+ class CommandReceived < Base
138
+ attr_reader :command
139
+ def initialize(command)
140
+ @command = command
141
+ end
142
+ end
143
+
144
+ class ActionEvent < Base
145
+ attr_reader :action
146
+ def initialize(action)
147
+ super()
148
+ @action = action
149
+ end
150
+
151
+ def log_message
152
+ "#{@action.class}"
153
+ end
154
+
155
+ end
156
+
157
+ class ActionStart < ActionEvent
158
+ end
159
+ class ActionComplete < ActionEvent
160
+ end
161
+ class ActionFailed < ActionEvent
162
+ attr_reader :exception
163
+ def initialize(action, e)
164
+ super(action)
165
+ @exception = e
166
+ end
167
+ end
168
+
169
+ class JobEvent < Base
170
+ attr_reader :job_id
171
+ def initialize(job_id)
172
+ super()
173
+ @action = job_id
174
+ end
175
+
176
+ def log_message
177
+ "#{@action.class}"
178
+ end
179
+ end
180
+ class JobStart < JobEvent
181
+ end
182
+ class JobComplete < JobEvent
183
+ end
184
+ class JobFailed < JobEvent
185
+ attr_reader :exception
186
+ def initialize(job_id, e)
187
+ super(job_id)
188
+ @exception = e
189
+ end
190
+ end
191
+
192
+
193
+ class AgentShutdown < Base; end
194
+ class MasterShutdown < Base; end
195
+
196
+ class InstanceCountChanged < Base
197
+ attr_reader :resource, :prev_count, :count
198
+ def initialize(resource, prev_count, count)
199
+ @resource = resource
200
+ @prev_count = prev_count
201
+ @count = count
202
+ end
203
+
204
+ def increased?
205
+ @prev_count < @count
206
+ end
207
+
208
+ def decreased?
209
+ @prev_count > @count
210
+ end
211
+ end
212
+
213
+ class ActorProgress < Base
214
+ attr_reader :agent_id, :token, :progress
215
+ def initialize(agent_id, token, progress)
216
+ @agent_id = agent_id
217
+ @token = token
218
+ @progress = progress
219
+ end
220
+ end
221
+
222
+ class ActorComplete < Base
223
+ attr_reader :agent_id, :token, :status
224
+ def initialize(agent_id, token, status)
225
+ @agent_id = agent_id
226
+ @token = token
227
+ @status = status
228
+ end
229
+ end
230
+
231
+ end
232
+ end
@@ -0,0 +1,154 @@
1
+
2
+ module Wakame
3
+ class EventDispatcher
4
+ class << self
5
+
6
+ def instance
7
+ if @instance.nil?
8
+ @instance = self.new
9
+ end
10
+ @instance
11
+ end
12
+
13
+ def subscribe(event_class, *args, &blk)
14
+ self.instance.subscribe(event_class, *args, &blk)
15
+ end
16
+
17
+ def unsubscribe(event_class)
18
+ self.instance.unsubscribe(event_class)
19
+ end
20
+
21
+
22
+ def fire_event(event_obj)
23
+ self.instance.fire_event(event_obj)
24
+ end
25
+
26
+ def reset
27
+ @instance = nil
28
+ end
29
+
30
+ end
31
+
32
+ include ThreadImmutable
33
+
34
+ def initialize
35
+ @event_handlers = {}
36
+ @tickets = {}
37
+
38
+ @unsubscribe_queue = []
39
+ end
40
+
41
+ def subscribe(event_class, *args, &blk)
42
+ event_class = case event_class
43
+ when Class
44
+ event_class
45
+ when String
46
+ Util.str2const(event_class)
47
+ else
48
+ raise ArgumentError, "event_class has to be a form of String or Class type"
49
+ end
50
+
51
+ EM.barrier {
52
+ tlist = @event_handlers[event_class]
53
+ if tlist.nil?
54
+ tlist = @event_handlers[event_class] = []
55
+ end
56
+
57
+ tickets = []
58
+ args.each { |o|
59
+ tickets << Util.gen_id
60
+ @tickets.store(tickets.last, [event_class, o])
61
+ tlist << tickets.last
62
+ }
63
+
64
+ if blk
65
+ tickets << Util.gen_id
66
+ @tickets.store(tickets.last, [event_class, blk])
67
+ tlist << tickets.last
68
+ end
69
+
70
+ # Return in array if num of ticket to be returned is more than or equal 2.
71
+ tickets.size > 1 ? tickets : tickets.first
72
+ }
73
+ end
74
+
75
+ def unsubscribe(ticket)
76
+ unless @tickets.has_key?(ticket)
77
+ #Wakame.log.warn("EventHander.unsubscribe(#{ticket}) has been tried but the ticket was not registered.")
78
+ return nil
79
+ end
80
+
81
+ EM.barrier {
82
+ Wakame.log.debug("#{self.class}.unsubscribe(#{ticket})")
83
+
84
+ @unsubscribe_queue << ticket
85
+ ticket
86
+ }
87
+ end
88
+
89
+ def fire_event(event_obj)
90
+ raise ArgumentError unless event_obj.is_a?(Event::Base)
91
+ log_msg = ""
92
+ log_msg = " #{event_obj.log_message}" unless event_obj.log_message.nil?
93
+
94
+ Wakame.log.debug("Event #{event_obj.class} has been fired:" + log_msg )
95
+ tlist = @event_handlers[event_obj.class]
96
+ return if tlist.nil?
97
+
98
+ run_callbacks = proc {
99
+ @unsubscribe_queue.each { |t|
100
+ @tickets.delete(t)
101
+ tlist.delete(t)
102
+ }
103
+
104
+ tlist.each { |t|
105
+ ary = @tickets[t]
106
+ c = ary[1]
107
+ if c.nil?
108
+ next
109
+ end
110
+
111
+ begin
112
+ c.call(event_obj)
113
+ rescue => e
114
+ Wakame.log.error(e)
115
+ #raise e
116
+ end
117
+ }
118
+
119
+ @unsubscribe_queue.each { |t|
120
+ @tickets.delete(t)
121
+ tlist.delete(t)
122
+ }
123
+ }
124
+
125
+ #@handler_run_queue.push(run_handlers)
126
+
127
+ ::EventMachine.barrier {
128
+ begin
129
+ run_callbacks.call
130
+ rescue => e
131
+ Wakame.log.error(e)
132
+ end
133
+ }
134
+ end
135
+
136
+ def reset(event_class=nil)
137
+ if event_class.nil?
138
+ @event_handlers.clear
139
+ @tickets.clear
140
+ else
141
+ unless @event_handlers[event_class.to_s].nil?
142
+ @event_handlers[event_class.to_s].each_key { |k|
143
+ @tickets.delete(k)
144
+ }
145
+ @event_handlers[event_class.to_s].clear
146
+ end
147
+ end
148
+ end
149
+ thread_immutable_methods :reset
150
+
151
+ end
152
+
153
+ ED = EventDispatcher
154
+ end