jrpc 1.1.8 → 2.1.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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +55 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +228 -0
  5. data/CHANGELOG.md +67 -0
  6. data/Gemfile +17 -0
  7. data/README.md +240 -13
  8. data/Rakefile +3 -1
  9. data/bin/console +1 -0
  10. data/bin/jrpc +37 -26
  11. data/bin/jrpc-shell +34 -24
  12. data/jrpc.gemspec +6 -8
  13. data/lib/jrpc/errors.rb +65 -0
  14. data/lib/jrpc/id_generator.rb +22 -0
  15. data/lib/jrpc/message.rb +78 -0
  16. data/lib/jrpc/payload_logging.rb +19 -0
  17. data/lib/jrpc/shared_client/outbound_queue.rb +71 -0
  18. data/lib/jrpc/shared_client/registry.rb +46 -0
  19. data/lib/jrpc/shared_client/ticket.rb +84 -0
  20. data/lib/jrpc/shared_client/transport_loop.rb +298 -0
  21. data/lib/jrpc/shared_client.rb +194 -0
  22. data/lib/jrpc/simple_client.rb +98 -0
  23. data/lib/jrpc/transport/base.rb +63 -0
  24. data/lib/jrpc/transport/tcp.rb +292 -0
  25. data/lib/jrpc/transport/test.rb +333 -0
  26. data/lib/jrpc/transport.rb +12 -0
  27. data/lib/jrpc/version.rb +3 -1
  28. data/lib/jrpc.rb +14 -16
  29. metadata +25 -71
  30. data/.travis.yml +0 -4
  31. data/lib/jrpc/base_client.rb +0 -123
  32. data/lib/jrpc/error/client_error.rb +0 -5
  33. data/lib/jrpc/error/connection_error.rb +0 -11
  34. data/lib/jrpc/error/error.rb +0 -5
  35. data/lib/jrpc/error/internal_error.rb +0 -9
  36. data/lib/jrpc/error/internal_server_error.rb +0 -5
  37. data/lib/jrpc/error/invalid_params.rb +0 -9
  38. data/lib/jrpc/error/invalid_request.rb +0 -9
  39. data/lib/jrpc/error/method_not_found.rb +0 -9
  40. data/lib/jrpc/error/parse_error.rb +0 -9
  41. data/lib/jrpc/error/server_error.rb +0 -11
  42. data/lib/jrpc/error/unknown_error.rb +0 -5
  43. data/lib/jrpc/tcp_client.rb +0 -112
  44. data/lib/jrpc/transport/socket_base.rb +0 -88
  45. data/lib/jrpc/transport/socket_tcp.rb +0 -132
  46. data/lib/jrpc/utils.rb +0 -9
@@ -1,132 +0,0 @@
1
- module JRPC
2
- module Transport
3
- class SocketTcp < SocketBase
4
-
5
- def read(length, timeout = @read_timeout)
6
- received = ''
7
- length_to_read = length
8
- while length_to_read > 0
9
- io_read, = IO.select([socket], [], [], timeout)
10
- raise ReadTimeoutError unless io_read
11
- check_fin_signal
12
- chunk = io_read[0].read_nonblock(length_to_read)
13
- received += chunk
14
- length_to_read -= chunk.bytesize
15
- end
16
- received
17
- rescue Errno::EPIPE, EOFError => e
18
- # EPIPE, in this case, means that the data connection was unexpectedly terminated.
19
- clear_socket!
20
- raise ReadFailedError, "#{e.class} #{e.message}"
21
- end
22
-
23
- def write(data, timeout = @write_timeout)
24
- length_written = 0
25
- data_to_write = data
26
- while data_to_write.bytesize > 0
27
- _, io_write, = IO.select([], [socket], [], timeout)
28
- raise WriteTimeoutError unless io_write
29
- check_fin_signal
30
- chunk_length = io_write[0].write_nonblock(data_to_write)
31
- length_written += chunk_length
32
- data_to_write = data.byteslice(length_written, data.length)
33
- end
34
- length_written
35
- rescue Errno::EPIPE => e
36
- # EPIPE, in this case, means that the data connection was unexpectedly terminated.
37
- clear_socket!
38
- raise WriteFailedError, "#{e.class} #{e.message}"
39
- end
40
-
41
- def close
42
- return if @socket.nil?
43
- socket.close
44
- end
45
-
46
- # Socket implementation allows client to send data to server after FIN,
47
- # but server will never receive this data.
48
- # So we consider socket closed when it have FIN event
49
- # and close it correctly from client side.
50
- def closed?
51
- return true if @socket.nil? || socket.closed?
52
-
53
- if fin_signal?
54
- close
55
- return true
56
- end
57
-
58
- false
59
- end
60
-
61
- # Socket implementation allows client to send data to server after FIN,
62
- # but server will never receive this data.
63
- # We correctly close socket from client side when FIN event received.
64
- # Should be checked before send data to socket or recv data from socket.
65
- def check_fin_signal
66
- close if socket && !socket.closed? && fin_signal?
67
- end
68
-
69
- def socket
70
- @socket ||= build_socket
71
- end
72
-
73
- private
74
-
75
- # when recv_nonblock(1) responds with empty string means that FIN event was received.
76
- # in other cases it will return 1 byte string or raise EAGAINWaitReadable.
77
- # MSG_PEEK means we do not move pointer when reading data.
78
- # see https://apidock.com/ruby/BasicSocket/recv_nonblock
79
- def fin_signal?
80
- begin
81
- resp = socket.recv_nonblock(1, Socket::MSG_PEEK)
82
- rescue IO::EAGAINWaitReadable => _
83
- resp = nil
84
- end
85
- resp == ''
86
- end
87
-
88
- def clear_socket!
89
- return if @socket.nil?
90
- @socket.close unless @socket.closed?
91
- @socket = nil
92
- end
93
-
94
- def set_timeout_to(socket, type, value)
95
- secs = Integer(value)
96
- u_secs = Integer((value - secs) * 1_000_000)
97
- opt_val = [secs, u_secs].pack('l_2')
98
- socket.setsockopt Socket::SOL_SOCKET, type, opt_val
99
- end
100
-
101
- def build_socket
102
- host = @server.split(':').first
103
- addr = Socket.getaddrinfo(host, nil)
104
- Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0)
105
- end
106
-
107
- def connect_socket
108
- host, port = @server.split(':')
109
- addr = Socket.getaddrinfo(host, nil)
110
- full_addr = Socket.pack_sockaddr_in(port, addr[0][3])
111
-
112
- begin
113
- socket.connect_nonblock(full_addr)
114
- rescue IO::WaitWritable => _
115
- if IO.select(nil, [socket], nil, @connect_timeout)
116
- socket.connect_nonblock(full_addr)
117
- else
118
- clear_socket!
119
- raise ConnectionFailedError, "Can't connect during #{@connect_timeout}"
120
- end
121
- end
122
-
123
- rescue Errno::EISCONN => _
124
- # already connected
125
- rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ETIMEDOUT, Errno::EPIPE => e
126
- clear_socket!
127
- raise ConnectionFailedError, "#{e.class} #{e.message}"
128
- end
129
-
130
- end
131
- end
132
- end
data/lib/jrpc/utils.rb DELETED
@@ -1,9 +0,0 @@
1
- module JRPC
2
- class Utils
3
-
4
- def self.truncate(string, length, ommiter = '...')
5
- "#{string[0..length]}#{ommiter if string.length > length}"
6
- end
7
-
8
- end
9
- end