skyfall 0.1.3 → 0.2.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: b1d8eea31c1c63f4aabd513a470083862b653f4fb1ba5a0a638da1d9e8cba3af
4
- data.tar.gz: 15e57a872800ad3a0c2a0f38be1ed31694617e82fe0981e1c9a1598c9f70e325
3
+ metadata.gz: ce06b8a7ef3783cd255621d6868a737735b782999a8cab76b70cf1f869e2cd1d
4
+ data.tar.gz: 9edea42903a17cb83ee717ea92c81e9a853b530a24f0bc803f70835b3bed1ba2
5
5
  SHA512:
6
- metadata.gz: 84544c24ff44ed583df898567b260db3b23517de6248b105f6199de49f2a3bcfaaada701bb62252c59a44af2845321637cfa4ab5061b9f8f800d27107fb2f83e
7
- data.tar.gz: fb62308d1e517fdd257633a19f503dc9f9fce7d5b6b4d778a588c19facbe8c45ff60cca3e242ae9024c4975c9ca84326083e4eeddedd0da8d34f3ae9f647d05b
6
+ metadata.gz: 1b04bb91b734fe84d984af3c6a8c78959230d5ef865109882d86c5f0b2537f0a8b25678dcace7f5d8c26e560f871edba4de07f38273e2e7cf17088fd125a08e2
7
+ data.tar.gz: 5dffcf8a308789995d16293a9b8caba848374ab80c147a0ef87f440cb2c98887b4d81f3eb447d74c2bfc608ae448b54d9ada90556eb6e55cf59cc1df37e15390
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## [0.2.0] - 2023-07-24
2
+
3
+ - switched the websocket library from `websocket-client-simple` to `faye-websocket`, which should make event parsing up to ~30× faster (!)
4
+ - added `auto_reconnect` property to `Stream` (on by default) - if true, it will try to reconnect with an exponential backoff when the websocket disconnects, until you call `Stream#disconnect`
5
+
6
+ Note:
7
+
8
+ - calling `sleep` is no longer needed after connecting - call `connect` on a new thread instead to get previously default behavior of running the event loop asynchronously
9
+ - the disconnect event no longer passes an error object in the argument
10
+ - there is currently no "heartbeat" feature as in 0.1.x that checks for a stuck connection - but it doesn't seem to be needed
11
+
1
12
  ## [0.1.3] - 2023-07-04
2
13
 
3
14
  - allow passing a previously saved cursor to websocket to replay any missed events
data/README.md CHANGED
@@ -41,8 +41,6 @@ When you're ready, open the connection by calling `connect`:
41
41
  sky.connect
42
42
  ```
43
43
 
44
- The connection is started asynchronously on a separate thread. If you're running this code in a simple script (and not as a part of a server), call e.g. `sleep` without arguments or `loop { STDIN.read }` to prevent the script for exiting while the connection is open.
45
-
46
44
 
47
45
  ### Processing messages
48
46
 
data/example/firehose.rb CHANGED
@@ -21,7 +21,7 @@ end
21
21
 
22
22
  sky.on_connect { puts "Connected" }
23
23
  sky.on_disconnect { puts "Disconnected" }
24
+ sky.on_reconnect { puts "Reconnecting..." }
24
25
  sky.on_error { |e| puts "ERROR: #{e}" }
25
26
 
26
27
  sky.connect
27
- sleep
@@ -1,7 +1,8 @@
1
1
  require_relative 'websocket_message'
2
2
 
3
+ require 'eventmachine'
4
+ require 'faye/websocket'
3
5
  require 'uri'
4
- require 'websocket-client-simple'
5
6
 
6
7
  module Skyfall
7
8
  class Stream
@@ -11,7 +12,9 @@ module Skyfall
11
12
  :subscribe_repos => SUBSCRIBE_REPOS
12
13
  }
13
14
 
14
- attr_accessor :heartbeat_timeout, :heartbeat_interval, :cursor
15
+ MAX_RECONNECT_INTERVAL = 300
16
+
17
+ attr_accessor :heartbeat_timeout, :heartbeat_interval, :cursor, :auto_reconnect
15
18
 
16
19
  def initialize(server, endpoint, cursor = nil)
17
20
  @endpoint = check_endpoint(endpoint)
@@ -22,93 +25,71 @@ module Skyfall
22
25
  @heartbeat_interval = 5
23
26
  @heartbeat_timeout = 30
24
27
  @last_update = nil
28
+ @auto_reconnect = true
29
+ @connection_attempts = 0
25
30
  end
26
31
 
27
32
  def connect
28
- return if @websocket
33
+ return if @ws
29
34
 
30
35
  url = build_websocket_url
31
- handlers = @handlers
32
- stream = self
33
-
34
- handlers[:connecting]&.call(url)
35
-
36
- @websocket = WebSocket::Client::Simple.connect(url) do |ws|
37
- ws.on :message do |msg|
38
- stream.notify_heartbeat
39
36
 
40
- atp_message = Skyfall::WebsocketMessage.new(msg.data)
41
- stream.cursor = atp_message.seq
37
+ @handlers[:connecting]&.call(url)
38
+ @engines_on = true
42
39
 
43
- handlers[:raw_message]&.call(msg.data)
44
- handlers[:message]&.call(atp_message)
45
- end
46
-
47
- ws.on :open do
48
- handlers[:connect]&.call
40
+ EM.run do
41
+ EventMachine.error_handler do |e|
42
+ @handlers[:error]&.call(e)
49
43
  end
50
44
 
51
- ws.on :close do |e|
52
- handlers[:disconnect]&.call(e)
53
- end
45
+ @ws = Faye::WebSocket::Client.new(url)
54
46
 
55
- ws.on :error do |e|
56
- handlers[:error]&.call(e)
47
+ @ws.on(:open) do |e|
48
+ @handlers[:connect]&.call
57
49
  end
58
- end
59
50
 
60
- if @heartbeat_interval && @heartbeat_timeout && @heartbeat_thread.nil?
61
- hb_interval = @heartbeat_interval
62
- hb_timeout = @heartbeat_timeout
51
+ @ws.on(:message) do |msg|
52
+ @connection_attempts = 0
63
53
 
64
- @last_update = Time.now
54
+ data = msg.data.pack('C*')
55
+ @handlers[:raw_message]&.call(data)
65
56
 
66
- @heartbeat_thread = Thread.new do
67
- loop do
68
- sleep(hb_interval)
69
- @heartbeat_mutex.synchronize do
70
- if Time.now - @last_update > hb_timeout
71
- force_restart
72
- end
73
- end
57
+ if @handlers[:message]
58
+ atp_message = Skyfall::WebsocketMessage.new(data)
59
+ @cursor = atp_message.seq
60
+ @handlers[:message].call(atp_message)
61
+ else
62
+ @cursor = nil
74
63
  end
75
64
  end
76
- end
77
- end
78
65
 
79
- def force_restart
80
- @websocket.close
81
- @websocket = nil
66
+ @ws.on(:error) do |e|
67
+ @handlers[:error]&.call(e)
68
+ end
82
69
 
83
- timeout = 5
70
+ @ws.on(:close) do |e|
71
+ @ws = nil
84
72
 
85
- loop do
86
- begin
87
- @handlers[:reconnect]&.call
88
- connect
89
- break
90
- rescue Exception => e
91
- @handlers[:error]&.call(e)
92
- sleep(timeout)
93
- timeout *= 2
73
+ if @auto_reconnect && @engines_on
74
+ EM.add_timer(reconnect_delay) do
75
+ @connection_attempts += 1
76
+ @handlers[:reconnect]&.call
77
+ connect
78
+ end
79
+ else
80
+ @engines_on = false
81
+ @handlers[:disconnect]&.call
82
+ EM.stop_event_loop unless @ws
83
+ end
94
84
  end
95
85
  end
96
-
97
- @last_update = Time.now
98
86
  end
99
87
 
100
88
  def disconnect
101
- return unless @websocket
102
-
103
- @heartbeat_thread&.kill
104
- @heartbeat_thread = nil
89
+ return unless EM.reactor_running?
105
90
 
106
- @websocket.close
107
- @websocket = nil
108
- end
109
-
110
- def notify_heartbeat
111
- @heartbeat_mutex.synchronize { @last_update = Time.now }
91
+ @engines_on = false
92
+ EM.stop_event_loop
112
93
  end
113
94
 
114
95
  alias close disconnect
@@ -144,6 +125,14 @@ module Skyfall
144
125
 
145
126
  private
146
127
 
128
+ def reconnect_delay
129
+ if @connection_attempts == 0
130
+ 0
131
+ else
132
+ [2 ** (@connection_attempts - 1), MAX_RECONNECT_INTERVAL].min
133
+ end
134
+ end
135
+
147
136
  def build_websocket_url
148
137
  url = "wss://#{@server}/xrpc/#{@endpoint}"
149
138
  url += "?cursor=#{@cursor}" if @cursor
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Skyfall
4
- VERSION = "0.1.3"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skyfall
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kuba Suder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-04 00:00:00.000000000 Z
11
+ date: 2023-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base32
@@ -51,25 +51,19 @@ dependencies:
51
51
  - !ruby/object:Gem::Version
52
52
  version: 0.5.9.6
53
53
  - !ruby/object:Gem::Dependency
54
- name: websocket-client-simple
54
+ name: faye-websocket
55
55
  requirement: !ruby/object:Gem::Requirement
56
56
  requirements:
57
57
  - - "~>"
58
58
  - !ruby/object:Gem::Version
59
- version: '0.6'
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: 0.6.1
59
+ version: 0.11.2
63
60
  type: :runtime
64
61
  prerelease: false
65
62
  version_requirements: !ruby/object:Gem::Requirement
66
63
  requirements:
67
64
  - - "~>"
68
65
  - !ruby/object:Gem::Version
69
- version: '0.6'
70
- - - ">="
71
- - !ruby/object:Gem::Version
72
- version: 0.6.1
66
+ version: 0.11.2
73
67
  description: "\n Skyfall is a Ruby library for connecting to the \"firehose\" of
74
68
  the Bluesky social network, i.e. a websocket which\n streams all new posts and
75
69
  everything else happening on the Bluesky network in real time. The code connects