|
7 | 7 | "fmt" |
8 | 8 | "net/http" |
9 | 9 | "net/url" |
| 10 | + "sync" |
10 | 11 | "time" |
11 | 12 |
|
12 | 13 | "github.com/coder/websocket/wsjson" |
@@ -113,6 +114,11 @@ var ( |
113 | 114 | ) |
114 | 115 | ) |
115 | 116 |
|
| 117 | +var ( |
| 118 | + cloudDisconnectChan chan error |
| 119 | + cloudDisconnectLock = &sync.Mutex{} |
| 120 | +) |
| 121 | + |
116 | 122 | func cloudResetMetrics(established bool) { |
117 | 123 | metricCloudConnectionLastPingTimestamp.Set(-1) |
118 | 124 | metricCloudConnectionLastPingDuration.Set(-1) |
@@ -213,6 +219,24 @@ func handleCloudRegister(c *gin.Context) { |
213 | 219 | c.JSON(200, gin.H{"message": "Cloud registration successful"}) |
214 | 220 | } |
215 | 221 |
|
| 222 | +func disconnectCloud(reason error) { |
| 223 | + cloudDisconnectLock.Lock() |
| 224 | + defer cloudDisconnectLock.Unlock() |
| 225 | + |
| 226 | + if cloudDisconnectChan == nil { |
| 227 | + cloudLogger.Tracef("cloud disconnect channel is not set, no need to disconnect") |
| 228 | + return |
| 229 | + } |
| 230 | + |
| 231 | + // just in case the channel is closed, we don't want to panic |
| 232 | + defer func() { |
| 233 | + if r := recover(); r != nil { |
| 234 | + cloudLogger.Infof("cloud disconnect channel is closed, no need to disconnect: %v", r) |
| 235 | + } |
| 236 | + }() |
| 237 | + cloudDisconnectChan <- reason |
| 238 | +} |
| 239 | + |
216 | 240 | func runWebsocketClient() error { |
217 | 241 | if config.CloudToken == "" { |
218 | 242 | time.Sleep(5 * time.Second) |
@@ -275,6 +299,23 @@ func runWebsocketClient() error { |
275 | 299 | metricCloudConnectionLastPingTimestamp.SetToCurrentTime() |
276 | 300 | } |
277 | 301 | }() |
| 302 | + |
| 303 | + // create a channel to receive the disconnect event, once received, we cancelRun |
| 304 | + cloudDisconnectChan = make(chan error) |
| 305 | + defer func() { |
| 306 | + close(cloudDisconnectChan) |
| 307 | + cloudDisconnectChan = nil |
| 308 | + }() |
| 309 | + go func() { |
| 310 | + for err := range cloudDisconnectChan { |
| 311 | + if err == nil { |
| 312 | + continue |
| 313 | + } |
| 314 | + cloudLogger.Infof("disconnecting from cloud due to: %v", err) |
| 315 | + cancelRun() |
| 316 | + } |
| 317 | + }() |
| 318 | + |
278 | 319 | for { |
279 | 320 | typ, msg, err := c.Read(runCtx) |
280 | 321 | if err != nil { |
@@ -448,6 +489,9 @@ func rpcDeregisterDevice() error { |
448 | 489 | return fmt.Errorf("failed to save configuration after deregistering: %w", err) |
449 | 490 | } |
450 | 491 |
|
| 492 | + cloudLogger.Infof("device deregistered, disconnecting from cloud") |
| 493 | + disconnectCloud(fmt.Errorf("device deregistered")) |
| 494 | + |
451 | 495 | return nil |
452 | 496 | } |
453 | 497 |
|
|
0 commit comments