scale_rb 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79d55aeb610c1a4a11410703445983aa6b02cbf8ee21653a38d425b06c41e3dc
4
- data.tar.gz: 8e7832aa2495fed7226797bd21bc23db257754c8d5160cba57f7830879fe592f
3
+ metadata.gz: e5b8734ff8c6eda16208a8bb532ee411e15eaf04bf53f5f0f4d8465724b5f89e
4
+ data.tar.gz: 4aabf928980af1c7d2c6db2857c832743a9288f4e5b7cd17007ce6c25d7def1f
5
5
  SHA512:
6
- metadata.gz: 879a524038c25c42b98724a95c9db2658ba41a952386fa4132eb56ceff4d3403aa3fc519c4add1d29fc1ad6e413bdb5f1bc8ab4585a836327bc233dc7750ab43
7
- data.tar.gz: 4529731208f640854a9b9b3676ffdd3727b9344833ab026cd593f5d10e17ea0428bd651bc01aa774cb80fd68350249ba68be4b99eea54db6fe597b6f3732723a
6
+ metadata.gz: 2645dc18deb5d1d95bb28a4ad89512d2a05e9651f19eb48c3090895ab8fa16795204d09dbef9214168ba03126f0f2e6251e654b1bfb9766f12a3d85fc8801af1
7
+ data.tar.gz: 0ffb2cf53f4e46014f624f5e7d6d60cb8f92a9dabc74c97b90bf26725c3a6a80ffae96408df6aa0d4295d8ecef80b0f5520c74acb3f63a14d218084d48dd1abb
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- scale_rb (0.3.0)
4
+ scale_rb (0.3.1)
5
5
  async
6
6
  async-http (~> 0.69.0)
7
7
  async-websocket (~> 0.26.2)
@@ -12,7 +12,7 @@ PATH
12
12
  GEM
13
13
  remote: https://rubygems.org/
14
14
  specs:
15
- async (2.14.0)
15
+ async (2.14.1)
16
16
  console (~> 1.25, >= 1.25.2)
17
17
  fiber-annotation
18
18
  io-event (~> 1.6, >= 1.6.5)
@@ -45,7 +45,7 @@ GEM
45
45
  fiber-local (1.1.0)
46
46
  fiber-storage
47
47
  fiber-storage (0.1.2)
48
- io-endpoint (0.11.0)
48
+ io-endpoint (0.13.0)
49
49
  io-event (1.6.5)
50
50
  io-stream (0.4.0)
51
51
  json (2.7.2)
@@ -1,14 +1,10 @@
1
1
  require 'scale_rb'
2
2
 
3
- ScaleRb.logger.level = Logger::DEBUG
3
+ # ScaleRb.logger.level = Logger::DEBUG
4
4
 
5
- # the commented code below is the same as the code above
6
5
  ScaleRb::WsClient.start('wss://polkadot-rpc.dwellir.com') do |client|
7
6
  block_hash = client.chain_getBlockHash(21585684)
8
- # block_hash = client.request('chain_getBlockHash', [21585684])
9
-
10
7
  runtime_version = client.state_getRuntimeVersion(block_hash)
11
- # runtime_version = client.request('state_getRuntimeVersion', [block_hash])
12
-
13
- puts runtime_version
8
+ puts runtime_version['specName']
9
+ puts runtime_version['specVersion']
14
10
  end
@@ -1,6 +1,6 @@
1
1
  require 'scale_rb'
2
2
 
3
- ScaleRb.logger.level = Logger::DEBUG
3
+ # ScaleRb.logger.level = Logger::DEBUG
4
4
 
5
5
  ScaleRb::WsClient.start('wss://polkadot-rpc.dwellir.com') do |client|
6
6
  count = 0
@@ -13,7 +13,8 @@ ScaleRb::WsClient.start('wss://polkadot-rpc.dwellir.com') do |client|
13
13
  block_hash = client.chain_getBlockHash(block_number)
14
14
  puts "Received new head at height: #{block_number}, block hash: #{block_hash}"
15
15
  else
16
- client.chain_unsubscribeNewHead(subscription_id)
16
+ unsub_result = client.chain_unsubscribeNewHead(subscription_id)
17
+ puts "Unsubscribed from new heads: #{unsub_result}"
17
18
  end
18
19
  end
19
20
 
@@ -6,6 +6,56 @@ require 'json'
6
6
 
7
7
  require_relative 'client_ext'
8
8
 
9
+ module ScaleRb
10
+ class WsClient
11
+ def self.start(url)
12
+ Async do |task|
13
+ endpoint = Async::HTTP::Endpoint.parse(url, alpn_protocols: Async::HTTP::Protocol::HTTP11.names)
14
+ client = WsClient.new
15
+
16
+ task.async do
17
+ Async::WebSocket::Client.connect(endpoint) do |connection|
18
+ Async do
19
+ while request = client.next_request
20
+ ScaleRb.logger.debug "Sending request: #{request.to_json}"
21
+ connection.write(request.to_json)
22
+ end
23
+ end
24
+
25
+ # inside main task
26
+ while message = connection.read
27
+ data = JSON.parse(message)
28
+ ScaleRb.logger.debug "Received message: #{data}"
29
+
30
+ Async do
31
+ client.handle_response(data)
32
+ rescue => e
33
+ ScaleRb.logger.error "#{e.class}: #{e.message}"
34
+ ScaleRb.logger.error e.backtrace.join("\n")
35
+ task.stop
36
+ end
37
+ end
38
+ rescue => e
39
+ ScaleRb.logger.error "#{e.class}: #{e.message}"
40
+ ScaleRb.logger.error e.backtrace.join("\n")
41
+ ensure
42
+ task.stop
43
+ end
44
+ end
45
+
46
+ task.async do
47
+ client.supported_methods = client.rpc_methods()['methods']
48
+ yield client
49
+ rescue => e
50
+ ScaleRb.logger.error "#{e.class}: #{e.message}"
51
+ ScaleRb.logger.error e.backtrace.join("\n")
52
+ task.stop
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
9
59
  module ScaleRb
10
60
  class WsClient
11
61
  include ClientExt
@@ -18,29 +68,35 @@ module ScaleRb
18
68
  @request_id = 1
19
69
  end
20
70
 
21
- def request(method, params = [])
22
- # don't check for rpc_methods, because there is no @supported_methods when initializing
71
+ def respond_to_missing?(method, *)
72
+ @supported_methods.include?(method.to_s)
73
+ end
74
+
75
+ def method_missing(method, *args)
76
+ method = method.to_s
77
+ ScaleRb.logger.debug "#{method}(#{args.join(', ')})"
78
+
79
+ # why not check 'rpc_methods', because there is no @supported_methods when initializing
23
80
  if method != 'rpc_methods' && !@supported_methods.include?(method)
24
81
  raise "Method `#{method}` is not supported. It should be in [#{@supported_methods.join(', ')}]."
25
82
  end
26
83
 
27
- response_future = Async::Notification.new
28
-
29
- @response_handler.register(@request_id, proc { |response|
30
- # this is running in the main task
31
- response_future.signal(response['result'])
32
- })
33
-
34
- request = JsonRpcRequest.new(@request_id, method, params)
35
- @queue.enqueue(request)
36
-
37
- @request_id += 1
84
+ if method.include?('unsubscribe')
85
+ unsubscribe(method, args[0])
86
+ elsif method.include?('subscribe')
87
+ raise "A subscribe method needs a block" unless block_given?
38
88
 
39
- response_future.wait
89
+ subscribe(method, args) do |notification|
90
+ yield notification['params']['result']
91
+ end
92
+ else
93
+ request(method, args)
94
+ end
40
95
  end
41
96
 
42
97
  def subscribe(method, params = [], &block)
43
98
  return unless method.include?('subscribe')
99
+ return if method.include?('unsubscribe')
44
100
 
45
101
  subscription_id = request(method, params)
46
102
  @subscription_handler.subscribe(subscription_id, block)
@@ -48,9 +104,11 @@ module ScaleRb
48
104
  end
49
105
 
50
106
  def unsubscribe(method, subscription_id)
51
- result = request(method, [subscription_id])
52
- @subscription_handler.unsubscribe(subscription_id)
53
- result
107
+ return unless method.include?('unsubscribe')
108
+
109
+ if @subscription_handler.unsubscribe(subscription_id)
110
+ request(method, [subscription_id])
111
+ end
54
112
  end
55
113
 
56
114
  def next_request
@@ -67,72 +125,22 @@ module ScaleRb
67
125
  end
68
126
  end
69
127
 
70
- def respond_to_missing?(*_args)
71
- true
72
- end
73
-
74
- def method_missing(method, *args)
75
- ScaleRb.logger.debug "#{method}(#{args.join(', ')})"
128
+ private
76
129
 
77
- method = method.to_s
78
- if method.include?('unsubscribe')
79
- unsubscribe(method, args[0])
80
- elsif method.include?('subscribe')
81
- raise "A subscribe method needs a block" unless block_given?
82
-
83
- subscribe(method, args) do |notification|
84
- yield notification['params']['result']
85
- end
86
- else
87
- request(method, args)
88
- end
89
- end
90
-
91
- def self.start(url)
92
- Async do |task|
93
- endpoint = Async::HTTP::Endpoint.parse(url, alpn_protocols: Async::HTTP::Protocol::HTTP11.names)
94
- client = WsClient.new
130
+ def request(method, params = [])
131
+ response_future = Async::Notification.new
95
132
 
96
- task.async do
97
- Async::WebSocket::Client.connect(endpoint) do |connection|
98
- Async do
99
- while request = client.next_request
100
- ScaleRb.logger.debug "Sending request: #{request.to_json}"
101
- connection.write(request.to_json)
102
- end
103
- end
133
+ @response_handler.register(@request_id, proc { |response|
134
+ # this is running in the main task
135
+ response_future.signal(response['result'])
136
+ })
104
137
 
105
- # inside main task
106
- while message = connection.read
107
- data = JSON.parse(message)
108
- ScaleRb.logger.debug "Received message: #{data}"
138
+ request = JsonRpcRequest.new(@request_id, method, params)
139
+ @queue.enqueue(request)
109
140
 
110
- # 可以简单的理解为,这里的handle_response就是通知wait中的request,可以继续了.
111
- Async do
112
- client.handle_response(data)
113
- rescue => e
114
- ScaleRb.logger.error "#{e.class}: #{e.message}"
115
- ScaleRb.logger.error e.backtrace.join("\n")
116
- task.stop
117
- end
118
- end
119
- rescue => e
120
- ScaleRb.logger.error "#{e.class}: #{e.message}"
121
- ScaleRb.logger.error e.backtrace.join("\n")
122
- ensure
123
- task.stop
124
- end
125
- end
141
+ @request_id += 1
126
142
 
127
- task.async do
128
- client.supported_methods = client.request('rpc_methods')['methods']
129
- yield client
130
- rescue => e
131
- ScaleRb.logger.error "#{e.class}: #{e.message}"
132
- ScaleRb.logger.error e.backtrace.join("\n")
133
- task.stop
134
- end
135
- end
143
+ response_future.wait
136
144
  end
137
145
  end
138
146
 
@@ -191,10 +199,20 @@ module ScaleRb
191
199
 
192
200
  def handle(notification)
193
201
  subscription_id = notification.dig('params', 'subscription')
194
- if subscription_id && @subscriptions.key?(subscription_id)
202
+ return if subscription_id.nil?
203
+
204
+ if @subscriptions.key?(subscription_id)
195
205
  @subscriptions[subscription_id].call(notification)
196
206
  else
197
- ScaleRb.logger.debug "Received a notification with unknown subscription id: #{notification}"
207
+ # the subscription_id may be not registered.
208
+ # in client.subscribe function,
209
+ # ...
210
+ # subscription_id = request(method, params)
211
+ # @subscription_handler.subscribe(subscription_id, block)
212
+ # ...
213
+ # the request(method, params) may be slow, so the subscription_id may be not registered when the first notification comes.
214
+ sleep 0.01
215
+ handle(notification)
198
216
  end
199
217
  end
200
218
  end
@@ -1,3 +1,3 @@
1
1
  module ScaleRb
2
- VERSION = '0.3.0'
2
+ VERSION = '0.3.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scale_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aki Wu
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-14 00:00:00.000000000 Z
11
+ date: 2024-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base58