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,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
+ # HeartBeat
15
+ #
16
+ #
17
+ class HeartBeat
18
+
19
+ end
20
+ end
21
+ end
22
+ 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
+ # Kick
15
+ #
16
+ #
17
+ class Kick
18
+
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
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
+ # Common
11
+ #
12
+ #
13
+ module Common
14
+ # Coder
15
+ #
16
+ #
17
+ module Coder
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
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
+ # Common
11
+ #
12
+ #
13
+ module Common
14
+ # Handler
15
+ #
16
+ #
17
+ module Handler
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,110 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 25 July 2014
4
+
5
+ require 'json'
6
+ require 'websocket-eventmachine-server'
7
+ require 'citrus/connectors/ws_socket'
8
+
9
+ module Citrus
10
+ # Connectors
11
+ #
12
+ #
13
+ module Connectors
14
+ # WsConnector
15
+ #
16
+ #
17
+ class WsConnector
18
+ include Utils::EventEmitter
19
+
20
+ # Create a new websocket connector
21
+ #
22
+ # @param [Integer] port
23
+ # @param [String] host
24
+ # @param [Hash] args
25
+ def initialize port, host, args={}
26
+ @port = port
27
+ @host = host
28
+ @args = args
29
+
30
+ @heartbeats = args[:heartbeats] || true
31
+ @heartbeat_timeout = args[:heartbeat_timeout] || 0.06
32
+ @heartbeat_interval = args[:heartbeat_interval] || 0.025
33
+
34
+ @cur_id = 0
35
+ end
36
+
37
+ # Start the connector to listen to the specified port
38
+ def start &block
39
+ begin
40
+ @server = WebSocket::EventMachine::Server.start(:host => @host, :port => @port) { |ws|
41
+ ws.onopen {
42
+ ws_socket = WsSocket.new @cur_id, ws
43
+ @cur_id += 1
44
+ emit :connection, ws_socket
45
+ ws_socket.on(:closing) { |reason|
46
+ ws_socket.send({ 'route' => 'on_kick', 'reason' => reason })
47
+ }
48
+ }
49
+ }
50
+ rescue => err
51
+ end
52
+ EM.next_tick { block_given? and yield }
53
+ end
54
+
55
+ # Stop the connector
56
+ #
57
+ # @param [Boolean] force
58
+ def stop force=false, &block
59
+ @server.close
60
+ EM.next_tick { block_given? and yield }
61
+ end
62
+
63
+ # Encode message
64
+ #
65
+ # @param [Integer, NilClass] req_id
66
+ # @param [String] route
67
+ # @param [Object] msg
68
+ def encode req_id, route, msg
69
+ if req_id
70
+ compose_response req_id, route, msg
71
+ else
72
+ componse_push route, msg
73
+ end
74
+ end
75
+
76
+ # Decode message
77
+ #
78
+ # @param [String] msg
79
+ def decode msg
80
+ begin
81
+ JSON.parse msg
82
+ rescue => err
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ # Compose response message
89
+ #
90
+ # @param [Integer] msg_id
91
+ # @param [String] route
92
+ # @param [Hash] msg_body
93
+ #
94
+ # @private
95
+ def compose_response msg_id, route, msg_body
96
+ { 'id' => msg_id, 'body' => msg_body }
97
+ end
98
+
99
+ # Compose push message
100
+ #
101
+ # @param [String] route
102
+ # @param [Hash] msg_body
103
+ #
104
+ # @private
105
+ def compose_push route, msg_body
106
+ { 'route' => route, 'body' => msg_body }
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,75 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 25 July 2014
4
+
5
+ require 'json'
6
+
7
+ module Citrus
8
+ # Connectors
9
+ #
10
+ #
11
+ module Connectors
12
+ # WsSocket
13
+ #
14
+ #
15
+ class WsSocket
16
+ include Utils::EventEmitter
17
+
18
+ attr_reader :id, :remote_address
19
+
20
+ # Create a new ws socket
21
+ #
22
+ # @param [Integer] id
23
+ # @param [Object] ws
24
+ def initialize id, ws
25
+ @id = id
26
+ @ws = ws
27
+
28
+ port, ip = Socket.unpack_sockaddr_in @ws.get_peername
29
+ @remote_address = {
30
+ :port => port,
31
+ :ip => ip
32
+ }
33
+
34
+ @ws.onclose { emit :disconnect }
35
+ @ws.onerror { |err| emit :error }
36
+ @ws.onmessage { |msg, type| emit :message, msg }
37
+
38
+ @state = :state_inited
39
+ end
40
+
41
+ # Send message to the client
42
+ #
43
+ # @param [Hash] msg
44
+ def send msg
45
+ return unless @state == :state_inited
46
+ @ws.send msg.to_json
47
+ end
48
+
49
+ # Disconnect the client
50
+ def disconnect
51
+ return if @state == :state_closed
52
+ @state = :state_closed
53
+ @ws.close
54
+ end
55
+
56
+ # Batch version for send
57
+ #
58
+ # @param [Array] msgs
59
+ def send_batch msgs
60
+ @ws.send encode_batch(msgs)
61
+ end
62
+
63
+ private
64
+
65
+ # Encode batch messages
66
+ #
67
+ # @param [Array] msgs
68
+ #
69
+ # @private
70
+ def encode_batch msgs
71
+ msgs.to_json
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,19 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 21 July 2014
4
+
5
+ module Citrus
6
+ # HandlerFilter
7
+ #
8
+ #
9
+ class HandlerFilter
10
+ attr_accessor :name
11
+
12
+ #
13
+ #
14
+ #
15
+ def initialize
16
+ @name = ''
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 17 July 2014
4
+
5
+ require 'citrus/filters/handler/handler_filter'
6
+
7
+ module Citrus
8
+ # TooBusy
9
+ #
10
+ #
11
+ class TooBusy < HandlerFilter
12
+ def initialize
13
+ @name = 'too_busy'
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 21 July 2014
4
+
5
+ module Citrus
6
+ # RpcFilter
7
+ #
8
+ #
9
+ class RpcFilter
10
+ attr_accessor :name
11
+
12
+ #
13
+ #
14
+ #
15
+ def initialize
16
+ @name = ''
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 17 July 2014
4
+
5
+ require 'citrus/filters/rpc/rpc_filter'
6
+
7
+ module Citrus
8
+ # TooBusy
9
+ #
10
+ #
11
+ class TooBusy < RpcFilter
12
+ def initialize
13
+ @name = 'too_busy'
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,60 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 18 July 2014
4
+
5
+ require 'citrus/master/starter'
6
+ require 'citrus/util/module_util'
7
+
8
+ module Citrus
9
+ # Master
10
+ #
11
+ #
12
+ module Master
13
+ # Master
14
+ #
15
+ #
16
+ class Master
17
+ include Starter
18
+ include Utils::ModuleUtil
19
+
20
+ # Create a new master
21
+ #
22
+ # @param [Object] app
23
+ # @param [Hash] args
24
+ def initialize app, args={}
25
+ @app = app
26
+ @master = true
27
+ @master_info = app.master
28
+ @modules = []
29
+ @close_watcher = args[:close_watcher]
30
+ @console_service = CitrusAdmin::ConsoleService.create_master_console(
31
+ args.merge({
32
+ :env => app.env,
33
+ :port => @master_info[:port]
34
+ })
35
+ )
36
+ end
37
+
38
+ # Start master
39
+ def start &block
40
+ register_default_modules
41
+ load_modules
42
+ @console_service.start { |err|
43
+ exit if err
44
+ start_modules { |err|
45
+ if err
46
+ block_given? and yield err
47
+ return
48
+ end
49
+ run_servers
50
+ block_given? and yield
51
+ }
52
+ }
53
+ end
54
+
55
+ # Stop master
56
+ def stop &block
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,73 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 19 July 2014
4
+
5
+ module Citrus
6
+ # Master
7
+ #
8
+ #
9
+ module Master
10
+ # Starter
11
+ #
12
+ #
13
+ module Starter
14
+ include Utils
15
+
16
+ # Run servers
17
+ def run_servers
18
+ condition = @app.start_id || @app.type
19
+ case condition
20
+ when :master
21
+ when :all
22
+ @app.servers_map.each { |server_id, server|
23
+ run_server server
24
+ }
25
+ else
26
+ end
27
+ end
28
+
29
+ # Run server
30
+ #
31
+ # @param [Hash] server
32
+ def run_server server, &block
33
+ if local? server[:host]
34
+ options = []
35
+ options << sprintf('%s', $0)
36
+ options << sprintf('env=%s', @app.env)
37
+ server.each { |key, value|
38
+ options << sprintf('%s=%s', key, value)
39
+ }
40
+ local_run 'ruby', nil, options
41
+ else
42
+ end
43
+ end
44
+
45
+ #
46
+ #
47
+ #
48
+ def ssh_run
49
+ end
50
+
51
+ #
52
+ #
53
+ #
54
+ def local_run cmd, host, options
55
+ spawn_process cmd, host, options
56
+ end
57
+
58
+ #
59
+ #
60
+ #
61
+ def spawn_process cmd, host, options
62
+ child = fork {
63
+ exec cmd + options.inject('') { |res, str| res += ' ' + str }
64
+ }
65
+ EM.watch_process child, Module.new {
66
+ define_method(:process_exited) {
67
+ Process.wait child
68
+ }
69
+ }
70
+ end
71
+ end
72
+ end
73
+ end