rakie 0.0.2

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