-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: move compile step to first run of server #2889
refactor: move compile step to first run of server #2889
Conversation
Looks like this works, unless the CI jobs cache the static resources between builds. I assume I should squash these commits? |
lib/server.js
Outdated
var bundler = browserify(path.join(__dirname, '/../client/main.js')) | ||
bundler.bundle().pipe(fs.createWriteStream(karmaJsPath)).once('finish', () => { | ||
bundler = browserify(path.join(__dirname, '/../context/main.js')) | ||
bundler.bundle().pipe(fs.createWriteStream(contextJsPath)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This creates a race condition, if the bundle is not generated fast enough, it will be missing when trying to be served. Need to make sure things are blocked to move on until it is finished.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, see comments for things that need adjusment
@@ -329,6 +329,7 @@ | |||
"dependencies": { | |||
"bluebird": "^3.3.0", | |||
"body-parser": "^1.16.1", | |||
"browserify": "^14.5.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be able to drop grunt-browserify
as a depency now
Going to have to modify the server unit tests to handle the way it's now calling back to |
lib/server.js
Outdated
bundler.bundle().pipe(fs.createWriteStream(karmaJsPath)).once('finish', () => { | ||
bundler = browserify(path.join(__dirname, '/../context/main.js')) | ||
// Start the web server once the last file has been browserified | ||
bundler.bundle().pipe(fs.createWriteStream(contextJsPath)).once('finish', () => { startWebServer() }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to wrap into an arrow function
lib/server.js
Outdated
self.log.info('Front-end scripts not present. Compiling...') | ||
// Browserify the files asynchronously | ||
var bundler = browserify(path.join(__dirname, '/../client/main.js')) | ||
bundler.bundle().pipe(fs.createWriteStream(karmaJsPath)).once('finish', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the two bundles should be created in parallel no need to wait for one or the other I think. Best you wrap bundle gen into a function that returns a promise and then use promise.all for the two invocations
lib/server.js
Outdated
} | ||
|
||
const karmaJsPath = path.join(__dirname, '/../static/karma.js') | ||
const contextJsPath = path.join(__dirname, '/../static/context.js') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these can be pulled to the top of the file
lib/server.js
Outdated
const karmaJsPath = path.join(__dirname, '/../static/karma.js') | ||
const contextJsPath = path.join(__dirname, '/../static/context.js') | ||
// Check if the static files haven't been compiled | ||
if (!(fs.existsSync(karmaJsPath) && fs.existsSync(contextJsPath))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use the async versions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fs.exists
is deprecated, fs.existsSync
is not. And it seems like it would be an unnecessary complication to use fs.stat
on two separate files and make callbacks that &&
the results together.
lib/server.js
Outdated
Promise.all([mainPromise, contextPromise]).then(() => { | ||
startWebServer() | ||
}, (error) => { | ||
self.log.error(error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- please use catch to handle the errors
- this needs to abort on error because if this fails it means we are unable to start properly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it just throw the error? Not sure what the correct way to trigger program exit is here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think exiting like it is done here: https://github.com/EzraBrooks/karma/blob/ba3da6824371c8824c6b5976b55048e54f0a9924/lib/server.js#L210-L212 should be the right course of action
What's the best course of action for making a test for this? File I/O has unpredictable execution times, so we should use a flag or event to detect - are we doing something similar elsewhere in the tests that could be mimicked? |
You can increase the timeout by doing it('is slow', function mytest () {
this.timeout(5000)
}) For filesystem, we use a mock file system in other unit tests, e.g. karma/test/unit/web-server.spec.js Line 17 in 10fac07
|
352c4df
to
e51aca1
Compare
e51aca1
to
e7433fc
Compare
Correct me if I'm wrong, but it seems like using a filesystem call makes more sense here than using a mock filesystem since we're looking for the actual existence of these files. |
The Node 6 and 8 jobs on Travis crashed during their package installs for some reason. |
@dignifiedquire Does this look good to you? Travis failed on conditions unrelated to the PR. |
The travis build fails with
That's pretty alarming ;-) |
Ah, it failed differently this time. |
@EzraBrooks Couldn't this be done in a way that don't slow down the first run everytime? Putting the burden of compiling client-side like this to every users for a niche use-case doesn't seems a very nice idea to me. Also adding |
I don't think it's a niche use case to not have a private npm registry and want to work with a fork of a major repository like this. Additionally, it's not going to slow down your CI if you properly cache the static resources on your CI job. It checks for existence of the files - it doesn't just assume they don't exist. |
I queued the Travis job back up and it ran fine. It had errored on an apt install previously for some reason. |
Thank you |
If I understand correctly, this change was made to move a build step from post install to every run? Why? As was pointed out on #2884
|
Do we know specifically what problems occur with post install? I think this PR optimizes for a less-used use-case, pull master from github, at the expense of the core use-case, npm install. Building master after pull is extremely common; yes it's an inconvenience but direct pull is not the common case. |
Fixes #2884 in a less npm-dependent manner than my previous PR.
@dignifiedquire How do you feel about this solution?