Skip to content

Commit 1ed71a4

Browse files
authored
SSE Edge (#4119)
* Ask SSE load balancer for the cluster / SSE websocket. * SSE loading screen: add SSE edge logic. * Starter: remove unneeded sandboxId from the SSE websocket query.
1 parent 0da67e4 commit 1ed71a4

File tree

6 files changed

+57
-27
lines changed

6 files changed

+57
-27
lines changed

packages/executors/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
},
2121
"dependencies": {
2222
"@codesandbox/common": "^1.0.8",
23+
"axios": "^0.19.2",
2324
"codesandbox-api": "0.0.24",
2425
"debug": "^4.1.1",
2526
"socket.io-client": "^2.2.0"

packages/executors/src/serverExecutor.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import io from 'socket.io-client';
22
import { dispatch } from 'codesandbox-api';
33
import _debug from 'debug';
4+
import axios from 'axios';
45

56
import { IExecutor, IFiles, ISetupParams } from './executor';
67

@@ -71,20 +72,18 @@ export class ServerExecutor implements IExecutor {
7172
this.token = this.retrieveSSEToken();
7273
}
7374

74-
private initializeSocket() {
75+
private async initializeSocket() {
7576
if (!this.sandboxId) {
7677
throw new Error('initializeSocket: sandboxId is not defined');
7778
}
78-
7979
const usedHost = this.host || 'https://codesandbox.io';
80-
const sseHost = usedHost.replace('https://', 'https://sse.');
80+
const sseLbHost = usedHost.replace('https://', 'https://sse-lb.');
81+
const res = await axios.get(`${sseLbHost}/api/cluster/${this.sandboxId}`);
82+
const sseHost = res.data.hostname;
8183

8284
this.socket = io(sseHost, {
8385
autoConnect: false,
8486
transports: ['websocket', 'polling'],
85-
query: {
86-
sandboxid: this.sandboxId,
87-
},
8887
});
8988
}
9089

@@ -100,7 +99,7 @@ export class ServerExecutor implements IExecutor {
10099
await this.dispose();
101100
await tick();
102101

103-
this.initializeSocket();
102+
await this.initializeSocket();
104103
}
105104

106105
public async setup() {
@@ -110,8 +109,10 @@ export class ServerExecutor implements IExecutor {
110109
}
111110

112111
public async dispose() {
113-
this.socket?.removeAllListeners();
114-
this.socket?.close();
112+
if (this.socket) {
113+
this.socket.removeAllListeners();
114+
this.socket.close();
115+
}
115116
}
116117

117118
public updateFiles(newFiles: IFiles) {
@@ -131,11 +132,15 @@ export class ServerExecutor implements IExecutor {
131132
}
132133

133134
public emit(event: string, data?: any) {
134-
this.socket?.emit(event, data);
135+
if (this.socket) {
136+
this.socket.emit(event, data);
137+
}
135138
}
136139

137140
public on(event: string, listener: (data: any) => void) {
138-
this.socket?.on(event, listener);
141+
if (this.socket) {
142+
this.socket.on(event, listener);
143+
}
139144
}
140145

141146
private openSocket() {
@@ -144,7 +149,7 @@ export class ServerExecutor implements IExecutor {
144149
}
145150

146151
return new Promise<void>((resolve, reject) => {
147-
this.socket?.on('connect', async () => {
152+
this.socket!.on('connect', async () => {
148153
try {
149154
if (this.connectTimeout) {
150155
clearTimeout(this.connectTimeout);
@@ -160,7 +165,7 @@ export class ServerExecutor implements IExecutor {
160165
}
161166
});
162167

163-
this.socket?.on('sandbox:start', () => {
168+
this.socket!.on('sandbox:start', () => {
164169
sseTerminalMessage(`Sandbox ${this.sandboxId} started`);
165170
});
166171

standalone-packages/sse-loading-screen/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"license": "MIT",
66
"dependencies": {
77
"@codesandbox/common": "^1.0.8",
8+
"axios": "^0.19.2",
89
"babel-plugin-emotion": "^9.2.10",
910
"emotion": "^9.2.10",
1011
"gsap": "^2.0.2",

standalone-packages/sse-loading-screen/src/index.js

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import AttrPlugin from 'gsap/AttrPlugin';
1111
import { Power3 } from 'gsap/EasePack';
1212
import TweenLite from 'gsap/TweenLite';
1313
import TimelineLite from 'gsap/TimelineLite';
14+
import axios from 'axios';
1415

1516
import { isStandalone } from 'codesandbox-api'
1617
import getTemplate from '@codesandbox/common/lib/templates';
@@ -36,10 +37,11 @@ if (process.env.NODE_ENV === 'development') {
3637
hostParts = window.location.hostname.split('.');
3738
}
3839
const rootDomain = `codesandbox.${hostParts[hostParts.length - 1]}`;
39-
const domain = `sse.${rootDomain}`;
40-
// parses sandboxid[-port]
41-
const sandbox = hostParts[0].replace(/-\d+/, '');
40+
const sseLbHost = `sse-lb.${rootDomain}`;
41+
// parses sandboxId[-port]
42+
const sandboxId = hostParts[0].replace(/-\d+/, '');
4243
const port = hostParts[0].replace(/^\w+-?/, '');
44+
// console.log('sandboxId:', sandboxId, 'port:', port);
4345
const lastLoadedAt = parseInt(localStorage.getItem('last_loaded_at'), 10);
4446
const now = Date.now();
4547
let isLoop = false;
@@ -236,18 +238,18 @@ async function start() {
236238

237239
term.fit();
238240

239-
const socket = io(`https://${domain}`, {
241+
const res = await axios.get(`https://${sseLbHost}/api/cluster/${sandboxId}`);
242+
const sseHost = res.data.hostname;
243+
244+
const socket = io(`https://${sseHost}`, {
240245
autoConnect: false,
241246
transports: ['websocket'],
242247
reconnectionAttempts: 5,
243248
reconnectionDelayMax: 32000,
244-
query: {
245-
sandboxid: sandbox,
246-
},
247249
});
248250

249251
socket.on('connect', () => {
250-
socket.emit('sandbox', { id: sandbox });
252+
socket.emit('sandbox', { id: sandboxId });
251253
socket.emit('sandbox:start');
252254
});
253255

@@ -258,7 +260,7 @@ async function start() {
258260
}
259261
reloadTimeout = setTimeout(() => {
260262
window.location.reload(true);
261-
}, 10 * SECOND);
263+
}, 15 * SECOND);
262264
});
263265

264266
socket.on('sandbox:error', ({ message, unrecoverable }) => {
@@ -341,11 +343,11 @@ if (isLoop) {
341343
localStorage.setItem('last_loaded_at', now);
342344

343345
if (process.env.NODE_ENV === 'production') {
344-
fetch(`https://${rootDomain}/api/v1/sandboxes/${sandbox}/slim`)
346+
fetch(`https://${rootDomain}/api/v1/sandboxes/${sandboxId}/slim`)
345347
.then(res => {
346348
if (res.status === 404) {
347349
if (isStandalone) {
348-
show404(sandbox);
350+
show404(sandboxId);
349351
}
350352

351353
return {};
@@ -355,7 +357,7 @@ if (isLoop) {
355357
})
356358
.then(json => {
357359
if (Object.keys(json) > 0 && !json.is_sse) {
358-
window.location.replace(`https://${sandbox}.${rootDomain}/`);
360+
window.location.replace(`https://${sandboxId}.${rootDomain}/`);
359361
}
360362
if (json.template) {
361363
const templateDef = getTemplate(json.template);

standalone-packages/sse-loading-screen/yarn.lock

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,13 @@ autoprefixer@^6.3.1:
412412
postcss "^5.2.16"
413413
postcss-value-parser "^3.2.3"
414414

415+
axios@^0.19.2:
416+
version "0.19.2"
417+
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
418+
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
419+
dependencies:
420+
follow-redirects "1.5.10"
421+
415422
babel-code-frame@^6.26.0:
416423
version "6.26.0"
417424
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
@@ -2005,7 +2012,7 @@ [email protected], debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.
20052012
dependencies:
20062013
ms "2.0.0"
20072014

2008-
debug@~3.1.0:
2015+
debug@=3.1.0, debug@~3.1.0:
20092016
version "3.1.0"
20102017
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
20112018
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
@@ -2477,6 +2484,13 @@ flatten@^1.0.2:
24772484
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
24782485
integrity sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=
24792486

2487+
2488+
version "1.5.10"
2489+
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
2490+
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
2491+
dependencies:
2492+
debug "=3.1.0"
2493+
24802494
fontfaceobserver@2.*:
24812495
version "2.0.13"
24822496
resolved "https://registry.yarnpkg.com/fontfaceobserver/-/fontfaceobserver-2.0.13.tgz#47adbb343261eda98cb44db2152196ff124d3221"

yarn.lock

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6643,7 +6643,7 @@ axe-core@^3.3.2:
66436643
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-3.4.1.tgz#e42623918bb85b5ef674633852cb9029db0309c5"
66446644
integrity sha512-+EhIdwR0hF6aeMx46gFDUy6qyCfsL0DmBrV3Z+LxYbsOd8e1zBaPHa3f9Rbjsz2dEwSBkLw6TwML/CAIIAqRpw==
66456645

6646-
[email protected], axios@^0.19.0:
6646+
66476647
version "0.19.0"
66486648
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8"
66496649
integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==
@@ -6659,6 +6659,13 @@ axios@^0.16.2:
66596659
follow-redirects "^1.2.3"
66606660
is-buffer "^1.1.5"
66616661

6662+
axios@^0.19.0, axios@^0.19.2:
6663+
version "0.19.2"
6664+
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
6665+
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
6666+
dependencies:
6667+
follow-redirects "1.5.10"
6668+
66626669
axobject-query@^2.0.2:
66636670
version "2.0.2"
66646671
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9"

0 commit comments

Comments
 (0)