Skip to content

Instantly share code, notes, and snippets.

@Mefistophell
Last active January 30, 2020 15:01
Show Gist options
  • Save Mefistophell/ef80a93238bb28581028bdfbe1fc2173 to your computer and use it in GitHub Desktop.
Save Mefistophell/ef80a93238bb28581028bdfbe1fc2173 to your computer and use it in GitHub Desktop.
Read a large file without blocking the event loop

To test:

Set the path to a large file in worker.js

Run: node index.js

Then you can run this bash: while true; do date && curl -m 5 http://localhost:3000/ && echo; sleep 1; done

and open a browser http://127.0.0.1:3000/read

Result

You can see that reading a large file does not block incoming requests.

const http = require('http')
const { Worker } = require('worker_threads')
function startWorker (cb) {
const w = new Worker(`${__dirname}/worker.js`)
w.on('message', (msg) => {
cb(msg)
})
w.on('error', (e) => console.error(e))
w.on('exit', (code) => {
if (code !== 0) {
console.error(new Error(`Worker stopped with exit code ${code}`))
}
})
return w
}
let counterReadFile = 1
let counterRequestHome = 1
const server = http.createServer()
server.on('request', (req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
if (req.url === '/read') {
startWorker((m) => res.end(`Reading the file has been ${m}. Counter: ${counterReadFile++}`))
} else if (req.url === '/') {
res.end(`Home page. Counter ${counterRequestHome++}`)
} else {
res.end(`Page not found`)
}
}
)
server.listen(3000, '127.0.0.1', () => {
console.log(`Server running at http://127.0.0.1:3000/`)
})
const { parentPort } = require('worker_threads')
const fs = require('fs')
fs.readFile(
`${__dirname}/bigfile.tgz`, // the path to a very large file
{ encoding: 'utf8' }, (err, data) => {
//... some actions
parentPort.postMessage('completed')
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment