tcp_sumac 0.0.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b1a4ae1aec5db2c3cf69cfdd289b6fc5fee21956
4
+ data.tar.gz: 60c962795965dddcecc298095252f73a981840eb
5
+ SHA512:
6
+ metadata.gz: 425f272202d54fef53ff4d50fecb1da777b95b876da2ee95fa6359a191bfe8455e7a36c4ea0c00ae0b0a40b7d216dbca051efcef3291a45bcf540d003fa31da6
7
+ data.tar.gz: e98b56f857f7500140d33d166dbc954b9ded680529a625f60accfd4938d7127d2d095b42ad699a722a60fcdff2377da7d22ad1e1af6a4d7b3a6540a11ea7b66a
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Rob Fors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ # TCP Sumac
2
+ Wraps Sumac and TCPMessenger for an easy to implement library.
@@ -0,0 +1,32 @@
1
+ require 'thread'
2
+ require 'quack_concurrency'
3
+ require 'tcp_messenger'
4
+ require 'sumac'
5
+
6
+ require 'tcp_sumac/adapter'
7
+ require 'tcp_sumac/closed_error'
8
+ require 'tcp_sumac/connection_error'
9
+ require 'tcp_sumac/server'
10
+
11
+
12
+ module TCPSumac
13
+
14
+ def self.connect(duck_types: {}, entry: nil, host: , max_message_length: Float::INFINITY, port: , workers: 1)
15
+ messenger = TCPMessenger.connect(duck_types: duck_types, host: host, max_message_length: max_message_length, port: port)
16
+ adapter = Adapter.new(messenger)
17
+ Sumac.new(duck_types: duck_types, entry: entry, messenger: adapter, workers: workers)
18
+ end
19
+
20
+ def self.listen(duck_types: {}, entry: nil, entry_class: nil, max_message_length: Float::INFINITY, port: , workers: 1)
21
+ tcp_messenger_server = TCPMessenger.listen(duck_types: duck_types, max_message_length: max_message_length, port: port)
22
+ Server.new(tcp_messenger_server, duck_types: duck_types, entry: entry, entry_class: entry_class, max_message_length: max_message_length, workers: workers)
23
+ end
24
+
25
+ def self.accept(duck_types: {}, entry: nil, entry_class: nil, max_message_length: Float::INFINITY, port: , workers: 1)
26
+ server = listen(duck_types: duck_types, entry: entry, entry_class: entry_class, max_message_length: max_message_length, port: port, workers: workers)
27
+ sumac = server.accept
28
+ server.close
29
+ sumac
30
+ end
31
+
32
+ end
@@ -0,0 +1,40 @@
1
+ module TCPSumac
2
+ class Adapter
3
+
4
+ def initialize(messenger)
5
+ @messenger = messenger
6
+ end
7
+
8
+ def send(message)
9
+ begin
10
+ @messenger.send(message)
11
+ rescue TCPMessenger::ClosedError
12
+ raise Sumac::Adapter::ClosedError
13
+ end
14
+ nil
15
+ end
16
+
17
+ def receive
18
+ begin
19
+ message = @messenger.receive
20
+ rescue TCPMessenger::ClosedError
21
+ raise Sumac::Adapter::ClosedError
22
+ end
23
+ message
24
+ end
25
+
26
+ def close
27
+ begin
28
+ @messenger.close
29
+ rescue TCPMessenger::ClosedError
30
+ raise Sumac::Adapter::ClosedError
31
+ end
32
+ nil
33
+ end
34
+
35
+ def closed?
36
+ @messenger.closed?
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,5 @@
1
+ module TCPSumac
2
+ class ClosedError < StandardError
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module TCPSumac
2
+ class ConnectionError < ClosedError
3
+
4
+ end
5
+ end
@@ -0,0 +1,67 @@
1
+ module TCPSumac
2
+ class Server
3
+
4
+ def initialize(tcp_messenger_server, duck_types: , entry: , entry_class: , max_message_length: , workers: )
5
+ @tcp_messenger_server = tcp_messenger_server
6
+ @duck_types = duck_types
7
+ @entry = entry
8
+ @entry_class = entry_class
9
+ @max_message_length = max_message_length
10
+ @workers = workers
11
+ @close_mutex = QuackConcurrency::ReentrantMutex.new(duck_types: duck_types)
12
+ @accept_mutex = QuackConcurrency::ReentrantMutex.new(duck_types: duck_types)
13
+ @closed = false
14
+ end
15
+
16
+ def accept
17
+ @accept_mutex.synchronize do
18
+ raise ClosedError if closed?
19
+ begin
20
+ tcp_messenger = @tcp_messenger_server.accept
21
+ rescue
22
+ @close_mutex.synchronize do
23
+ raise ClosedError if closed?
24
+ close
25
+ raise ConnectionError
26
+ end
27
+ end
28
+ adapter = Adapter.new(tcp_messenger)
29
+
30
+ return Sumac.new(duck_types: @duck_types, entry: new_entry, messenger: adapter, workers: @workers)
31
+ end
32
+ end
33
+
34
+ def close
35
+ @close_mutex.synchronize do
36
+ raise ClosedError if closed?
37
+ begin
38
+ @tcp_messenger_server.close
39
+ rescue
40
+ raise ConnectionError
41
+ ensure
42
+ @closed = true
43
+ end
44
+ end
45
+ nil
46
+ end
47
+
48
+ def closed?
49
+ @closed
50
+ end
51
+
52
+ private
53
+
54
+ def new_entry
55
+ case
56
+ when @entry && !@entry_class
57
+ entry = @entry
58
+ when !@entry && @entry_class
59
+ entry = @entry_class.new
60
+ else
61
+ raise
62
+ end
63
+ entry
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,132 @@
1
+ require 'pry'
2
+ require 'tcp_sumac'
3
+
4
+ Thread.abort_on_exception = true
5
+
6
+ class Entry
7
+ include Sumac::ExposedObject
8
+
9
+ attr_accessor :value
10
+
11
+ expose :test, :value, :value=
12
+
13
+ def test
14
+ raise
15
+ sleep 5
16
+ 55
17
+ end
18
+
19
+ end
20
+
21
+ entry = Entry.new
22
+
23
+ sumac = TCPSumac.connect(host: '127.0.0.1', port: 2000, entry: entry, workers: 10)
24
+ #sumac.on(:network_error) { puts "***NETWORK_ERROR***" }
25
+ sumac.on(:shutdown) { puts "***SHUTDOWN***" }
26
+ sumac.on(:close) { puts "***CLOSE***" }
27
+
28
+ #u = sumac.entry.new_user('rob')
29
+ #u.sleep
30
+ #sumac.close
31
+ #begin
32
+ # u.sleep
33
+ #rescue StandardError => e
34
+ # puts e.message
35
+ #end
36
+
37
+ binding.pry
38
+ #sumac.entry.find('a').text
39
+ #sumac.join
40
+
41
+ threads = []
42
+ 100.times do
43
+ threads << Thread.new do
44
+ 1000.times do
45
+ #print 'a'
46
+ #name = (0...8).map { (65 + rand(26)).chr }.join
47
+ #g = sumac.entry.new_game
48
+ u = sumac.entry.new_user('name')
49
+ #begin
50
+ #rname = u.username
51
+ u.sleep
52
+ #rescue
53
+ #puts u.__remote_reference__.exposed_id
54
+ #binding.pry
55
+ #end
56
+ #raise unless rname == name
57
+ #print 'b'
58
+ #g.name
59
+ #g.forget
60
+ u.forget
61
+ #print 'c'
62
+ print '.'
63
+ end
64
+ end
65
+ end
66
+
67
+ #binding.pry
68
+ threads.each(&:join)
69
+ puts 'done'
70
+ #sumac.join
71
+ sumac.close
72
+
73
+ exit
74
+
75
+ c = []
76
+
77
+ 1_000.times do
78
+ messenger = TCPMessenger.connect('127.0.0.1', 2001)
79
+ connection = Sumac.start(messenger, nil)
80
+
81
+ connection.on(:network_error) { puts "***NETWORK_ERROR***" }
82
+ connection.on(:shutdown) { puts "***SHUTDOWN***" }
83
+ connection.on(:close) { messenger.close; puts "***CLOSE***" }
84
+
85
+ entry = connection.entry
86
+
87
+ u = entry.new_user('rob')
88
+ u.username
89
+ u.forget
90
+ c << connection
91
+ end
92
+
93
+ binding.pry
94
+
95
+ #t = Thread.new do
96
+ # begin
97
+ # sleep 1
98
+ # puts entry.test
99
+ # rescue Sumac::StaleObject
100
+ # puts 'good'
101
+ # end
102
+ #end
103
+
104
+ #mutex = Mutex.new
105
+ #$count = 0
106
+
107
+ #threads = 5.times.map do
108
+ # Thread.new do
109
+ # 100.times do
110
+ # entry.test
111
+ # mutex.synchronize { $count += 1; puts $count }
112
+ # end
113
+ # end
114
+ #end
115
+ #
116
+ #threads.each(&:join)
117
+
118
+ #sleep 2
119
+
120
+ connection.close
121
+
122
+ #binding.pry
123
+
124
+ #puts entry.new_user('rob').tt({},[44.44])
125
+
126
+ #puts connection.entry.new_user.username
127
+
128
+ #binding.pry
129
+
130
+
131
+
132
+ #t.join
@@ -0,0 +1,194 @@
1
+ require 'pry'
2
+ require 'tcp_sumac'
3
+
4
+ class Entry
5
+ include Sumac::ExposedObject
6
+
7
+ attr_accessor :value
8
+
9
+ expose :test, :value, :value=, :new_user, :games, :new_game
10
+ expose :messages
11
+
12
+ def test
13
+ #sleep 5
14
+ #sleep(rand)
15
+ 55
16
+ end
17
+
18
+ def new_user(username)
19
+ User.new(username)
20
+ end
21
+
22
+ def parent
23
+ Parent.new
24
+ end
25
+
26
+ def new_game
27
+ Game.new
28
+ end
29
+
30
+ def games
31
+ Game.new
32
+ #@games ||= [Game.new, Game.new]
33
+ end
34
+
35
+ def messages
36
+ TextMessage
37
+ end
38
+
39
+ end
40
+
41
+
42
+ class User
43
+ include Sumac::ExposedObject
44
+
45
+ attr_accessor :username
46
+
47
+ expose :username, :tt, :sleep
48
+
49
+ def initialize(username)
50
+ @username = username
51
+ end
52
+
53
+ def sleep
54
+ #binding.pry
55
+ #Kernel.sleep(0.1)
56
+ #raise 'test'
57
+ nil
58
+ end
59
+
60
+ def tt(a, b)
61
+ {'a' => a, 'b' => b}
62
+ end
63
+
64
+ end
65
+
66
+
67
+ class Game
68
+ include Sumac::ExposedObject
69
+
70
+ expose :name
71
+
72
+ def name
73
+ 'cool_game'
74
+ end
75
+
76
+ end
77
+
78
+
79
+ class Parent
80
+ include Sumac::ExposedObject
81
+
82
+ child_accessor :new_child
83
+
84
+ def initialize
85
+ @children = [Child.new(0, 'a'), Child.new(1, 'b')]
86
+ end
87
+
88
+ def child(key)
89
+ @children.find { |child| child.key == key }
90
+ end
91
+
92
+ def get_child(name)
93
+ @children.find { |child| child.name == name }
94
+ end
95
+
96
+ end
97
+
98
+
99
+ class Child
100
+ include Sumac::ExposedObjectChild
101
+
102
+ expose :name
103
+
104
+ def initialize(id, name)
105
+ @id = id
106
+ @name = name
107
+ end
108
+
109
+ def key
110
+ @id
111
+ end
112
+
113
+ def name
114
+ @name
115
+ end
116
+
117
+ end
118
+
119
+ class DB
120
+ class TextMessage
121
+
122
+ def self.messages
123
+ @text_messages ||= [new(0, 'a'), new(1, 'b')]
124
+ end
125
+
126
+ def self.find(uid)
127
+ messages.find { |text_message| text_message.uid == uid }
128
+ end
129
+
130
+ def self.search(text)
131
+ messages.find { |text_message| text_message.text == text }
132
+ end
133
+
134
+ attr_reader :uid, :text
135
+
136
+ def initialize(uid, text)
137
+ @uid = uid
138
+ @text = text
139
+ end
140
+
141
+ end
142
+ end
143
+
144
+ class TextMessage
145
+ extend Sumac::ExposedObject
146
+ include Sumac::ExposedObjectChild
147
+
148
+ child_accessor :get
149
+ parent_accessor :parent
150
+ key_accessor :key
151
+
152
+ expose :test, :find, :text
153
+
154
+ def self.get(key)
155
+ record = DB::TextMessage.find(key)
156
+ raise unless record
157
+ new(record)
158
+ end
159
+
160
+ def self.find(text)
161
+ record = DB::TextMessage.search(text)
162
+ raise unless record
163
+ new(record)
164
+ end
165
+
166
+ def initialize(record)
167
+ @record = record
168
+ end
169
+
170
+ def parent
171
+ TextMessage
172
+ end
173
+
174
+ def key
175
+ @record.uid
176
+ end
177
+
178
+ def text
179
+ @record.text
180
+ end
181
+
182
+ end
183
+
184
+ Thread.abort_on_exception = true
185
+
186
+ entry = Entry.new
187
+
188
+ sumac = TCPSumac.accept(port: 2000, entry: entry, workers: 10)
189
+ sumac.on(:shutdown) { puts "***SHUTDOWN***" }
190
+ sumac.on(:close) { puts "***CLOSE***" }
191
+
192
+ #binding.pry
193
+
194
+ sumac.join
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tcp_sumac
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Rob Fors
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-02-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: quack_concurrency
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: tcp_messenger
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: sumac
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 0.0.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.0.0
55
+ description:
56
+ email: mail@robfors.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - LICENSE
62
+ - README.md
63
+ - lib/tcp_sumac.rb
64
+ - lib/tcp_sumac/adapter.rb
65
+ - lib/tcp_sumac/closed_error.rb
66
+ - lib/tcp_sumac/connection_error.rb
67
+ - lib/tcp_sumac/server.rb
68
+ - test/client.rb
69
+ - test/server.rb
70
+ homepage: https://github.com/robfors/tcp_sumac
71
+ licenses:
72
+ - MIT
73
+ metadata: {}
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 2.4.8
91
+ signing_key:
92
+ specification_version: 4
93
+ summary: Wraps Sumac and TCPMessenger for an easy to implement library.
94
+ test_files: []