brasa 0.4.2 → 0.5.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/lib/brasa/commands/deploy.rb +43 -21
- data/lib/brasa/commands/up.rb +86 -42
- data/lib/brasa/version.rb +1 -1
- data/lib/brasa/websocket/cable_client.rb +146 -0
- metadata +16 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f58d1ef47800a723afab0a3b260562f7704a4b72e0ac364471a0dcc2b0445078
|
|
4
|
+
data.tar.gz: c1c9063b7c415605ab60e4bf2deb7274e6780c4bcf7ed7ad755b609c24d2c845
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 60d66b1edd7299319e0ae56964e9b1595a18f7c49879aca09bdf02f5d023d256a31d3ce0d75719964fef60dfcbc55517497fb715ee2c778feacf3648b118742b
|
|
7
|
+
data.tar.gz: 10b6eed8ee2bf1236e28c83ab98d0d4151da0d3a59bb6efcfb01af585f92a24339a1a53bd7f7e01f5dfc24d7ef9a718e84b19211afda4e3425d5cd39c3ae7b9a
|
|
@@ -5,7 +5,8 @@ module Brasa
|
|
|
5
5
|
module Commands
|
|
6
6
|
class Deploy < Base
|
|
7
7
|
POLL_INTERVAL = 5
|
|
8
|
-
|
|
8
|
+
DEPLOY_TIMEOUT = 1800
|
|
9
|
+
DEPLOY_MAX_POLLS = 360
|
|
9
10
|
|
|
10
11
|
def execute(options = {})
|
|
11
12
|
require_auth!
|
|
@@ -13,18 +14,16 @@ module Brasa
|
|
|
13
14
|
|
|
14
15
|
info("Empacotando código...")
|
|
15
16
|
archive_path = SourcePacker.pack
|
|
16
|
-
|
|
17
17
|
size_kb = File.size(archive_path) / 1024
|
|
18
18
|
info("Enviando #{size_kb}KB para o servidor...")
|
|
19
19
|
|
|
20
|
-
deploy = api.upload(
|
|
21
|
-
"/api/v1/apps/#{slug}/deploys",
|
|
20
|
+
deploy = api.upload("/api/v1/apps/#{slug}/deploys",
|
|
22
21
|
file_path: archive_path,
|
|
23
|
-
params: { branch: options["branch"] || project_config[:branch] || "main" }
|
|
24
|
-
)
|
|
25
|
-
info("
|
|
22
|
+
params: { branch: options["branch"] || project_config[:branch] || "main" })
|
|
23
|
+
info("Deploy ##{deploy["id"]} criado.")
|
|
24
|
+
info(" Na fila...")
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
wait_for_deploy_complete(slug, deploy["id"])
|
|
28
27
|
rescue Api::Client::ApiError => e
|
|
29
28
|
error("Erro: #{e.message}")
|
|
30
29
|
ensure
|
|
@@ -33,24 +32,51 @@ module Brasa
|
|
|
33
32
|
|
|
34
33
|
private
|
|
35
34
|
|
|
36
|
-
def
|
|
35
|
+
def wait_for_deploy_complete(slug, deploy_id)
|
|
36
|
+
ws = connect_websocket
|
|
37
|
+
started = Time.now
|
|
38
|
+
|
|
39
|
+
ws.on_log { |msg| print msg["line"] + "\n" if msg["line"] }
|
|
40
|
+
ws.subscribe("DeployLogChannel", deploy_id: deploy_id)
|
|
41
|
+
|
|
42
|
+
status = ws.wait_for("DeployStatusChannel",
|
|
43
|
+
params: { deploy_id: deploy_id },
|
|
44
|
+
until_status: %w[live failed],
|
|
45
|
+
timeout: DEPLOY_TIMEOUT)
|
|
46
|
+
|
|
47
|
+
elapsed = (Time.now - started).to_i
|
|
48
|
+
if status == "live"
|
|
49
|
+
success("\nDeploy concluído com sucesso! (#{elapsed}s)")
|
|
50
|
+
else
|
|
51
|
+
error("\nDeploy falhou.")
|
|
52
|
+
end
|
|
53
|
+
rescue Brasa::Websocket::CableClient::ConnectionError => e
|
|
54
|
+
$stderr.puts "\n [WebSocket indisponível: #{e.message}. Usando polling...]"
|
|
55
|
+
wait_for_deploy_polling(slug, deploy_id)
|
|
56
|
+
ensure
|
|
57
|
+
ws&.disconnect
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def connect_websocket
|
|
61
|
+
require "brasa/websocket/cable_client"
|
|
62
|
+
Brasa::Websocket::CableClient.new.tap(&:connect!)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def wait_for_deploy_polling(slug, deploy_id)
|
|
37
66
|
started = Time.now
|
|
38
67
|
last_status = nil
|
|
39
68
|
DEPLOY_MAX_POLLS.times do |i|
|
|
40
69
|
deploy = api.get("/api/v1/apps/#{slug}/deploys/#{deploy_id}")
|
|
41
|
-
|
|
42
70
|
case deploy["status"]
|
|
43
71
|
when "live"
|
|
44
|
-
|
|
45
|
-
success("\nDeploy concluído com sucesso! (#{elapsed}s)")
|
|
72
|
+
success("\nDeploy concluído com sucesso! (#{(Time.now - started).to_i}s)")
|
|
46
73
|
return
|
|
47
74
|
when "failed"
|
|
48
75
|
error("\nDeploy falhou.")
|
|
49
76
|
return
|
|
50
77
|
end
|
|
51
|
-
|
|
52
78
|
if deploy["status"] != last_status
|
|
53
|
-
print "\n #{status_label(deploy["status"])}"
|
|
79
|
+
print "\n #{status_label(deploy["status"])}"
|
|
54
80
|
last_status = deploy["status"]
|
|
55
81
|
end
|
|
56
82
|
print "."
|
|
@@ -60,21 +86,17 @@ module Brasa
|
|
|
60
86
|
print "!"
|
|
61
87
|
sleep(POLL_INTERVAL)
|
|
62
88
|
end
|
|
63
|
-
|
|
64
|
-
error("\nTimeout aguardando deploy (#{elapsed}s). O processo pode ainda estar rodando — verifique com: brasa status")
|
|
89
|
+
error("\nTimeout (#{(Time.now - started).to_i}s). Verifique com: brasa status")
|
|
65
90
|
end
|
|
66
91
|
|
|
67
92
|
def status_label(status)
|
|
68
|
-
{ "queued" => "Na fila...",
|
|
69
|
-
"building" => "Construindo imagem...",
|
|
93
|
+
{ "queued" => "Na fila...", "building" => "Construindo imagem...",
|
|
70
94
|
"deploying" => "Deployando..." }[status] || status
|
|
71
95
|
end
|
|
72
96
|
|
|
73
97
|
def show_elapsed(started)
|
|
74
98
|
elapsed = (Time.now - started).to_i
|
|
75
|
-
|
|
76
|
-
sec = elapsed % 60
|
|
77
|
-
print " (#{min}m#{sec}s)"
|
|
99
|
+
print " (#{elapsed / 60}m#{elapsed % 60}s)"
|
|
78
100
|
end
|
|
79
101
|
end
|
|
80
102
|
end
|
data/lib/brasa/commands/up.rb
CHANGED
|
@@ -5,8 +5,10 @@ module Brasa
|
|
|
5
5
|
module Commands
|
|
6
6
|
class Up < Base
|
|
7
7
|
POLL_INTERVAL = 5
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
PROVISION_TIMEOUT = 1200
|
|
9
|
+
DEPLOY_TIMEOUT = 1800
|
|
10
|
+
PROVISION_MAX_POLLS = 240
|
|
11
|
+
DEPLOY_MAX_POLLS = 360
|
|
10
12
|
|
|
11
13
|
def execute(options = {})
|
|
12
14
|
require_auth!
|
|
@@ -19,7 +21,8 @@ module Brasa
|
|
|
19
21
|
info("Iniciando deploy...")
|
|
20
22
|
else
|
|
21
23
|
info("Provisionando infraestrutura...")
|
|
22
|
-
|
|
24
|
+
trigger_provision(slug) if %w[pending error].include?(@app["status"])
|
|
25
|
+
unless wait_for_provisioning(@app["id"], slug)
|
|
23
26
|
return
|
|
24
27
|
end
|
|
25
28
|
success("Infraestrutura provisionada!")
|
|
@@ -27,8 +30,9 @@ module Brasa
|
|
|
27
30
|
end
|
|
28
31
|
|
|
29
32
|
deploy = trigger_deploy(slug)
|
|
33
|
+
info(" Na fila...")
|
|
30
34
|
|
|
31
|
-
if
|
|
35
|
+
if wait_for_deploy_complete(slug, deploy["id"])
|
|
32
36
|
subdomain = @app["subdomain"] || slug
|
|
33
37
|
success("Deploy concluído! App disponível em https://#{subdomain}.usebrasa.com.br")
|
|
34
38
|
end
|
|
@@ -50,23 +54,22 @@ module Brasa
|
|
|
50
54
|
create_app(config)
|
|
51
55
|
end
|
|
52
56
|
|
|
57
|
+
def trigger_provision(slug)
|
|
58
|
+
api.post("/api/v1/apps/#{slug}/provision")
|
|
59
|
+
rescue Api::Client::ApiError
|
|
60
|
+
end
|
|
61
|
+
|
|
53
62
|
def ensure_repo_url(slug)
|
|
54
63
|
repo = detect_git_remote
|
|
55
64
|
return unless repo
|
|
56
|
-
|
|
57
65
|
api.patch("/api/v1/apps/#{slug}", body: { app: { repo_url: repo } })
|
|
58
66
|
rescue Api::Client::ApiError
|
|
59
|
-
# Não bloquear o fluxo se falhar ao atualizar repo
|
|
60
67
|
end
|
|
61
68
|
|
|
62
69
|
def create_app(config)
|
|
63
70
|
app_params = {
|
|
64
|
-
name: config[:app],
|
|
65
|
-
|
|
66
|
-
preset: config[:preset],
|
|
67
|
-
region: config[:region],
|
|
68
|
-
repo_url: detect_git_remote,
|
|
69
|
-
repo_branch: config[:branch]
|
|
71
|
+
name: config[:app], stack: config[:stack], preset: config[:preset],
|
|
72
|
+
region: config[:region], repo_url: detect_git_remote, repo_branch: config[:branch]
|
|
70
73
|
}
|
|
71
74
|
app_params[:database_engine] = config[:database_engine] if config[:database_engine]
|
|
72
75
|
api.post("/api/v1/apps", body: { app: app_params })
|
|
@@ -77,13 +80,8 @@ module Brasa
|
|
|
77
80
|
archive_path = SourcePacker.pack
|
|
78
81
|
size_kb = File.size(archive_path) / 1024
|
|
79
82
|
info("Enviando #{size_kb}KB para o servidor...")
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
"/api/v1/apps/#{slug}/deploys",
|
|
83
|
-
file_path: archive_path,
|
|
84
|
-
params: { branch: project_config[:branch] || "main" }
|
|
85
|
-
)
|
|
86
|
-
deploy
|
|
83
|
+
api.upload("/api/v1/apps/#{slug}/deploys", file_path: archive_path,
|
|
84
|
+
params: { branch: project_config[:branch] || "main" })
|
|
87
85
|
ensure
|
|
88
86
|
FileUtils.rm_f(archive_path) if archive_path
|
|
89
87
|
end
|
|
@@ -93,18 +91,73 @@ module Brasa
|
|
|
93
91
|
remote.empty? ? nil : remote
|
|
94
92
|
end
|
|
95
93
|
|
|
96
|
-
|
|
94
|
+
# ── WebSocket methods ──
|
|
95
|
+
|
|
96
|
+
def wait_for_provisioning(app_id, slug)
|
|
97
|
+
ws = connect_websocket
|
|
98
|
+
status = ws.wait_for("ProvisionStatusChannel",
|
|
99
|
+
params: { app_id: app_id },
|
|
100
|
+
until_status: %w[active error],
|
|
101
|
+
timeout: PROVISION_TIMEOUT)
|
|
102
|
+
|
|
103
|
+
if status == "active"
|
|
104
|
+
true
|
|
105
|
+
else
|
|
106
|
+
error("\nErro no provisionamento.")
|
|
107
|
+
false
|
|
108
|
+
end
|
|
109
|
+
rescue Brasa::Websocket::CableClient::ConnectionError => e
|
|
110
|
+
warn_fallback(e)
|
|
111
|
+
wait_for_provisioning_polling(slug)
|
|
112
|
+
ensure
|
|
113
|
+
ws&.disconnect
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def wait_for_deploy_complete(slug, deploy_id)
|
|
117
|
+
ws = connect_websocket
|
|
118
|
+
started = Time.now
|
|
119
|
+
|
|
120
|
+
ws.on_log { |msg| print msg["line"] + "\n" if msg["line"] }
|
|
121
|
+
ws.subscribe("DeployLogChannel", deploy_id: deploy_id)
|
|
122
|
+
|
|
123
|
+
status = ws.wait_for("DeployStatusChannel",
|
|
124
|
+
params: { deploy_id: deploy_id },
|
|
125
|
+
until_status: %w[live failed],
|
|
126
|
+
timeout: DEPLOY_TIMEOUT)
|
|
127
|
+
|
|
128
|
+
if status == "live"
|
|
129
|
+
true
|
|
130
|
+
else
|
|
131
|
+
error("\nDeploy falhou.")
|
|
132
|
+
false
|
|
133
|
+
end
|
|
134
|
+
rescue Brasa::Websocket::CableClient::ConnectionError => e
|
|
135
|
+
warn_fallback(e)
|
|
136
|
+
wait_for_deploy_polling(slug, deploy_id)
|
|
137
|
+
ensure
|
|
138
|
+
ws&.disconnect
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def connect_websocket
|
|
142
|
+
require "brasa/websocket/cable_client"
|
|
143
|
+
Brasa::Websocket::CableClient.new.tap(&:connect!)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def warn_fallback(err)
|
|
147
|
+
$stderr.puts "\n [WebSocket indisponível: #{err.message}. Usando polling...]"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# ── Fallback polling ──
|
|
151
|
+
|
|
152
|
+
def wait_for_provisioning_polling(slug)
|
|
97
153
|
started = Time.now
|
|
98
154
|
last_status = nil
|
|
99
155
|
PROVISION_MAX_POLLS.times do |i|
|
|
100
156
|
app = api.get("/api/v1/apps/#{slug}")
|
|
101
157
|
return true if app["status"] == "active"
|
|
102
|
-
if app["status"] == "error"
|
|
103
|
-
error("\nErro no provisionamento.")
|
|
104
|
-
return false
|
|
105
|
-
end
|
|
158
|
+
return (error("\nErro no provisionamento."); false) if app["status"] == "error"
|
|
106
159
|
if app["status"] != last_status
|
|
107
|
-
print "\n #{status_label(app["status"])}"
|
|
160
|
+
print "\n #{status_label(app["status"])}"
|
|
108
161
|
last_status = app["status"]
|
|
109
162
|
end
|
|
110
163
|
print "."
|
|
@@ -114,23 +167,19 @@ module Brasa
|
|
|
114
167
|
print "!"
|
|
115
168
|
sleep(POLL_INTERVAL)
|
|
116
169
|
end
|
|
117
|
-
|
|
118
|
-
error("\nTimeout aguardando provisionamento (#{elapsed}s). O processo pode ainda estar rodando no servidor — verifique com: brasa status")
|
|
170
|
+
error("\nTimeout (#{(Time.now - started).to_i}s). Verifique com: brasa status")
|
|
119
171
|
false
|
|
120
172
|
end
|
|
121
173
|
|
|
122
|
-
def
|
|
174
|
+
def wait_for_deploy_polling(slug, deploy_id)
|
|
123
175
|
started = Time.now
|
|
124
176
|
last_status = nil
|
|
125
177
|
DEPLOY_MAX_POLLS.times do |i|
|
|
126
178
|
deploy = api.get("/api/v1/apps/#{slug}/deploys/#{deploy_id}")
|
|
127
179
|
return true if deploy["status"] == "live"
|
|
128
|
-
if deploy["status"] == "failed"
|
|
129
|
-
error("\nDeploy falhou.")
|
|
130
|
-
return false
|
|
131
|
-
end
|
|
180
|
+
return (error("\nDeploy falhou."); false) if deploy["status"] == "failed"
|
|
132
181
|
if deploy["status"] != last_status
|
|
133
|
-
print "\n #{status_label(deploy["status"])}"
|
|
182
|
+
print "\n #{status_label(deploy["status"])}"
|
|
134
183
|
last_status = deploy["status"]
|
|
135
184
|
end
|
|
136
185
|
print "."
|
|
@@ -140,24 +189,19 @@ module Brasa
|
|
|
140
189
|
print "!"
|
|
141
190
|
sleep(POLL_INTERVAL)
|
|
142
191
|
end
|
|
143
|
-
|
|
144
|
-
error("\nTimeout aguardando deploy (#{elapsed}s). O processo pode ainda estar rodando no servidor — verifique com: brasa status")
|
|
192
|
+
error("\nTimeout (#{(Time.now - started).to_i}s). Verifique com: brasa status")
|
|
145
193
|
false
|
|
146
194
|
end
|
|
147
195
|
|
|
148
196
|
def status_label(status)
|
|
149
|
-
{ "pending" => "Aguardando...",
|
|
150
|
-
"
|
|
151
|
-
"queued" => "Na fila...",
|
|
152
|
-
"building" => "Construindo imagem...",
|
|
197
|
+
{ "pending" => "Aguardando...", "provisioning" => "Provisionando VM...",
|
|
198
|
+
"queued" => "Na fila...", "building" => "Construindo imagem...",
|
|
153
199
|
"deploying" => "Deployando..." }[status] || status
|
|
154
200
|
end
|
|
155
201
|
|
|
156
202
|
def show_elapsed(started)
|
|
157
203
|
elapsed = (Time.now - started).to_i
|
|
158
|
-
|
|
159
|
-
sec = elapsed % 60
|
|
160
|
-
print " (#{min}m#{sec}s)"
|
|
204
|
+
print " (#{elapsed / 60}m#{elapsed % 60}s)"
|
|
161
205
|
end
|
|
162
206
|
end
|
|
163
207
|
end
|
data/lib/brasa/version.rb
CHANGED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
require "websocket-client-simple"
|
|
2
|
+
require "json"
|
|
3
|
+
|
|
4
|
+
module Brasa
|
|
5
|
+
module Websocket
|
|
6
|
+
class CableClient
|
|
7
|
+
class ConnectionError < StandardError; end
|
|
8
|
+
|
|
9
|
+
RECONNECT_DELAYS = [1, 3, 10].freeze
|
|
10
|
+
|
|
11
|
+
def initialize(api_url: nil, token: nil)
|
|
12
|
+
@api_url = api_url || Brasa::Config.api_url
|
|
13
|
+
@token = token || Brasa::Config.token
|
|
14
|
+
@subscriptions = {}
|
|
15
|
+
@connected = false
|
|
16
|
+
@log_callback = nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def connect!
|
|
20
|
+
raise ConnectionError, "Token nao encontrado. Execute `brasa login`." unless @token
|
|
21
|
+
|
|
22
|
+
ws_url = @api_url.sub(%r{^https?://}, "wss://").chomp("/") + "/cable"
|
|
23
|
+
@ws = WebSocket::Client::Simple.connect(ws_url, headers: {
|
|
24
|
+
"Authorization" => "Bearer #{@token}",
|
|
25
|
+
"Origin" => @api_url
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
setup_handlers
|
|
29
|
+
wait_for_welcome
|
|
30
|
+
self
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def subscribe(channel, params = {}, &callback)
|
|
34
|
+
identifier = { channel: channel }.merge(params).to_json
|
|
35
|
+
@subscriptions[identifier] = callback
|
|
36
|
+
send_command("subscribe", identifier)
|
|
37
|
+
identifier
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def wait_for(channel, params: {}, until_status: [], timeout: 1800)
|
|
41
|
+
result = nil
|
|
42
|
+
identifier = subscribe(channel, params) do |msg|
|
|
43
|
+
status = msg["status"]
|
|
44
|
+
result = status if until_status.include?(status)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
deadline = Time.now + timeout
|
|
48
|
+
loop do
|
|
49
|
+
return result if result
|
|
50
|
+
raise ConnectionError, "Timeout aguardando status (#{timeout}s)" if Time.now > deadline
|
|
51
|
+
|
|
52
|
+
unless @connected
|
|
53
|
+
reconnect!
|
|
54
|
+
# Re-subscribe after reconnect
|
|
55
|
+
@subscriptions.each_key { |id| send_command("subscribe", id) }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
sleep 0.2
|
|
59
|
+
end
|
|
60
|
+
ensure
|
|
61
|
+
send_command("unsubscribe", identifier) if identifier && @connected
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def on_log(&block)
|
|
65
|
+
@log_callback = block
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def disconnect
|
|
69
|
+
@ws&.close
|
|
70
|
+
@connected = false
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def setup_handlers
|
|
76
|
+
client = self
|
|
77
|
+
|
|
78
|
+
@ws.on :message do |msg|
|
|
79
|
+
begin
|
|
80
|
+
data = JSON.parse(msg.data)
|
|
81
|
+
client.send(:handle_message, data)
|
|
82
|
+
rescue JSON::ParserError
|
|
83
|
+
$stderr.puts "[WS] Mensagem malformada ignorada: #{msg.data.to_s.truncate(100)}" if ENV["BRASA_DEBUG"]
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
@ws.on :close do |_|
|
|
88
|
+
client.instance_variable_set(:@connected, false)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
@ws.on :error do |_|
|
|
92
|
+
client.instance_variable_set(:@connected, false)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def handle_message(data)
|
|
97
|
+
case data["type"]
|
|
98
|
+
when "welcome"
|
|
99
|
+
@connected = true
|
|
100
|
+
when "ping"
|
|
101
|
+
# keepalive — noop
|
|
102
|
+
when "confirm_subscription"
|
|
103
|
+
# confirmed
|
|
104
|
+
when "reject_subscription"
|
|
105
|
+
@connected = false
|
|
106
|
+
else
|
|
107
|
+
identifier = data["identifier"]
|
|
108
|
+
message = data["message"]
|
|
109
|
+
return unless message
|
|
110
|
+
|
|
111
|
+
callback = @subscriptions[identifier]
|
|
112
|
+
callback&.call(message)
|
|
113
|
+
|
|
114
|
+
@log_callback&.call(message) if message["line"]
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def wait_for_welcome
|
|
119
|
+
deadline = Time.now + 10
|
|
120
|
+
loop do
|
|
121
|
+
return if @connected
|
|
122
|
+
raise ConnectionError, "Timeout na conexao WebSocket" if Time.now > deadline
|
|
123
|
+
sleep 0.1
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def reconnect!
|
|
128
|
+
RECONNECT_DELAYS.each do |delay|
|
|
129
|
+
sleep delay
|
|
130
|
+
begin
|
|
131
|
+
connect!
|
|
132
|
+
return
|
|
133
|
+
rescue StandardError
|
|
134
|
+
next
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
raise ConnectionError, "Falha na reconexao apos #{RECONNECT_DELAYS.size} tentativas"
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def send_command(command, identifier)
|
|
141
|
+
return unless @ws&.open?
|
|
142
|
+
@ws.send({ command: command, identifier: identifier }.to_json)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: brasa
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brasa
|
|
@@ -107,6 +107,20 @@ dependencies:
|
|
|
107
107
|
- - "~>"
|
|
108
108
|
- !ruby/object:Gem::Version
|
|
109
109
|
version: '0.8'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: websocket-client-simple
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - "~>"
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0.8'
|
|
117
|
+
type: :runtime
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - "~>"
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0.8'
|
|
110
124
|
- !ruby/object:Gem::Dependency
|
|
111
125
|
name: rspec
|
|
112
126
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -168,6 +182,7 @@ files:
|
|
|
168
182
|
- lib/brasa/config.rb
|
|
169
183
|
- lib/brasa/source_packer.rb
|
|
170
184
|
- lib/brasa/version.rb
|
|
185
|
+
- lib/brasa/websocket/cable_client.rb
|
|
171
186
|
homepage: https://usebrasa.com.br
|
|
172
187
|
licenses:
|
|
173
188
|
- MIT
|