rakie 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 95d75f7ea14d2462c94b21bd025f17e5150075e295dd1dc9f927efb08826c424
4
+ data.tar.gz: 2642f719d6ae1427e99efc89b3d841fe7c7471f5cfd2da0597ad4df89d347b0e
5
+ SHA512:
6
+ metadata.gz: ae10ff4d934dac0f08a066d2809930132b736e4cb4bda7f7cf25f30cc48f7554b4b474e8ee7cbb7fcd57b7b4e75157d9a592ff9a8351f3d9fbee431b4006e944
7
+ data.tar.gz: 287525054ef601031d860c7a8b75b1985e91d7430cee7b489b7fb726c06cbe15223c3ebd63cad3fbdf590793d3cb343dbfc0a6890cba89a9cbf6b632541ab6a2
data/Rakefile ADDED
File without changes
@@ -0,0 +1,121 @@
1
+ module Rakie
2
+ class Channel
3
+ attr_accessor :delegate
4
+
5
+ def initialize(io, delegate=nil)
6
+ @io = io
7
+ @read_buffer = String.new
8
+ @write_buffer = String.new
9
+ @delegate = delegate
10
+ Event.push(io, self, Event::READ_EVENT)
11
+ end
12
+
13
+ def on_read(io)
14
+ begin
15
+ loop do
16
+ @read_buffer << io.read_nonblock(4096)
17
+ end
18
+
19
+ rescue IO::EAGAINWaitReadable
20
+ puts("Channel read finished")
21
+
22
+ rescue
23
+ # Process the last message on exception
24
+ if @delegate != nil
25
+ @delegate.on_recv(self, @read_buffer)
26
+ @read_buffer = String.new # Reset buffer
27
+ end
28
+
29
+ puts("Channel error #{io}")
30
+ return Event::HANDLE_FAILED
31
+ end
32
+
33
+ puts("Channel has delegate?: #{@delegate}")
34
+ if @delegate != nil
35
+ len = @delegate.on_recv(self, @read_buffer)
36
+
37
+ if len > @read_buffer.length
38
+ len = @read_buffer.length
39
+ end
40
+
41
+ @read_buffer = @read_buffer[len .. -1]
42
+ puts("Channel handle on_recv")
43
+ end
44
+
45
+ return Event::HANDLE_CONTINUED
46
+ end
47
+
48
+ def on_write(io)
49
+ begin
50
+ while @write_buffer.length > 0
51
+ len = io.write_nonblock(@write_buffer)
52
+ @write_buffer = @write_buffer[len .. -1]
53
+ end
54
+
55
+ puts("Channel write finished")
56
+
57
+ rescue IO::EAGAINWaitWritable
58
+ puts("Channel write continue")
59
+ return Event::HANDLE_CONTINUED
60
+
61
+ rescue
62
+ puts("Channel close #{io}")
63
+ return Event::HANDLE_FAILED
64
+ end
65
+
66
+ return Event::HANDLE_FINISHED
67
+ end
68
+
69
+ def on_close(io)
70
+ begin
71
+ io.close
72
+
73
+ rescue
74
+ puts("Channel is already closed")
75
+ end
76
+ end
77
+
78
+ def read(size)
79
+ if self.eof?
80
+ return ""
81
+ end
82
+
83
+ if size > data.length
84
+ size = data.length
85
+ end
86
+
87
+ data = @read_buffer[0 .. (size - 1)]
88
+ @read_buffer = @read_buffer[size .. -1]
89
+
90
+ return data
91
+ end
92
+
93
+ def write(data)
94
+ if @io.closed?
95
+ return -1
96
+ end
97
+
98
+ @write_buffer << data
99
+ Event.modify(@io, self, Event::READ_EVENT | Event::WRITE_EVENT)
100
+
101
+ return 0
102
+ end
103
+
104
+ def close
105
+ if @io.closed?
106
+ return nil
107
+ end
108
+
109
+ Event.delete(@io)
110
+ return nil
111
+ end
112
+
113
+ def eof?
114
+ @read_buffer.empty?
115
+ end
116
+
117
+ def closed?
118
+ @io.closed?
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,170 @@
1
+ module Rakie
2
+ class Event
3
+ @instance = nil
4
+
5
+ READ_EVENT = 1
6
+ WRITE_EVENT = 2
7
+
8
+ HANDLE_FAILED = -1
9
+ HANDLE_CONTINUED = 0
10
+ HANDLE_FINISHED = 1
11
+
12
+ def initialize
13
+ @wait_ios = []
14
+ @lock = Mutex.new
15
+ @signal_in, @signal_out = IO.pipe
16
+ @ios = {
17
+ @signal_in => READ_EVENT
18
+ }
19
+ @handlers = {}
20
+ @run_loop = Thread.new do
21
+ self.run_loop
22
+ end
23
+ end
24
+
25
+ def process_signal(io)
26
+ signal = io.read(1)
27
+ puts("Event handling #{signal}")
28
+
29
+ if signal == 'a'
30
+ new_io, new_handler, new_event = @wait_ios.shift
31
+ @ios[new_io] = new_event
32
+ @handlers[new_io] = new_handler
33
+ puts("Event add all #{new_io} to #{new_event}")
34
+
35
+ elsif signal == 'd'
36
+ new_io, = @wait_ios.shift
37
+ handler = @handlers[new_io]
38
+
39
+ if handler != nil
40
+ handler.on_close(new_io)
41
+ puts("Event close #{new_io}")
42
+ end
43
+
44
+ @ios.delete(new_io)
45
+ @handlers.delete(new_io)
46
+
47
+ puts("Event remove all #{new_io}")
48
+
49
+ elsif signal == 'm'
50
+ new_io, new_handler, new_event = @wait_ios.shift
51
+ @ios[new_io] = new_event
52
+ @handlers[new_io] = new_handler
53
+ puts("Event modify all #{new_io} to #{new_event}")
54
+
55
+ elsif signal == 'q'
56
+ return 1
57
+ end
58
+
59
+ return 0
60
+ end
61
+
62
+ def run_loop
63
+ loop do
64
+ read_ios = @ios.select {|k, v| v & READ_EVENT > 0}
65
+ write_ios = @ios.select {|k, v| v & WRITE_EVENT > 0}
66
+
67
+ read_ready, write_ready = IO.select(read_ios.keys, write_ios.keys, [], 5)
68
+
69
+ if read_ready != nil
70
+ read_ready.each do |io|
71
+ if io == @signal_in
72
+ @lock.lock
73
+
74
+ if self.process_signal(io) != 0
75
+ @lock.unlock
76
+ return
77
+ end
78
+
79
+ @lock.unlock
80
+ next
81
+ end
82
+
83
+ handler = @handlers[io]
84
+
85
+ if handler == nil
86
+ next
87
+ end
88
+
89
+ result = handler.on_read(io)
90
+
91
+ if result == HANDLE_FINISHED
92
+ @ios[io] = @ios[io] & ~READ_EVENT
93
+ puts("Event remove read #{io}")
94
+
95
+ elsif result == HANDLE_FAILED
96
+ handler.on_close(io)
97
+ puts("Event close #{io}")
98
+
99
+ @ios.delete(io)
100
+ @handlers.delete(io)
101
+ puts("Event remove all #{io}")
102
+ end
103
+ end
104
+ end
105
+
106
+ if write_ready != nil
107
+ write_ready.each do |io|
108
+ handler = @handlers[io]
109
+
110
+ if handler == nil
111
+ next
112
+ end
113
+
114
+ result = handler.on_write(io)
115
+
116
+ if result == HANDLE_FINISHED
117
+ @ios[io] = @ios[io] & ~WRITE_EVENT
118
+ puts("Event remove write #{io}")
119
+
120
+ elsif result == HANDLE_FAILED
121
+ handler.on_close(io)
122
+ puts("Event close #{io}")
123
+
124
+ @ios.delete(io)
125
+ @handlers.delete(io)
126
+ puts("Event remove all #{io}")
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ def push(io, handler, event)
134
+ @lock.lock
135
+ @wait_ios.push([io, handler, event])
136
+ @signal_out.write('a')
137
+ @lock.unlock
138
+ end
139
+
140
+ def delete(io)
141
+ @lock.lock
142
+ @wait_ios.push([io, nil, nil])
143
+ @signal_out.write('d')
144
+ @lock.unlock
145
+ end
146
+
147
+ def modify(io, handler, event)
148
+ @lock.lock
149
+ @wait_ios.push([io, handler, event])
150
+ @signal_out.write('m')
151
+ @lock.unlock
152
+ end
153
+
154
+ def self.instance
155
+ @instance ||= Event.new
156
+ end
157
+
158
+ def self.push(io, listener, type)
159
+ self.instance.push(io, listener, type)
160
+ end
161
+
162
+ def self.delete(io)
163
+ self.instance.delete(io)
164
+ end
165
+
166
+ def self.modify(io, listener, type)
167
+ self.instance.modify(io, listener, type)
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,149 @@
1
+ module Rakie
2
+ class SimpleServer
3
+ PARSE_ERROR = -1
4
+ PARSE_OK = 0
5
+ PARSE_PENDING = 1
6
+ PARSE_COMPLETE = 2
7
+
8
+ PARSE_TYPE = 0
9
+ PARSE_LEN = 1
10
+ PARSE_ENTITY = 2
11
+
12
+ def initialize(delegate=nil)
13
+ @channel = TCPServerChannel.new('127.0.0.1', 10086, self)
14
+ @clients = {}
15
+ @delegate = delegate
16
+ end
17
+
18
+ def on_accept(channel)
19
+ channel.delegate = self
20
+ @clients[channel] = {
21
+ :parse_status => PARSE_TYPE,
22
+ :parse_offset => 0,
23
+ :request => {
24
+ :type => 0,
25
+ :len => 0,
26
+ :entity => ""
27
+ },
28
+ :response => {
29
+ :type => 0,
30
+ :len => 0,
31
+ :entity => ""
32
+ }
33
+ }
34
+ puts("SimpleServer accept client: #{channel}")
35
+ end
36
+
37
+ def parse_data_type(client, data)
38
+ if data.length >= 1
39
+ type = data[0].ord
40
+ client[:request][:type] = type
41
+ client[:parse_status] = PARSE_LEN
42
+ client[:parse_offset] += 1
43
+
44
+ puts("SimpleServer parse data type ok")
45
+ return PARSE_OK
46
+ end
47
+
48
+ return PARSE_PENDING
49
+ end
50
+
51
+ def parse_data_len(client, data)
52
+ offset = client[:parse_offset]
53
+
54
+ if data.length >= 4 + offset
55
+ len = data[offset .. (4 + offset - 1)]
56
+ len = len.unpack('l')[0]
57
+
58
+ if len == nil
59
+ return PARSE_ERROR
60
+ end
61
+
62
+ client[:request][:len] = len
63
+ client[:parse_status] = PARSE_ENTITY
64
+ client[:parse_offset] = offset + 4
65
+
66
+ puts("SimpleServer parse data len ok")
67
+ return PARSE_OK
68
+ end
69
+
70
+ return PARSE_PENDING
71
+ end
72
+
73
+ def parse_data_entity(client, data)
74
+ len = client[:request][:len]
75
+ offset = client[:parse_offset]
76
+
77
+ if data.length >= len + offset
78
+ client[:request][:entity] = data[offset .. (offset + len - 1)]
79
+ client[:parse_status] = PARSE_TYPE
80
+ client[:parse_offset] = offset + len
81
+
82
+ puts("SimpleServer parse data entity ok")
83
+ return PARSE_COMPLETE
84
+ end
85
+
86
+ return PARSE_PENDING
87
+ end
88
+
89
+ def parse_data(client, data)
90
+ result = PARSE_OK
91
+
92
+ while result == PARSE_OK
93
+ current_status = client[:parse_status]
94
+
95
+ case current_status
96
+ when PARSE_TYPE
97
+ result = self.parse_data_type(client, data)
98
+
99
+ when PARSE_LEN
100
+ result = self.parse_data_len(client, data)
101
+
102
+ when PARSE_ENTITY
103
+ result = self.parse_data_entity(client, data)
104
+ end
105
+ end
106
+
107
+ puts("SimpleServer parse data result #{result}")
108
+
109
+ return result
110
+ end
111
+
112
+ def pack_data(response)
113
+ data = ""
114
+ data += [response[:type]].pack('c')
115
+ data += [response[:len]].pack('l')
116
+ data += response[:entity]
117
+ end
118
+
119
+ def on_recv(channel, data)
120
+ puts("SimpleServer recv: #{data}")
121
+ client = @clients[channel]
122
+ client[:parse_offset] = 0
123
+ result = self.parse_data(client, data)
124
+
125
+ pp client
126
+
127
+ if result == PARSE_COMPLETE
128
+ if @delegate != nil
129
+ @delegate.handle(client[:request], client[:response])
130
+
131
+ else
132
+ client[:response] = client[:request]
133
+ end
134
+
135
+ channel.write(self.pack_data(client[:response])) # Response data
136
+
137
+ elsif result == PARSE_ERROR
138
+ channel.close
139
+ @clients.delete(channel)
140
+ puts("SimpleServer: Illegal request")
141
+ return client[:parse_offset]
142
+ end
143
+
144
+ return client[:parse_offset]
145
+ end
146
+ end
147
+ end
148
+
149
+ require "pp"
@@ -0,0 +1,10 @@
1
+ module Rakie
2
+ class TCPChannel < Channel
3
+ def initialize(ip, port, delegate=nil)
4
+ @io = TCPSocket.new(ip, port)
5
+ super(@io, delegate)
6
+ end
7
+ end
8
+ end
9
+
10
+ require "socket"
@@ -0,0 +1,52 @@
1
+ module Rakie
2
+ class TCPServerChannel < Channel
3
+ def initialize(ip, port=nil, delegate=nil)
4
+ io = nil
5
+
6
+ if port == nil
7
+ port = ip
8
+ io = TCPServer.new(ip)
9
+
10
+ else
11
+ io = TCPServer.new(ip, port)
12
+ end
13
+
14
+ @clients = []
15
+
16
+ super(io, delegate)
17
+ end
18
+
19
+ def on_read(io)
20
+ begin
21
+ client_io, = io.accept_nonblock
22
+ channel = Channel.new(client_io)
23
+
24
+ if @delegate != nil
25
+ puts("TCPServerChannel has delegate")
26
+ @delegate.on_accept(channel)
27
+
28
+ else
29
+ puts("TCPServerChannel no delegate")
30
+ @clients << channel
31
+ end
32
+
33
+ puts("TCPServerChannel accept #{channel}")
34
+
35
+ rescue IO::EAGAINWaitReadable
36
+ puts("TCPServerChannel accept wait")
37
+
38
+ rescue
39
+ puts("TCPServerChannel Accept failed #{io}")
40
+ return Event::HANDLE_FAILED
41
+ end
42
+
43
+ return Event::HANDLE_CONTINUED
44
+ end
45
+
46
+ def accept
47
+ @clients.shift
48
+ end
49
+ end
50
+ end
51
+
52
+ require "socket"
data/lib/rakie.rb ADDED
@@ -0,0 +1,10 @@
1
+
2
+ module Rakie
3
+
4
+ end
5
+
6
+ require "rakie/channel"
7
+ require "rakie/event"
8
+ require "rakie/simple_server"
9
+ require "rakie/tcp_channel"
10
+ require "rakie/tcp_server_channel"
@@ -0,0 +1,5 @@
1
+ require 'test/unit'
2
+
3
+ class RakieTest < Test::Unit::TestCase
4
+
5
+ end
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rakie
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Jakit Liang
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-03-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Rakie is lucky and lucky
14
+ email: jakitliang@163.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - Rakefile
20
+ - lib/rakie.rb
21
+ - lib/rakie/channel.rb
22
+ - lib/rakie/event.rb
23
+ - lib/rakie/simple_server.rb
24
+ - lib/rakie/tcp_channel.rb
25
+ - lib/rakie/tcp_server_channel.rb
26
+ - test/test_rakie.rb
27
+ homepage: https://github.com/Jakitto/rakie
28
+ licenses:
29
+ - BSD-2-Clause-Patent
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubygems_version: 3.0.9
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: Rakie!
50
+ test_files:
51
+ - test/test_rakie.rb