Skip to content

Commit f4474e7

Browse files
refactor to worker IDs for specific message passing
1 parent 083a2cc commit f4474e7

File tree

5 files changed

+108
-115
lines changed

5 files changed

+108
-115
lines changed

packages/app/src/app/overmind/effects/vscode/SandboxFsSync/index.ts

Lines changed: 61 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ const global = getGlobal() as Window & { BrowserFS: any };
2626
const browserFs = global.BrowserFS.BFSRequire('fs');
2727
const SERVICE_URL = 'https://ata-fetcher.cloud/api/v5/typings';
2828

29-
let lastMTime = new Date(0);
30-
3129
declare global {
3230
interface Window {
3331
BrowserFS: any;
@@ -50,14 +48,25 @@ class SandboxFsSync {
5048
'@types/jest': 'latest',
5149
};
5250

51+
private workerIds: string[] = [];
52+
5353
private isDisposed = false;
54-
private currentSyncId = 0;
5554
private typesInfo: Promise<any>;
5655
constructor(options: SandboxFsSyncOptions) {
5756
this.options = options;
5857
self.addEventListener('message', this.onWorkerMessage);
5958
}
6059

60+
public sync(cb: () => void) {
61+
this.send('reset', {});
62+
this.syncDependencyTypings();
63+
setTimeout(() => {
64+
if (!this.isDisposed) {
65+
cb();
66+
}
67+
}, WAIT_INITIAL_TYPINGS_MS);
68+
}
69+
6170
public getTypes() {
6271
return Object.keys(this.types).reduce(
6372
(aggr, key) => Object.assign(aggr, this.types[key]),
@@ -94,8 +103,6 @@ class SandboxFsSync {
94103
}
95104
});
96105

97-
this.syncSandbox(sandboxFs);
98-
99106
return sandboxFs;
100107
}
101108

@@ -106,7 +113,7 @@ class SandboxFsSync {
106113
this.send('write-file', copy);
107114

108115
if (module.title === 'package.json') {
109-
this.syncDependencyTypings(this.currentSyncId + 1);
116+
this.syncDependencyTypings();
110117
}
111118
}
112119

@@ -139,43 +146,32 @@ class SandboxFsSync {
139146
this.send('mkdir', copy);
140147
}
141148

142-
public async syncTypings(cb: () => void) {
143-
try {
144-
await this.syncDependencyTypings(this.currentSyncId + 1);
145-
} catch (error) {
146-
// Do nothing
147-
}
148-
149-
setTimeout(() => {
150-
if (!this.isDisposed) {
151-
cb();
152-
}
153-
}, WAIT_INITIAL_TYPINGS_MS);
154-
}
155-
156149
private onWorkerMessage = evt => {
157-
if (evt.data.$type === 'sync-types') {
158-
// We pass the current syncId as we want to latch on
159-
// to the existing sync
160-
this.syncDependencyTypings(this.currentSyncId);
150+
if (evt.data.$fs_id && !this.workerIds.includes(evt.data.$fs_id)) {
151+
this.workerIds.push(evt.data.$fs_id);
161152
}
162153

163154
if (evt.data.$type === 'sync-sandbox') {
164-
this.syncSandbox(this.options.getSandboxFs());
155+
this.syncSandbox(this.options.getSandboxFs(), evt.data.$fs_id);
156+
}
157+
158+
if (evt.data.$type === 'sync-types') {
159+
this.send('types-sync', this.getTypes(), evt.data.$fs_id);
165160
}
166161
};
167162

168163
// We sync the FS whenever we create a new one, which happens in different
169164
// scenarios. If a worker is requesting a sync we grab the existing FS from
170165
// the state
171-
private syncSandbox(sandboxFs) {
172-
this.send('sandbox-fs', json(sandboxFs));
166+
private syncSandbox(sandboxFs, id?) {
167+
this.send('sandbox-fs', json(sandboxFs), id);
173168
}
174169

175-
private send(type: string, data: any) {
170+
private send(type: string, data: any, id?: string) {
176171
global.postMessage(
177172
{
178173
$broadcast: true,
174+
$fs_ids: typeof id === 'undefined' ? this.workerIds : [id],
179175
$type: type,
180176
$data: data,
181177
},
@@ -186,15 +182,8 @@ class SandboxFsSync {
186182
// We pass in either existing or new syncId. This allows us to evaluate
187183
// if we are just going to pass existing types or start up a new round
188184
// to fetch types
189-
private async syncDependencyTypings(syncId: number) {
190-
if (syncId === this.currentSyncId) {
191-
this.sendTypes();
192-
return;
193-
}
194-
185+
private async syncDependencyTypings(fsId?) {
195186
try {
196-
this.currentSyncId = syncId;
197-
198187
this.typesInfo = await this.getTypesInfo();
199188
const syncDetails = await this.getDependencyTypingsSyncDetails();
200189

@@ -205,7 +194,7 @@ class SandboxFsSync {
205194
this.deps = newDeps;
206195

207196
added.forEach(dep => {
208-
this.fetchDependencyTyping(syncId, dep, syncDetails.autoInstall);
197+
this.fetchDependencyTyping(dep, syncDetails.autoInstall);
209198
});
210199

211200
if (removed.length) {
@@ -221,7 +210,7 @@ class SandboxFsSync {
221210
delete this.types[removedDep.name];
222211
});
223212

224-
this.send('types-remove', removedTypings);
213+
this.send('types-remove', removedTypings, fsId);
225214
}
226215
}
227216
} catch (error) {
@@ -272,42 +261,34 @@ class SandboxFsSync {
272261
return;
273262
}
274263

275-
if (stat.mtime.toString() !== lastMTime.toString()) {
276-
lastMTime = stat.mtime;
277-
278-
browserFs.readFile(
279-
'/sandbox/package.json',
280-
async (packageJsonReadError, rv) => {
281-
if (packageJsonReadError) {
282-
reject(packageJsonReadError);
283-
return;
284-
}
264+
browserFs.readFile(
265+
'/sandbox/package.json',
266+
async (packageJsonReadError, rv) => {
267+
if (packageJsonReadError) {
268+
reject(packageJsonReadError);
269+
return;
270+
}
285271

286-
browserFs.stat(
287-
'/sandbox/tsconfig.json',
288-
(tsConfigError, result) => {
289-
// If tsconfig exists we want to sync the typesp
290-
try {
291-
const packageJson = JSON.parse(rv.toString());
292-
resolve({
293-
dependencies: {
294-
...packageJson.dependencies,
295-
...packageJson.devDependencies,
296-
},
297-
autoInstall: Boolean(tsConfigError) || !result,
298-
});
299-
} catch (error) {
300-
reject(
301-
new Error('TYPINGS: Could not parse package.json')
302-
);
303-
}
272+
browserFs.stat(
273+
'/sandbox/tsconfig.json',
274+
(tsConfigError, result) => {
275+
// If tsconfig exists we want to sync the typesp
276+
try {
277+
const packageJson = JSON.parse(rv.toString());
278+
resolve({
279+
dependencies: {
280+
...packageJson.dependencies,
281+
...packageJson.devDependencies,
282+
},
283+
autoInstall: Boolean(tsConfigError) || !result,
284+
});
285+
} catch (error) {
286+
reject(new Error('TYPINGS: Could not parse package.json'));
304287
}
305-
);
306-
}
307-
);
308-
} else {
309-
resolve(null);
310-
}
288+
}
289+
);
290+
}
291+
);
311292
});
312293
} catch (e) {
313294
resolve(null);
@@ -316,14 +297,6 @@ class SandboxFsSync {
316297
});
317298
}
318299

319-
private sendTypes() {
320-
this.send('types-sync', this.getTypes());
321-
}
322-
323-
private sendPackageTypes(types: { [path: string]: any }) {
324-
this.send('package-types-sync', types);
325-
}
326-
327300
/**
328301
* Gets all entries of dependencies -> @types/ version
329302
*/
@@ -339,23 +312,22 @@ class SandboxFsSync {
339312
return this.typesInfo;
340313
}
341314

315+
// We send new packages to all registered workers
342316
private setAndSendPackageTypes(
343317
name: string,
344-
types: { [name: string]: string },
345-
syncId: number
318+
types: { [name: string]: string }
346319
) {
347-
if (!this.isDisposed && this.currentSyncId === syncId) {
320+
if (!this.isDisposed) {
348321
if (!this.types[name]) {
349322
this.types[name] = {};
350323
}
351324

352325
Object.assign(this.types[name], types);
353-
this.sendPackageTypes(types);
326+
this.send('package-types-sync', types);
354327
}
355328
}
356329

357330
private async fetchDependencyTyping(
358-
syncId: number,
359331
dep: { name: string; version: string },
360332
autoInstallTypes: boolean
361333
) {
@@ -368,13 +340,9 @@ class SandboxFsSync {
368340
) {
369341
const name = `@types/${dep.name}`;
370342
fetchPackageJSON(name, dep.version).then(({ version }) => {
371-
this.setAndSendPackageTypes(
372-
dep.name,
373-
{
374-
[name]: version,
375-
},
376-
syncId
377-
);
343+
this.setAndSendPackageTypes(dep.name, {
344+
[name]: version,
345+
});
378346
});
379347
}
380348

@@ -389,7 +357,7 @@ class SandboxFsSync {
389357

390358
const { files } = await fetchRequest.json();
391359

392-
this.setAndSendPackageTypes(dep.name, files, syncId);
360+
this.setAndSendPackageTypes(dep.name, files);
393361
} catch (e) {
394362
if (process.env.NODE_ENV === 'development') {
395363
console.warn('Trouble fetching types for ' + dep.name);

packages/app/src/app/overmind/effects/vscode/extensionHostWorker/common/fs.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
commonPostMessage,
33
getGlobal,
44
} from '@codesandbox/common/lib/utils/global';
5+
import * as uuid from 'uuid';
56

67
import { FileSystemConfiguration } from '../../../../../../../../../standalone-packages/codesandbox-browserfs';
78
import { IModule } from '../../../../../../../../../standalone-packages/codesandbox-browserfs/dist/node/backend/CodeSandboxFS';
@@ -64,12 +65,13 @@ export async function initializeBrowserFS({
6465
module: IModule;
6566
};
6667
} = {};
67-
let isResolved = false;
6868

6969
return new Promise(resolve => {
7070
const config = { ...BROWSER_FS_CONFIG };
7171
let currentSandboxFs = {};
7272

73+
let fsId = uuid.v4();
74+
7375
if (syncSandbox) {
7476
if (syncTypes) {
7577
config.options['/sandbox/node_modules'] = {
@@ -115,12 +117,30 @@ export async function initializeBrowserFS({
115117

116118
if (syncSandbox) {
117119
self.addEventListener('message', evt => {
120+
// Some messages are specific to this worker
121+
if (!evt.data.$fs_ids || !evt.data.$fs_ids.includes(fsId)) {
122+
return;
123+
}
124+
118125
switch (evt.data.$type) {
126+
case 'reset': {
127+
isInitialSync = true;
128+
fsId = uuid.v4();
129+
types = {};
130+
currentSandboxFs = {};
131+
commonPostMessage({
132+
$broadcast: true,
133+
$type: 'sync-sandbox',
134+
$fs_id: fsId,
135+
$data: {},
136+
});
137+
break;
138+
}
119139
case 'types-sync': {
120140
types = evt.data.$data;
121141
touchFileSystem();
122-
if (!isResolved) {
123-
isResolved = true;
142+
if (isInitialSync) {
143+
isInitialSync = false;
124144
resolve();
125145
}
126146
break;
@@ -142,10 +162,10 @@ export async function initializeBrowserFS({
142162
case 'sandbox-fs': {
143163
currentSandboxFs = evt.data.$data;
144164
if (isInitialSync) {
145-
isInitialSync = false;
146165
commonPostMessage({
147166
$broadcast: true,
148167
$type: 'sync-types',
168+
$fs_id: fsId,
149169
$data: {},
150170
});
151171
} else {
@@ -184,6 +204,7 @@ export async function initializeBrowserFS({
184204
commonPostMessage({
185205
$broadcast: true,
186206
$type: 'sync-sandbox',
207+
$fs_id: fsId,
187208
$data: {},
188209
});
189210
} else {

0 commit comments

Comments
 (0)