pomelo-citrus 0.0.1

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 (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