Welcome to the Linux Foundation Forum!

opendirSync vs opendir

Hello everyone. In ch-13, in the streaming directory content example, opendirSync(__dirname) is used as input for Readable.from() method. I wonder why it was used instead of the async opendir method? As I understand it's not recommended to use sync methods when serving HTTP responses. Was it just for demonstrative purposes? Maybe I missed something? Thanks

'use strict'
const { createServer } = require('http')
const { Readable, Transform, pipeline } = require('stream')
const { opendirSync } = require('fs')

const createEntryStream = () => {
let syntax = '[\n'
return new Transform({
writableObjectMode: true,
readableObjectMode: false,
transform (entry, enc, next) {
next(null, ${syntax} "${entry.name}")
syntax = ',\n'
},
final (cb) {
this.push('\n]\n')
cb()
}
})
}

createServer((req, res) => {
if (req.url !== '/') {
res.statusCode = 404
res.end('Not Found')
return
}
const dirStream = Readable.from(opendirSync(__dirname))
const entryStream = createEntryStream()
res.setHeader('Content-Type', 'application/json')
pipeline(dirStream, entryStream, res, (err) => {
if (err) console.error(err)
})
}).listen(3000)

Welcome!

It looks like you're new here. Sign in or register to get started.
Sign In

Comments

  • hi @mmd391

    As I understand it's not recommended to use sync methods when serving HTTP responses.

    This is correct, and we are not using sync methods when serving HTTP responses. We're using a sync method on initialization - which is what sync methods are for - convenient init stuff.

    It returns a stream (which is an asynchronous abstraction) which is then used during the request/response phase.

  • Hello @davidmarkclements

    thank you for your reply! So, if I would use const dirStream = Readable.from(await opendir(__dirname)), I would not gain much and only increase the complexity of the code? Sorry, if it's a silly question.

  • @mmd391 actually I have this wrong, I misread it. The sync op is in a request hot path - you're absolutely right

    I'm updated the code to the following:

    1. 'use strict'
    2. const { createServer } = require('http')
    3. const { Readable, Transform, pipeline } = require('stream')
    4. const { opendir } = require('fs')
    5.  
    6. const createEntryStream = () => {
    7. let syntax = '[\n'
    8. return new Transform({
    9. writableObjectMode: true,
    10. readableObjectMode: false,
    11. transform (entry, enc, next) {
    12. next(null, `${syntax} "${entry.name}"`)
    13. syntax = ',\n'
    14. },
    15. final (cb) {
    16. this.push('\n]\n')
    17. cb()
    18. }
    19. })
    20. }
    21.  
    22. createServer((req, res) => {
    23. if (req.url !== '/') {
    24. res.statusCode = 404
    25. res.end('Not Found')
    26. return
    27. }
    28. opendir(__dirname, (err, dir) => {
    29. if (err) {
    30. res.statusCode = 500
    31. res.end('Server Error')
    32. return
    33. }
    34. const dirStream = Readable.from(dir)
    35. const entryStream = createEntryStream()
    36. res.setHeader('Content-Type', 'application/json')
    37. pipeline(dirStream, entryStream, res, (err) => {
    38. if (err) console.error(err)
    39. })
    40. })
    41. }).listen(3000)

    You could also use the following:

    1. 'use strict'
    2. const { createServer } = require('http')
    3. const { Readable, Transform, pipeline } = require('stream')
    4. const { opendir } = require('fs').promises
    5.  
    6. const createEntryStream = () => {
    7. let syntax = '[\n'
    8. return new Transform({
    9. writableObjectMode: true,
    10. readableObjectMode: false,
    11. transform (entry, enc, next) {
    12. next(null, `${syntax} "${entry.name}"`)
    13. syntax = ',\n'
    14. },
    15. final (cb) {
    16. this.push('\n]\n')
    17. cb()
    18. }
    19. })
    20. }
    21.  
    22.  
    23. createServer(async (req, res) => {
    24. if (req.url !== '/') {
    25. res.statusCode = 404
    26. res.end('Not Found')
    27. return
    28. }
    29. try {
    30. const dirStream = Readable.from(await opendir(__dirname))
    31. const entryStream = createEntryStream()
    32. res.setHeader('Content-Type', 'application/json')
    33. pipeline(dirStream, entryStream, res, (err) => {
    34. if (err) console.error(err)
    35. })
    36. } catch (err) {
    37. res.statusCode = 500
    38. res.end('Server Error')
    39. return
    40. }
    41. }).listen(3000)

    Thanks for calling this out!

  • Thank you @davidmarkclements!

This discussion has been closed.

Welcome!

It looks like you're new here. Sign in or register to get started.
Sign In

Categories

Upcoming Training