matrix_sdk 2.0.1 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1de46ea35a8763e17d834c9395dc95a12c3084557085a0eb6b8e5f1fa25979a
4
- data.tar.gz: 13a55698bf72695e8e690d4d5f6618d7efe595f06c32c65580b10e9bf550724e
3
+ metadata.gz: 88e56c3775bf881fb720e4e262ff6073136204d26b72c03bb1bbd2a4138b90ee
4
+ data.tar.gz: c8f5223c4c0c4febda391e8320a90667b6438b92806ce0b9b7c251a506678730
5
5
  SHA512:
6
- metadata.gz: 919a27ee7fd758c382eafe3f8aad89c13da2a6cc6542ccd8bfe52d09186d93453b12406dfe6b03b6aa63d1898dbacfb6dbced4f4e9606722ad04df4f237cf600
7
- data.tar.gz: a8f5c0bc4fb07a089e0d1daebeb8996c6d36157550e73e3869a8bb55f25cc2c405a064654fc49c8bdb323f9d8c168b3c785e52b9f88fbc168ee29c152f7472a5
6
+ metadata.gz: 7ce44dc75ea446ff9f901d8309f58df4251c2c199540d27f086fbb77359974b5950da8c960540e3d7e89d1a40b7f264dfb9f1c5ad8462c4e94176fcb19fedc60
7
+ data.tar.gz: 0b2acb16c36524bac00528fe322984a587f8f0c951754d316148fbd337a5f0dafec6ce5daf3cdc5829673115bb96453b60475702633ca1e11718d5e78c8e37b0
data/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
+ ## 2.1.0 - 2020-05-22
2
+
3
+ - Adds unique query IDs as well as duration in API debug output, to make it easier to track long requests
4
+ - Finishes up MSC support, get sync over SSE working flawlessly
5
+ - Exposes the #listen_forever method in the client abstraction
6
+ - Fixes room access methods
7
+
1
8
  ## 2.0.1 - 2020-03-13
2
9
 
3
- - Add code for handling non-final MSC's in protocols
10
+ - Adds code for handling non-final MSC's in protocols
4
11
  - Currently implementing clients parts of MSC2018 for Sync over Server Sent Events
5
12
 
6
13
  ## 2.0.0 - 2020-02-14
@@ -161,6 +161,7 @@ module MatrixSdk
161
161
  def protocols
162
162
  self
163
163
  .class.included_modules
164
+ .reject { |m| m&.name.nil? }
164
165
  .select { |m| m.name.start_with? 'MatrixSdk::Protocols::' }
165
166
  .map { |m| m.name.split('::').last.to_sym }
166
167
  end
@@ -272,14 +273,20 @@ module MatrixSdk
272
273
  loop do
273
274
  raise MatrixConnectionError, "Server still too busy to handle request after #{failures} attempts, try again later" if failures >= 10
274
275
 
275
- print_http(request)
276
+ req_id = ('A'..'Z').to_a.sample(4).join
277
+
278
+ print_http(request, id: req_id)
276
279
  begin
280
+ dur_start = Time.now
277
281
  response = http.request request
278
- rescue EOFError => e
282
+ dur_end = Time.now
283
+ duration = dur_end - dur_start
284
+ rescue EOFError
279
285
  logger.error 'Socket closed unexpectedly'
280
- raise e
286
+ raise
281
287
  end
282
- print_http(response)
288
+ print_http(response, duration: duration, id: req_id)
289
+
283
290
  data = JSON.parse(response.body, symbolize_names: true) rescue nil
284
291
 
285
292
  if response.is_a? Net::HTTPTooManyRequests
@@ -298,17 +305,26 @@ module MatrixSdk
298
305
  end
299
306
  end
300
307
 
308
+ # Generate a transaction ID
309
+ #
310
+ # @return [String] An arbitrary transaction ID
311
+ def transaction_id
312
+ ret = @transaction_id ||= 0
313
+ @transaction_id = @transaction_id.succ
314
+ ret
315
+ end
316
+
301
317
  private
302
318
 
303
- def print_http(http, body: true)
319
+ def print_http(http, body: true, duration: nil, id: nil)
304
320
  return unless logger.debug?
305
321
 
306
322
  if http.is_a? Net::HTTPRequest
307
- dir = '>'
323
+ dir = "#{id ? id + ' : ' : nil}>"
308
324
  logger.debug "#{dir} Sending a #{http.method} request to `#{http.path}`:"
309
325
  else
310
- dir = '<'
311
- logger.debug "#{dir} Received a #{http.code} #{http.message} response:"
326
+ dir = "#{id ? id + ' : ' : nil}<"
327
+ logger.debug "#{dir} Received a #{http.code} #{http.message} response:#{duration ? " [#{(duration * 1000).to_i}ms]" : nil}"
312
328
  end
313
329
  http.to_hash.map { |k, v| "#{k}: #{k == 'authorization' ? '[ REDACTED ]' : v.join(', ')}" }.each do |h|
314
330
  logger.debug "#{dir} #{h}"
@@ -324,12 +340,6 @@ module MatrixSdk
324
340
  logger.warn "#{e.class} occured while printing request debug; #{e.message}\n#{e.backtrace.join "\n"}"
325
341
  end
326
342
 
327
- def transaction_id
328
- ret = @transaction_id ||= 0
329
- @transaction_id = @transaction_id.succ
330
- ret
331
- end
332
-
333
343
  def api_to_path(api)
334
344
  # TODO: <api>_current / <api>_latest
335
345
  "/_matrix/#{api.to_s.split('_').join('/')}"
@@ -424,12 +424,26 @@ module MatrixSdk
424
424
 
425
425
  @should_listen = true
426
426
  if api.protocol?(:MSC) && api.msc2108?
427
+ params[:filter] = sync_filter unless params.key? :filter
428
+ params[:filter] = params[:filter].to_json unless params[:filter].nil? || params[:filter].is_a?(String)
427
429
  params[:since] = @next_batch if @next_batch
428
- thread = api.msc2108_sync_sse(params) do |data, event:, id:|
429
- logger.debug "Handling SSE event '#{event}' from '#{id}'"
430
+
431
+ errors = 0
432
+ thread, cancel_token = api.msc2108_sync_sse(params) do |data, event:, id:|
430
433
  @next_batch = id if id
431
- handle_sync_response(data) if event.to_sym == :sync
434
+ if event.to_sym == :sync
435
+ handle_sync_response(data)
436
+ errors = 0
437
+ elsif event.to_sym == :sync_error
438
+ logger.error "SSE Sync error received; #{data.type}: #{data.message}"
439
+ errors += 1
440
+
441
+ # TODO: Allow configuring
442
+ raise 'Aborting due to excessive errors' if errors >= 5
443
+ end
432
444
  end
445
+
446
+ @should_listen = cancel_token
433
447
  else
434
448
  thread = Thread.new { listen_forever(params) }
435
449
  end
@@ -441,8 +455,15 @@ module MatrixSdk
441
455
  def stop_listener_thread
442
456
  return unless @sync_thread
443
457
 
444
- @should_listen = false
445
- @sync_thread.join if @sync_thread.alive?
458
+ if @should_listen.is_a? Hash
459
+ @should_listen[:run] = false
460
+ else
461
+ @should_listen = false
462
+ end
463
+ if @sync_thread.alive?
464
+ ret = @sync_thread.join(2)
465
+ @sync_thread.kill unless ret
466
+ end
446
467
  @sync_thread = nil
447
468
  end
448
469
 
@@ -503,8 +524,6 @@ module MatrixSdk
503
524
  end
504
525
  end
505
526
 
506
- private
507
-
508
527
  def listen_forever(timeout: 30, bad_sync_timeout: 5, sync_interval: 30, **params)
509
528
  orig_bad_sync_timeout = bad_sync_timeout + 0
510
529
  while @should_listen
@@ -528,6 +547,8 @@ module MatrixSdk
528
547
  fire_error(ErrorEvent.new(e, :listener_thread))
529
548
  end
530
549
 
550
+ private
551
+
531
552
  def post_authentication(data)
532
553
  @mxid = data[:user_id]
533
554
  @api.access_token = data[:access_token]
@@ -2,16 +2,13 @@
2
2
 
3
3
  # Preliminary support for unmerged MSCs (Matrix Spec Changes)
4
4
  module MatrixSdk::Protocols::MSC
5
- def self.included(_)
6
- @msc = {}
7
- end
8
-
9
5
  def refresh_mscs
10
6
  @msc = {}
11
7
  end
12
8
 
13
9
  # Check if there's support for MSC2108 - Sync over Server Sent Events
14
10
  def msc2108?
11
+ @msc ||= {}
15
12
  @msc[2108] ||= \
16
13
  begin
17
14
  request(:get, :client_r0, '/sync/sse', skip_auth: true, headers: { accept: 'text/event-stream' })
@@ -20,13 +17,13 @@ module MatrixSdk::Protocols::MSC
20
17
  rescue MatrixSdk::MatrixRequestError
21
18
  false
22
19
  end
20
+ rescue StandardError => e
21
+ logger.debug "Failed to check MSC2108 status;\n#{e.inspect}"
22
+ false
23
23
  end
24
24
 
25
25
  # Sync over Server Sent Events - MSC2108
26
26
  #
27
- # @note With the default Ruby Net::HTTP server, body fragments are cached up to 16kB,
28
- # which will result in large batches and delays if your filters trim a lot of data.
29
- #
30
27
  # @example Syncing over SSE
31
28
  # @since = 'some token'
32
29
  # api.msc2108_sync_sse(since: @since) do |data, event:, id:|
@@ -38,10 +35,11 @@ module MatrixSdk::Protocols::MSC
38
35
  #
39
36
  # @see Protocols::CS#sync
40
37
  # @see https://github.com/matrix-org/matrix-doc/pull/2108/
38
+ # rubocop:disable Metrics/MethodLength
41
39
  def msc2108_sync_sse(since: nil, **params, &on_data)
42
40
  raise ArgumentError, 'Must be given a block accepting two args - data and { event:, id: }' \
43
41
  unless on_data.is_a?(Proc) && on_data.arity == 2
44
- raise MatrixNotAuthorizedError unless access_token
42
+ raise 'Needs to be logged in' unless access_token # TODO: Better error
45
43
 
46
44
  query = params.select do |k, _v|
47
45
  %i[filter full_state set_presence].include? k
@@ -53,20 +51,52 @@ module MatrixSdk::Protocols::MSC
53
51
  u.query = URI.encode_www_form(query)
54
52
  end)
55
53
  req['accept'] = 'text/event-stream'
54
+ req['accept-encoding'] = 'identity' # Disable compression on the SSE stream
56
55
  req['authorization'] = "Bearer #{access_token}"
57
56
  req['last-event-id'] = since if since
58
57
 
58
+ cancellation_token = { run: true }
59
+
59
60
  # rubocop:disable Metrics/BlockLength
60
- thread = Thread.new do
61
+ thread = Thread.new(cancellation_token) do |ctx|
61
62
  print_http(req)
62
63
  http.request req do |response|
64
+ break unless ctx[:run]
65
+
63
66
  print_http(response, body: false)
64
67
  raise MatrixRequestError.new_by_code(JSON.parse(response.body, symbolize_names: true), response.code) unless response.is_a? Net::HTTPSuccess
65
68
 
69
+ # Override buffer size for BufferedIO
70
+ socket = response.instance_variable_get :@socket
71
+ if socket.is_a? Net::BufferedIO
72
+ socket.instance_eval do
73
+ def rbuf_fill
74
+ bufsize_override = 1024
75
+ loop do
76
+ case rv = @io.read_nonblock(bufsize_override, exception: false)
77
+ when String
78
+ @rbuf << rv
79
+ rv.clear
80
+ return
81
+ when :wait_readable
82
+ @io.to_io.wait_readable(@read_timeout) || raise(Net::ReadTimeout)
83
+ when :wait_writable
84
+ @io.to_io.wait_writable(@read_timeout) || raise(Net::ReadTimeout)
85
+ when nil
86
+ raise EOFError, 'end of file reached'
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ stream_id = ('A'..'Z').to_a.sample(4).join
94
+
95
+ logger.debug "MSC2108 : #{stream_id} : Starting SSE stream."
96
+
66
97
  buffer = ''
67
98
  response.read_body do |chunk|
68
99
  buffer += chunk
69
- logger.debug "< MSC2108: Received #{chunk.length}B of data."
70
100
 
71
101
  while (index = buffer.index(/\r\n\r\n|\n\n/))
72
102
  stream = buffer.slice!(0..index)
@@ -86,20 +116,32 @@ module MatrixSdk::Protocols::MSC
86
116
  /^id:(.+)$/.match(part) do |m_id|
87
117
  id = m_id[1].strip
88
118
  end
119
+ /^:(.+)$/.match(part) do |m_comment|
120
+ logger.debug "MSC2108 : #{stream_id} : Received comment '#{m_comment[1].strip}'"
121
+ end
89
122
  end
90
123
 
91
- data = JSON.parse(data, symbolize_names: true)
124
+ if %w[sync sync_error].include? event
125
+ data = JSON.parse(data, symbolize_names: true)
126
+ yield((MatrixSdk::Response.new self, data), event: event, id: id)
127
+ elsif event
128
+ logger.info "MSC2108 : #{stream_id} : Received unknown event '#{event}'; #{data}"
129
+ end
130
+ end
92
131
 
93
- yield((MatrixSdk::Response.new self, data), event: event, id: id)
132
+ unless ctx[:run]
133
+ socket.close
134
+ break
94
135
  end
95
136
  end
137
+ break unless ctx[:run]
96
138
  end
97
139
  end
98
140
  # rubocop:enable Metrics/BlockLength
99
141
 
100
- thread.abort_on_exception = true
101
142
  thread.run
102
143
 
103
- thread
144
+ [thread, cancellation_token]
104
145
  end
146
+ # rubocop:enable Metrics/MethodLength
105
147
  end
@@ -590,7 +590,7 @@ module MatrixSdk
590
590
  #
591
591
  # @param join_rule [:invite,:public] The join rule of the room
592
592
  def join_rule=(join_rule)
593
- client.api.set_join_rule(id, join_rule)
593
+ client.api.set_room_join_rules(id, join_rule)
594
594
  @join_rule = join_rule
595
595
  end
596
596
 
@@ -606,7 +606,7 @@ module MatrixSdk
606
606
  #
607
607
  # @param guest_access [:can_join,:forbidden] The new guest access status of the room
608
608
  def guest_access=(guest_access)
609
- client.api.set_guest_access(id, guest_access)
609
+ client.api.set_room_guest_access(id, guest_access)
610
610
  @guest_access = guest_access
611
611
  end
612
612
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MatrixSdk
4
- VERSION = '2.0.1'
4
+ VERSION = '2.1.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: matrix_sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Olofsson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-13 00:00:00.000000000 Z
11
+ date: 2020-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mocha