Skip to content
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

node does not exit when starting express server in uvu setup #91

Closed
happybeing opened this issue Feb 1, 2021 · 6 comments
Closed

node does not exit when starting express server in uvu setup #91

happybeing opened this issue Feb 1, 2021 · 6 comments

Comments

@happybeing
Copy link

I've got a uvu setup that seems fine apart from hanging after displaying test results.

In test.before() I create two web servers, one using nodejs http module (is a simple git http server), and one for the app using express (and use test.after() to close them down). Even though I can see both servers do shut down, uvu hangs after printing the test summary (with all tests passing) and I have to Ctrl-C.

I'm using the express server so I can use webpack-dev-middleware to serve modules from memory without a full build. However, I can run without the express server when I'm doing a test on the build, because I don't need the middleware for that.

So when I run a build test I don't use the express server, but replace it with a nodejs server that serves the static build output. So in this case I have two nodejs http servers, one for the git http server and one for the app. This works fine and after passing all tests, uvu exits. So it seems to be to do with the express app or server.

I'm sure the server is closing, and have tried several modules that help close the running server if connections remain open. But inspecting the server object I can see there are no open connections, and the server does appear to have shut down correctly.

Do you have any experience of starting a server inside uvu tests, and particularly with express? I'm not sure it is a big enough issue to go into in depth (because I can just run an external server during development testing) but want to ask in case it's an easy thing to solve. Thanks.

@lukeed
Copy link
Owner

lukeed commented Feb 2, 2021

I would need to see actual code in order to give some actual advice here. You can find me on the svelte discord (I'm 99% sure I've seen you there) if you don't want to publish snippets publicly.

@happybeing
Copy link
Author

happybeing commented Feb 2, 2021

Thanks @lukeed, after I posted the above I reverted to some earlier code planning to go for the fallback (separate server for development testing) and found that code was working correctly with the express (development) server, but not the build server. So I'm confused!

This means I've had both kinds of server working and shutting down correctly (node http and express), but not in the same implementation. One of the main variables here is where I do the server setup and shut down: in setup/index.js in test.before/after, or in test.before.each/after.each. I'll investigate more today.

Thanks very much for offering to look further. I'll let you know when I have some code in case you want to take a look. And yes, you've seen me over on the Svelte Discord (the app I'm building uses Svelte + Rust/WASM on WASI/WasmerJS in the browser). I went for uvu in part because I got the impression it is associated with Svelte in some way, so happy to hear you are over there too.

@happybeing
Copy link
Author

happybeing commented Feb 2, 2021

@lukeed I found and fixed a few things with promises and things look to be happening in the correct order now (setting up / shutting down etc based on the order of console messages in the terminal), but I'm back at the state where yarn:build runs the tests (3/3 pass) and exits, and yarn test runs the tests (3/3 pass) but does not exit.

Before I tidied things up and fixed the promise issues I had this exactly the other way around, so I know the express server used by yarn test (which sets CONFIG.mode === 'development') is not really the problem. Ignore this - it was only exiting because I was calling process.exit() in testafter(). 😊 So it may well be something to do with using the express server, but I have nothing pointing directly to that as the issue. I just know that it only hangs when I'm using it, which I need to do in order to make use of webpack-dev-middleware.

If you have time to scan the code you might pick something up. I based it on your puppeteer example so the structure should be reasonably sensible. As I said before, it isn't imperative we fix this as I can remove the dev server and run that externally for development testing, so let me know if you want to just close this. I've no evidence that it's an issue with uvu.

The code is on main at this commit if you want to take a look: happybeing/p2p-git-portal-wasi@113e29f

@lukeed
Copy link
Owner

lukeed commented Feb 3, 2021

Hey, I checked it out this morning. Your dev server never terminates webpack-dev-middleware which spawns its own series of XYZ to set up the server-side HMR bits.

Here's the working code for devserver.cjs:

const webpackConfig = require('../../../webpack.config.js');
const express = require('express');
let app = express();
let server, middleware;

async function startServer(port) {

    const webpack = require('webpack');
    const compiler = webpack(webpackConfig);
    middleware = require('webpack-dev-middleware')(compiler, {
        // webpack-dev-middleware options
    });

    app.use(express.static(webpackConfig.devServer.contentBase));
    app.use(middleware);

    return new Promise(resolve => {
        try {
        server = app.listen(port, () => {
            console.log('devserver on port ' + port);
            resolve();
        });
        server = require('http-shutdown')(server);
        } catch(e) {
            console.log('devserver error1: ' + e);
        }
    });
}

module.exports = {
    startServer: startServer,
    shutdownServer: () => {
        return new Promise(resolve => {
            try {
                if (middleware) middleware.close();
                server.close(function(err) {
                    if (err) {
                        console.log('devserver shutdown failed', err.message);
                        return resolve();
                    }
                    console.log('devserver shut down');
                    resolve();
                });
            } catch(e) {
                console.log('devserver error2: ' + e);
            }
        });
    }
}

@happybeing
Copy link
Author

Thank you so much, that works. And thanks for uvu (why 'uvu' by the way?).

@lukeed
Copy link
Owner

lukeed commented Feb 4, 2021

Cool! uvu is short, easy to remember, and easy to type. The acronym for "ultimate velocity unleashed" was shoe horned after haha

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants