pomelo-citrus 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +20 -0
  3. data/Rakefile +0 -0
  4. data/citrus.gemspec +35 -0
  5. data/lib/citrus.rb +18 -0
  6. data/lib/citrus/application.rb +237 -0
  7. data/lib/citrus/citrus.rb +27 -0
  8. data/lib/citrus/common/remote/backend/msg_remote.rb +57 -0
  9. data/lib/citrus/common/remote/frontend/channel_remote.rb +73 -0
  10. data/lib/citrus/common/remote/frontend/session_remote.rb +108 -0
  11. data/lib/citrus/common/service/backend_session_service.rb +265 -0
  12. data/lib/citrus/common/service/channel_service.rb +485 -0
  13. data/lib/citrus/common/service/connection_service.rb +71 -0
  14. data/lib/citrus/common/service/filter_service.rb +92 -0
  15. data/lib/citrus/common/service/handler_service.rb +63 -0
  16. data/lib/citrus/common/service/session_service.rb +446 -0
  17. data/lib/citrus/components/backend_session.rb +32 -0
  18. data/lib/citrus/components/channel.rb +33 -0
  19. data/lib/citrus/components/component.rb +19 -0
  20. data/lib/citrus/components/connection.rb +48 -0
  21. data/lib/citrus/components/connector.rb +265 -0
  22. data/lib/citrus/components/master.rb +40 -0
  23. data/lib/citrus/components/monitor.rb +48 -0
  24. data/lib/citrus/components/proxy.rb +195 -0
  25. data/lib/citrus/components/push_scheduler.rb +74 -0
  26. data/lib/citrus/components/remote.rb +71 -0
  27. data/lib/citrus/components/server.rb +61 -0
  28. data/lib/citrus/components/session.rb +41 -0
  29. data/lib/citrus/connectors/commands/handshake.rb +22 -0
  30. data/lib/citrus/connectors/commands/heartbeat.rb +22 -0
  31. data/lib/citrus/connectors/commands/kick.rb +22 -0
  32. data/lib/citrus/connectors/common/coder.rb +21 -0
  33. data/lib/citrus/connectors/common/handler.rb +21 -0
  34. data/lib/citrus/connectors/ws_connector.rb +110 -0
  35. data/lib/citrus/connectors/ws_socket.rb +75 -0
  36. data/lib/citrus/filters/handler/handler_filter.rb +19 -0
  37. data/lib/citrus/filters/handler/too_busy.rb +16 -0
  38. data/lib/citrus/filters/rpc/rpc_filter.rb +19 -0
  39. data/lib/citrus/filters/rpc/too_busy.rb +16 -0
  40. data/lib/citrus/master/master.rb +60 -0
  41. data/lib/citrus/master/starter.rb +73 -0
  42. data/lib/citrus/master/watchdog.rb +83 -0
  43. data/lib/citrus/modules/console.rb +45 -0
  44. data/lib/citrus/modules/console_module.rb +35 -0
  45. data/lib/citrus/modules/master_watcher.rb +88 -0
  46. data/lib/citrus/modules/monitor_watcher.rb +86 -0
  47. data/lib/citrus/monitor/monitor.rb +61 -0
  48. data/lib/citrus/push_schedulers/buffer.rb +16 -0
  49. data/lib/citrus/push_schedulers/direct.rb +76 -0
  50. data/lib/citrus/server/server.rb +327 -0
  51. data/lib/citrus/util/app_util.rb +203 -0
  52. data/lib/citrus/util/constants.rb +19 -0
  53. data/lib/citrus/util/countdown_latch.rb +42 -0
  54. data/lib/citrus/util/events.rb +14 -0
  55. data/lib/citrus/util/module_util.rb +68 -0
  56. data/lib/citrus/util/path_util.rb +50 -0
  57. data/lib/citrus/util/utils.rb +49 -0
  58. data/lib/citrus/version.rb +7 -0
  59. metadata +241 -0
@@ -0,0 +1,195 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 20 July 2014
4
+
5
+ require 'digest/crc32'
6
+ require 'citrus/components/component'
7
+ require 'citrus/util/path_util'
8
+
9
+ module Citrus
10
+ # Components
11
+ #
12
+ #
13
+ module Components
14
+ # Proxy
15
+ #
16
+ #
17
+ class Proxy < Component
18
+ @name = 'proxy'
19
+
20
+ include Utils::PathUtil
21
+
22
+ # Initialize the component
23
+ #
24
+ # @param [Object] app
25
+ # @param [Hash] args
26
+ def initialize app, args={}
27
+ args[:buffer_msg] = args[:buffer_msg] || false
28
+ args[:interval] = args[:interval] || 0.03
29
+
30
+ args[:router] = gen_router
31
+ args[:context] = app
32
+ args[:route_context] = app
33
+
34
+ @args = args
35
+ @client = CitrusRpc::RpcClient::Client.new @args
36
+
37
+ @app = app
38
+ @app.on(:add_servers) { |servers| add_servers servers }
39
+ @app.on(:remove_servers) { |ids| remove_servers ids }
40
+ @app.on(:replace_servers) { |servers| replace_servers servers }
41
+ end
42
+
43
+ # Start the component
44
+ def start &block
45
+ unless @app.rpc_befores.empty?
46
+ @client.before @app.rpc_befores
47
+ end
48
+
49
+ unless @app.rpc_afters.empty?
50
+ @client.after @app.rpc_afters
51
+ end
52
+
53
+ if @app.rpc_error_handler
54
+ @client.set_error_handler @app.rpc_error_handler
55
+ end
56
+
57
+ EM.next_tick { block_given? and yield }
58
+ end
59
+
60
+ # Component lifecycle callback
61
+ def after_start &block
62
+ @app.rpc = @client.proxies.user
63
+ @app.sysrpc = @client.proxies.sys
64
+
65
+ @app.define_singleton_method :rpc_invoke, proc{ |*args, &block|
66
+ @client.rpc_invoke *args, &block
67
+ }
68
+
69
+ @client.start &block
70
+ end
71
+
72
+ # Add remote servers
73
+ #
74
+ # @param [Array] servers
75
+ def add_servers servers
76
+ return unless servers
77
+ return if servers.empty
78
+
79
+ gen_proxies servers
80
+
81
+ @client.add_servers servers
82
+ end
83
+
84
+ # Remove remote servers
85
+ #
86
+ # @param [Array] ids
87
+ def remove_servers ids
88
+ @client.remove_servers ids
89
+ end
90
+
91
+ # Replace remote servers
92
+ #
93
+ # @param [Array] servers
94
+ def replace_servers servers
95
+ return unless servers
96
+ return if servers.empty
97
+
98
+ @client.proxies = {}
99
+ gen_proxies servers
100
+
101
+ @client.replace_servers servers
102
+ end
103
+
104
+ # Proxy for rpc client's rpc_invoke
105
+ #
106
+ # @param [String] server_id
107
+ # @param [Hash] msg
108
+ def rpc_invoke server_id, msg, &block
109
+ @client.rpc_invoke server_id, msg, &block
110
+ end
111
+
112
+ private
113
+
114
+ # Generate proxies for the server infos
115
+ #
116
+ # @param [Array] sinfos
117
+ #
118
+ # @private
119
+ def gen_proxies sinfos
120
+ sinfos.each { |sinfo|
121
+ @client.add_proxies get_proxy_records(sinfo) unless has_proxy? sinfo
122
+ }
123
+ end
124
+
125
+ # Check whether a proxy has been generated
126
+ #
127
+ # @param [Hash] sinfo
128
+ #
129
+ # @private
130
+ def has_proxy? sinfo
131
+ @client.proxies.sys && @client.proxies.sys.respond_to? sinfo[:server_type]
132
+ end
133
+
134
+ # Get proxy path for rpc client
135
+ #
136
+ # @param [Hash] sinfo
137
+ #
138
+ # @private
139
+ def get_proxy_records sinfo
140
+ records = []
141
+
142
+ role = @app.frontend? sinfo ? :frontend : :backend
143
+ server_type = sinfo[:server_type]
144
+
145
+ record = get_sys_remote_path role
146
+ records << remote_path_record('sys', server_type, record) if record
147
+
148
+ record = get_user_remote_path @app.base, server_type
149
+ records << remote_path_record('user', server_type, record) if record
150
+
151
+ records
152
+ end
153
+
154
+ # Generate router
155
+ #
156
+ # @private
157
+ def gen_router
158
+ Proc.new { |session, msg, &block|
159
+ routers = @app.routers
160
+ unless routers
161
+ default_router session, msg, &block
162
+ return
163
+ end
164
+
165
+ type = msg['server_type']
166
+ router = routers[type] || routers['default']
167
+
168
+ if router
169
+ router.call session, msg, &block
170
+ else
171
+ default_router session, msg, &block
172
+ end
173
+ }
174
+ end
175
+
176
+ # Default router
177
+ #
178
+ # @param [Object] session
179
+ # @param [Hash] msg
180
+ #
181
+ # @private
182
+ def default_router session, msg, &block
183
+ list = @app.get_servers_by_type msg['server_type']
184
+ unless list && !list.empty?
185
+ block_given? and yield Exception.new 'can not find server info for type: ' + msg['server_type']
186
+ return
187
+ end
188
+
189
+ uid = session ? (session.uid || '') : ''
190
+ idx = (Digest::CRC32.hexdigest uid).to_i % list.length
191
+ block_given? and yield nil, list[idx][:server_id]
192
+ end
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,74 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 17 July 2014
4
+
5
+ require 'citrus/components/component'
6
+ require 'citrus/push_schedulers/direct'
7
+
8
+ module Citrus
9
+ # Components
10
+ #
11
+ #
12
+ module Components
13
+ # PushScheduler
14
+ #
15
+ #
16
+ class PushScheduler < Component
17
+ @name = 'push_scheduler'
18
+
19
+ # Initialize the component
20
+ #
21
+ # @param [Object] app
22
+ # @param [Hash] args
23
+ def initialize app, args={}
24
+ @app = app
25
+ @scheduler = get_scheduler app, args
26
+ end
27
+
28
+ # Component lifecycle callback
29
+ def after_start &block
30
+ if @scheduler.respond_to? :start
31
+ @scheduler.start &block
32
+ else
33
+ EM.next_tick { block.call } if block_given?
34
+ end
35
+ end
36
+
37
+ # Component lifecycle callback
38
+ def stop &block
39
+ if @scheduler.respond_to? :stop
40
+ @scheduler.stop &block
41
+ else
42
+ EM.next_tick { block.call } if block_given?
43
+ end
44
+ end
45
+
46
+ # Schedule how the message to send
47
+ #
48
+ # @param [Integer] req_id
49
+ # @param [String] route
50
+ # @param [Hash] msg
51
+ # @param [Array] recvs
52
+ # @param [Hash] args
53
+ def schedule req_id, route, msg, recvs, args, &block
54
+ if @scheculer.respond_to? :schedule
55
+ @scheduler.schedule req_id, route, msg, recvs, args, &block
56
+ else
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ # Get scheduler
63
+ #
64
+ # @param [Object] app
65
+ # @param [Hash] args
66
+ #
67
+ # @private
68
+ def get_scheduler app, args={}
69
+ scheduler = args[:scheduler] || Citrus::PushSchedulers::Direct
70
+ scheduler.new app, args
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,71 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 17 July 2014
4
+
5
+ require 'citrus/components/component'
6
+ require 'citrus/util/path_util'
7
+
8
+ module Citrus
9
+ # Components
10
+ #
11
+ #
12
+ module Components
13
+ # Remote
14
+ #
15
+ #
16
+ class Remote < Component
17
+ @name = 'remote'
18
+
19
+ include Utils::PathUtil
20
+
21
+ # Initialize the component
22
+ #
23
+ # @param [Object] app
24
+ # @param [Hash] args
25
+ def initialize app, args={}
26
+ args[:buffer_msg] = args[:buffer_msg] || false
27
+ args[:interval] = args[:interval] || 0.03
28
+ @app = app
29
+ @args = args
30
+ end
31
+
32
+ # Start the component
33
+ def start &block
34
+ @args[:port] = @app.cur_server[:port]
35
+ @args[:paths] = get_remote_paths
36
+ @args[:context] = @app
37
+
38
+ @remote = CitrusRpc::RpcServer::Server.new @args
39
+ @remote.start
40
+
41
+ EM.next_tick { block_given? and yield }
42
+ end
43
+
44
+ # Stop the component
45
+ #
46
+ # @param [Boolean] force
47
+ def stop force=false, &block
48
+ @remote.stop force
49
+ EM.next_tick { block_given? and yield }
50
+ end
51
+
52
+ private
53
+
54
+ # Get remote paths
55
+ def get_remote_paths
56
+ paths = []
57
+
58
+ role = @app.frontend? sinfo ? :frontend : :backend
59
+ server_type = sinfo[:server_type]
60
+
61
+ sys_path = get_sys_remote_path role
62
+ paths << remote_path_record('sys', server_type, sys_path) if sys_path
63
+
64
+ user_path = get_user_remote_path @app.base, server_type
65
+ paths << remote_path_record('user', server_type, user_path) if user_path
66
+
67
+ paths
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,61 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 17 July 2014
4
+
5
+ require 'citrus/components/component'
6
+ require 'citrus/server/server'
7
+
8
+ module Citrus
9
+ # Components
10
+ #
11
+ #
12
+ module Components
13
+ # Server
14
+ #
15
+ #
16
+ class Server < Component
17
+ @name = 'server'
18
+
19
+ # Initialize the component
20
+ #
21
+ # @param [Object] app
22
+ def initialize app
23
+ @server = Citrus::Server::Server.new app
24
+ end
25
+
26
+ # Start the component
27
+ def start &block
28
+ @server.start
29
+ EM.next_tick { block_given? and yield }
30
+ end
31
+
32
+ # Component lifecycle callback
33
+ def after_start &block
34
+ @server.after_start
35
+ EM.next_tick { block_given? and yield }
36
+ end
37
+
38
+ # Stop the component
39
+ def stop force=false, &block
40
+ @server.stop
41
+ EM.next_tick { block_given? and yield }
42
+ end
43
+
44
+ # Proxy server handle
45
+ #
46
+ # @param [Hash] msg
47
+ # @param [Object] session
48
+ def handle msg, session, &block
49
+ @server.handle msg, session, &block
50
+ end
51
+
52
+ # Proxy server global handle
53
+ #
54
+ # @param [Hash] msg
55
+ # @param [Object] session
56
+ def global_handle msg, session, &block
57
+ @server.global_handle msg, session, &block
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,41 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 17 July 2014
4
+
5
+ require 'citrus/components/component'
6
+ require 'citrus/common/service/session_service'
7
+
8
+ module Citrus
9
+ # Components
10
+ #
11
+ #
12
+ module Components
13
+ # Session
14
+ #
15
+ #
16
+ class Session < Component
17
+ @name = 'session'
18
+
19
+ attr_reader :service
20
+
21
+ # Initialize the component
22
+ #
23
+ # @param [Object] app
24
+ # @param [Hash] args
25
+ def initialize app, args={}
26
+ @app = app
27
+ @service = Common::Service::SessionService.new args
28
+
29
+ this = self
30
+ @app.define_singleton_method :session_service, proc{ this }
31
+ end
32
+
33
+ # Proxy for connection service
34
+ #
35
+ # @param [String] name
36
+ def method_missing name, *args, &block
37
+ @service.send name, *args, &block
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,22 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 25 July 2014
4
+
5
+ module Citrus
6
+ # Connectors
7
+ #
8
+ #
9
+ module Connectors
10
+ # Commands
11
+ #
12
+ #
13
+ module Commands
14
+ # HandShake
15
+ #
16
+ #
17
+ class HandShake
18
+
19
+ end
20
+ end
21
+ end
22
+ end