io_request 1.2.0 → 2.3.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.
- checksums.yaml +4 -4
- data/.gitignore +10 -8
- data/.rubocop.yml +37 -0
- data/.rubocop_todo.yml +7 -0
- data/Gemfile +17 -4
- data/README.md +31 -39
- data/Rakefile +31 -10
- data/bin/console +8 -14
- data/io_request.gemspec +23 -21
- data/lib/io_request.rb +20 -8
- data/lib/io_request/authorizer.rb +42 -0
- data/lib/io_request/client.rb +177 -157
- data/lib/io_request/connection/ssl_sockets.rb +163 -0
- data/lib/io_request/logging.rb +13 -42
- data/lib/io_request/message.rb +68 -85
- data/lib/io_request/utility/multi_thread.rb +64 -0
- data/lib/io_request/utility/with_id.rb +60 -0
- data/lib/io_request/utility/with_prog_name.rb +14 -0
- data/lib/io_request/version.rb +3 -1
- metadata +26 -22
- data/Gemfile.lock +0 -29
- data/examples/simple_example.rb +0 -52
- data/lib/io_request/utility.rb +0 -104
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IORequest
|
4
|
+
# Utility methods.
|
5
|
+
module Utility
|
6
|
+
# Extended Id of object
|
7
|
+
class ExtendedID
|
8
|
+
include Comparable
|
9
|
+
|
10
|
+
# Create new Id based on PID, thread ID and object ID.
|
11
|
+
def initialize(pid = nil, tid = nil, oid = nil)
|
12
|
+
@pid = pid || Process.pid
|
13
|
+
@tid = tid || Thread.current.object_id
|
14
|
+
@oid = oid || object_id
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Integer] process ID.
|
18
|
+
attr_reader :pid
|
19
|
+
|
20
|
+
# @return [Integer] thread ID.
|
21
|
+
attr_reader :tid
|
22
|
+
|
23
|
+
# @return [Integer] object ID.
|
24
|
+
attr_reader :oid
|
25
|
+
|
26
|
+
# @return [String]
|
27
|
+
def to_s
|
28
|
+
"#{@pid}##{@tid}##{@oid}"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Comparison operator.
|
32
|
+
def <=>(other)
|
33
|
+
if @pid == other.pid && @tid == other.tid
|
34
|
+
@oid <=> other.oid
|
35
|
+
elsif @pid == other.pid && @tid != other.tid
|
36
|
+
@tid <=> tid
|
37
|
+
else
|
38
|
+
@pid <=> other.pid
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.from(obj)
|
43
|
+
case obj
|
44
|
+
when ExtendedID then new(obj.pid, obj.tid, obj.oid)
|
45
|
+
when String then new(*obj.split('#').map(&:to_i))
|
46
|
+
else
|
47
|
+
raise 'unknown type'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
# Adds special method to return object ID.
|
52
|
+
module WithID
|
53
|
+
# Identifies object in thread and process.
|
54
|
+
def __with_id__extended_id
|
55
|
+
@__with_id__extended_id ||= ExtendedID.new
|
56
|
+
end
|
57
|
+
alias extended_id __with_id__extended_id
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IORequest
|
4
|
+
# Utility methods.
|
5
|
+
module Utility
|
6
|
+
# Adds special method to identify object in log files.
|
7
|
+
module WithProgName
|
8
|
+
# Identifies object and thread it runs in.
|
9
|
+
def prog_name
|
10
|
+
"#{self.class.name}##{object_id} in Thread##{Thread.current.object_id}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/io_request/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: io_request
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fizvlad
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -25,75 +25,75 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '5.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '5.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '13.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '13.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: json
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '2.0'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '2.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: logger
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: '1.4'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: '1.4'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: timeout-extensions
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
89
|
+
version: 0.1.1
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: 0.1.1
|
97
97
|
description:
|
98
98
|
email:
|
99
99
|
- fizvlad@mail.ru
|
@@ -102,20 +102,24 @@ extensions: []
|
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
104
|
- ".gitignore"
|
105
|
+
- ".rubocop.yml"
|
106
|
+
- ".rubocop_todo.yml"
|
105
107
|
- ".travis.yml"
|
106
108
|
- Gemfile
|
107
|
-
- Gemfile.lock
|
108
109
|
- LICENSE.txt
|
109
110
|
- README.md
|
110
111
|
- Rakefile
|
111
112
|
- bin/console
|
112
|
-
- examples/simple_example.rb
|
113
113
|
- io_request.gemspec
|
114
114
|
- lib/io_request.rb
|
115
|
+
- lib/io_request/authorizer.rb
|
115
116
|
- lib/io_request/client.rb
|
117
|
+
- lib/io_request/connection/ssl_sockets.rb
|
116
118
|
- lib/io_request/logging.rb
|
117
119
|
- lib/io_request/message.rb
|
118
|
-
- lib/io_request/utility.rb
|
120
|
+
- lib/io_request/utility/multi_thread.rb
|
121
|
+
- lib/io_request/utility/with_id.rb
|
122
|
+
- lib/io_request/utility/with_prog_name.rb
|
119
123
|
- lib/io_request/version.rb
|
120
124
|
homepage: https://github.com/fizvlad/io-request-rb
|
121
125
|
licenses:
|
@@ -132,14 +136,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
132
136
|
requirements:
|
133
137
|
- - ">="
|
134
138
|
- !ruby/object:Gem::Version
|
135
|
-
version: 2.
|
139
|
+
version: 2.6.5
|
136
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
141
|
requirements:
|
138
142
|
- - ">="
|
139
143
|
- !ruby/object:Gem::Version
|
140
144
|
version: '0'
|
141
145
|
requirements: []
|
142
|
-
rubygems_version: 3.0.
|
146
|
+
rubygems_version: 3.1.0.pre2
|
143
147
|
signing_key:
|
144
148
|
specification_version: 4
|
145
149
|
summary: Small gem to create JSON request/response type of connection over IO object
|
data/Gemfile.lock
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
io_request (1.2.0)
|
5
|
-
json (~> 2.0)
|
6
|
-
logger (~> 1.4)
|
7
|
-
timeout-extensions (~> 0.1.1)
|
8
|
-
|
9
|
-
GEM
|
10
|
-
remote: https://rubygems.org/
|
11
|
-
specs:
|
12
|
-
json (2.3.0)
|
13
|
-
logger (1.4.1)
|
14
|
-
minitest (5.13.0)
|
15
|
-
rake (13.0.1)
|
16
|
-
timeout-extensions (0.1.1)
|
17
|
-
|
18
|
-
PLATFORMS
|
19
|
-
ruby
|
20
|
-
x64-mingw32
|
21
|
-
|
22
|
-
DEPENDENCIES
|
23
|
-
bundler (~> 2.0)
|
24
|
-
io_request!
|
25
|
-
minitest (~> 5.0)
|
26
|
-
rake (~> 13.0)
|
27
|
-
|
28
|
-
BUNDLED WITH
|
29
|
-
2.0.2
|
data/examples/simple_example.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
require "io_request"
|
2
|
-
|
3
|
-
r1, w1 = IO.pipe
|
4
|
-
r2, w2 = IO.pipe
|
5
|
-
|
6
|
-
client_1 = IORequest::Client.new read: r1, write: w2
|
7
|
-
client_2 = IORequest::Client.new read: r2, write: w1
|
8
|
-
|
9
|
-
# Use
|
10
|
-
# Set up responders
|
11
|
-
# Authorization
|
12
|
-
client_2.respond type: "auth" do |request|
|
13
|
-
puts "Client 2: Authorization attempt as #{request.data[:username].inspect}"
|
14
|
-
sleep 2 # Some processing
|
15
|
-
{ type: "auth_success" }
|
16
|
-
end
|
17
|
-
|
18
|
-
# Default
|
19
|
-
client_2.respond do |request|
|
20
|
-
puts "Client 2: #{request.data.inspect}"
|
21
|
-
{ type: "success" }
|
22
|
-
end
|
23
|
-
|
24
|
-
# Send requests
|
25
|
-
auth = false
|
26
|
-
auth_request = client_1.request(
|
27
|
-
data: { type: "auth", username: "mymail@example.com", password: "let's pretend password hash is here" },
|
28
|
-
sync: true
|
29
|
-
) do |response|
|
30
|
-
unless response.data[:type] == "auth_success"
|
31
|
-
puts "Client 1: Authorization failed. Response: #{response.data.inspect}"
|
32
|
-
next
|
33
|
-
end
|
34
|
-
|
35
|
-
auth = true
|
36
|
-
# Do something
|
37
|
-
end
|
38
|
-
exit unless auth
|
39
|
-
puts "Client 1: Authorized!"
|
40
|
-
|
41
|
-
message = client_1.request(
|
42
|
-
data: { type: "message", message: "Hello!" },
|
43
|
-
sync: true
|
44
|
-
) do |response|
|
45
|
-
puts "Client 1: Message responded"
|
46
|
-
end
|
47
|
-
|
48
|
-
# Close
|
49
|
-
r1.close
|
50
|
-
w1.close
|
51
|
-
r2.close
|
52
|
-
w2.close
|
data/lib/io_request/utility.rb
DELETED
@@ -1,104 +0,0 @@
|
|
1
|
-
module IORequest
|
2
|
-
# Utility methods.
|
3
|
-
module Utility
|
4
|
-
# Adds special method to identify object in log files.
|
5
|
-
module WithProgName
|
6
|
-
##
|
7
|
-
# Identifies object and thread it runs in.
|
8
|
-
def prog_name
|
9
|
-
self_class = self.class
|
10
|
-
"#{self_class.name}##{object_id} in Thread##{Thread.current.object_id}"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
# Adds some methods to spawn new threads and join them.
|
15
|
-
#
|
16
|
-
# @note This module creates instance variables with prefix +@_MultiThread_+.
|
17
|
-
module MultiThread
|
18
|
-
private
|
19
|
-
|
20
|
-
# @return [Array<Thread>] array of running threads
|
21
|
-
def running_threads
|
22
|
-
@_MultiThread_threads ||= []
|
23
|
-
end
|
24
|
-
|
25
|
-
# Runs block with provided arguments forwarded as arguments in separate thread.
|
26
|
-
#
|
27
|
-
# All the inline args will be passed to block.
|
28
|
-
#
|
29
|
-
# @param thread_name [String] thread name.
|
30
|
-
#
|
31
|
-
# @return [Thread]
|
32
|
-
def in_thread(*args, name: nil, &block)
|
33
|
-
@_MultiThread_threads ||= []
|
34
|
-
@_MultiThread_mutex ||= Mutex.new
|
35
|
-
# Synchronizing addition/deletion of new threads. That's important
|
36
|
-
@_MultiThread_mutex.synchronize do
|
37
|
-
new_thread = Thread.new(*args) do |*in_args|
|
38
|
-
begin
|
39
|
-
block.call(*in_args)
|
40
|
-
ensure
|
41
|
-
@_MultiThread_mutex.synchronize do
|
42
|
-
@_MultiThread_threads.delete(Thread.current)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
@_MultiThread_threads << new_thread
|
47
|
-
new_thread.name = name if name
|
48
|
-
new_thread
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# For each running thread.
|
53
|
-
def each_thread(&block)
|
54
|
-
@_MultiThread_threads ||= []
|
55
|
-
|
56
|
-
@_MultiThread_threads.each(&block)
|
57
|
-
end
|
58
|
-
|
59
|
-
# Kills each thread.
|
60
|
-
def kill_threads
|
61
|
-
each_thread(&:kill)
|
62
|
-
each_thread(&:join)
|
63
|
-
end
|
64
|
-
|
65
|
-
# Joins each thread.
|
66
|
-
def join_threads
|
67
|
-
each_thread(&:join)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
# Extending Hash class.
|
74
|
-
class Hash
|
75
|
-
# Use this on JSON objects to turn all the +String+ keys of hash to symbols.
|
76
|
-
#
|
77
|
-
# @param depth [Integer] maximum amount of hashes to handle. This is just a
|
78
|
-
# simple way to protect from infinite loop.
|
79
|
-
#
|
80
|
-
# @return [self]
|
81
|
-
def symbolize_keys!(depth = 1000)
|
82
|
-
queue = [self]
|
83
|
-
count = 0
|
84
|
-
while h = queue.shift
|
85
|
-
h.transform_keys! { |key| key.is_a?(String) ? key.to_sym : key }
|
86
|
-
h.each_value { |v| queue.push(v) if v.is_a?(Hash) }
|
87
|
-
count += 1
|
88
|
-
break if count >= depth
|
89
|
-
end
|
90
|
-
self
|
91
|
-
end
|
92
|
-
|
93
|
-
# Whether provided hash is included into this one.
|
94
|
-
#
|
95
|
-
# @param other [Hash]
|
96
|
-
#
|
97
|
-
# @return [Boolean]
|
98
|
-
def contains?(other)
|
99
|
-
other.keys.all? do |key|
|
100
|
-
other[key] == self[key]
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|