Browse Source
If we don't block on SDK builds, then the riot-web build fails due to half-built dependencies. This needs to be done at two levels: the js-sdk because it is used by both the react-sdk and riot-web, and at the react-sdk because riot-web needs it. This means our build process is synchronous for js -> react -> riot, at least for the initial build. This does increase the startup time, particularly because the file watch timer is at 5 seconds. The timer is used to detect a storm of file changes in the underlying SDKs and give the build process some room to compile larger files if needed. The file watcher is accompanied by a "canary signal file" to prevent the build-blocking script from unblocking too early. Both the js and react SDKs build when `npm install` is run, so we ensure that we only listen for the `npm start` build for each SDK. This is all done at the riot level instead of at the individual SDK levels (where we could use a canary file to signal up the stack) because: * babel (used by the js-sdk) doesn't really provide an "end up build" signal * webpack is a bit of a nightmare to get it to behave at times * this blocking approach is really only applicable to riot-web, although may be useful to some other projects. Hopefully that all makes sense.pull/7355/head
5 changed files with 97 additions and 8 deletions
@ -0,0 +1,56 @@
|
||||
const path = require('path'); |
||||
const chokidar = require('chokidar'); |
||||
const AsyncLock = require('async-lock'); |
||||
|
||||
|
||||
const WAIT_TIME = 5000; // ms
|
||||
|
||||
function waitForCanary(canaryName) { |
||||
return new Promise((resolve, reject) => { |
||||
const filename = path.resolve(path.join(".tmp", canaryName)); |
||||
|
||||
// See triggerCanarySignal in build-watch-sdk.js for why we watch for `unlink`
|
||||
const watcher = chokidar.watch(filename).on('unlink', (path) => { |
||||
console.log("[block-on-build] Received signal to start watching for builds"); |
||||
watcher.close(); |
||||
resolve(); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
function waitOnSdkBuild(sdkName) { |
||||
// First we wait for a local canary file to be changed
|
||||
return waitForCanary(sdkName).then(() => new Promise((resolve, reject) => { |
||||
const buildDirectory = path.dirname(require.resolve(`matrix-${sdkName}-sdk`)); |
||||
const lock = new AsyncLock(); |
||||
let timerId = null; |
||||
|
||||
const watcher = chokidar.watch(buildDirectory).on('all', (event, path) => { |
||||
lock.acquire("timer", (done) => { |
||||
if (timerId !== null) { |
||||
//console.log("Resetting countdown");
|
||||
clearTimeout(timerId); |
||||
} |
||||
//console.log(`Waiting ${WAIT_TIME}ms for another file update...`);
|
||||
timerId = setTimeout(() => { |
||||
console.log("[block-on-build] No updates - unblocking"); |
||||
watcher.close(); |
||||
resolve(); |
||||
}, WAIT_TIME); |
||||
done(); |
||||
}, null, null); |
||||
}); |
||||
})); |
||||
} |
||||
|
||||
const sdkName = process.argv[2]; |
||||
if (!sdkName) { |
||||
console.error("[block-on-build] No SDK name provided"); |
||||
process.exit(1); |
||||
} |
||||
|
||||
console.log("[block-on-build] Waiting for SDK: " + sdkName); |
||||
waitOnSdkBuild(sdkName).then(() => { |
||||
console.log("[block-on-build] Unblocked"); |
||||
process.exit(0); |
||||
}); |
Loading…
Reference in new issue