pushangular6http2spdyserver-side-rendering

SPDY http2 + push throws exception in Angular 6 SSR


I have Angular 6 project with SPDY http2 push and SSR enabled. When clicking around more with hard refreshes and navigating around sometimes i got these errors:

and after couple refreshes i got that weired error: { AssertionError [ERR_ASSERTION]: false == true at PriorityNode.removeChild (C:\git\wearlenses-3-client\web\dist\server.js:130338:3) at PriorityNode.remove (C:\git\wearlenses-3-client\web\dist\server.js:130326:15) at PriorityTree.add (C:\git\wearlenses-3-client\web\dist\server.js:130427:23) at Stream._initPriority (C:\git\wearlenses-3-client\web\dist\server.js:130559:25) at new Stream (C:\git\wearlenses-3-client\web\dist\server.js:130534:8) at Connection._createStream (C:\git\wearlenses-3-client\web\dist\server.js:131564:16) at Connection._handleHeaders (C:\git\wearlenses-3-client\web\dist\server.js:131612:21) at Connection._handleFrame (C:\git\wearlenses-3-client\web\dist\server.js:131495:10) at Parser.<anonymous> (C:\git\wearlenses-3-client\web\dist\server.js:131332:10) at ZoneDelegate.invokeTask (C:\git\wearlenses-3-client\web\dist\server.js:117435:31) generatedMessage: true, name: 'AssertionError [ERR_ASSERTION]', code: 'ERR_ASSERTION', actual: false, expected: true, operator: '==' } TypeError: Cannot read property 'getPriority' of null at C:\git\wearlenses-3-client\web\dist\server.js:130627:32 at ZoneDelegate.invokeTask (C:\git\wearlenses-3-client\web\dist\server.js:117435:31) at Zone.runTask (C:\git\wearlenses-3-client\web\dist\server.js:117202:47) at ZoneTask.invokeTask (C:\git\wearlenses-3-client\web\dist\server.js:117510:34) at ZoneTask.invoke (C:\git\wearlenses-3-client\web\dist\server.js:117499:48) at data.args.(anonymous function) (C:\git\wearlenses-3-client\web\dist\server.js:118352:25) at process._tickCallback (internal/process/next_tick.js:112:11)

Here is parts of code:

``` app.get('*', (req: any, res: any) => {

try {
    Promise.all([...config.files]).then((data: any[]) => {
            for (let i = 0; i < config.files.length; i++) {
                const pushOptions = {
                    status: 200, // optional
                    method: 'GET', // optional
                    request: {
                        accept: '*/*'
                    },
                    response: {
                        'content-type': config.files[i].mimeType,
                        'Cache-Control': 'public, max-age=30672000'
                    }
                };

                let contentToSend = data[i];

                if (config.files[i].mimeType === 'application/font-woff2') {
                    contentToSend = new Buffer(contentToSend);
                    pushOptions.response['Content-Length'] = contentToSend.length;
                    pushOptions.response['Accept-Ranges'] = 'bytes';
                }

                if (config.files[i].gzip) {
                    pushOptions.response['content-encoding'] = 'gzip';
                    contentToSend = zlib.gzipSync(contentToSend);
                }

                const stream = (<any>res).push(`/${config.files[i].name}`, pushOptions);

                stream.on('error', () => { });

                stream.end(contentToSend);
            }
        }).catch(error => { });
} catch (e) {
    console.log(e);
}


res.render('index', { req });

}); ```

I feel like there should be res.render in another place but if i try to put it after stream.end performance drops.

What I should do differently?


Solution

  • I have solved this issue. This is some bug and quick fix for this is:

    let fs = require('fs')
    let path = require('path')
    let file = path.join(
        process.cwd(),
        'node_modules/spdy-transport/lib/spdy-transport/priority.js'
    )
    
    let data = fs
        .readFileSync(file)
        .toString()
        .split('\n')
    if (data.length < 190) {
        data.splice(73, 0, '/*')
        data.splice(75, 0, '*/')
        data.splice(
            187,
            0,
            `
        var index = utils.binarySearch(this.list, node, compareChildren);
        this.list.splice(index, 1);
    `
        )
        let text = data.join('\n')
    
        fs.writeFile(file, text, function(err) {
            if (err) return console.log(err)
        })
    }
    

    sources where taken from:

    https://github.com/spdy-http2/spdy-transport/issues/47
    https://github.com/Noumenae/server/issues/20
    https://github.com/spdy-http2/node-spdy/issues/285
    https://github.com/spdy-http2/node-spdy/issues/244
    

    As far as I understood everybody just wait for Express 5 which will have natvie http2 support.