What is the internal buffer size for "fs.createReadStream" - node.js

What is the internal buffer size for "fs.createReadStream" ?
From the stream's documentation, it is mentioned that the fs.createReadStream uses an internal buffer that is accessible via readable._readableState.buffer
From the stream's documentation, it is mentioned that the default highWaterMark is 64kb.
But the readable._readableState.buffer.length get's 1, not 8 (8 bytes = 64 kb). Why is that ?
References:
https://nodejs.org/docs/latest-v6.x/api/stream.html#stream_buffering
https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options

Related

Is there a way to limit the maximum size of a websocket message?

I have an application in which I wish to limit the maximum size of a message that was sent across the wire by a connected client. Since the theoretical maximum of a message in Node.js is about 1.9 GB, I actually never want my application to allocate that big a chunk of memory if some malicious clients tries to send an over-sized packet.
How can I limit the incoming message size, to say, 1024 bytes?
To anyone looking for answer to this question in future, use maxPayload option in server configuration to limit the message size before it is read by Node (which is almost always what you want)
const wss = new WebSocket.Server({
clientTracking: true,
maxPayload: 128 * 1024, // 128 KB
path: "/learn",
//....
})
Each character is 1 to 3 bytes in length. So you can technically just substring the string to get desired length.
var limited = fullString.substring(0, 1024);
Or you can use a package like this : utf8-binary-cutter

Linux serial port read() returns the maximum buffer size passed in

unsigned char buf[256];
num = read (fd, &buf, sizeof (buf));
I have a program that reads the serial port at 100ms rate. Device can send a maximum of 120 bytes of data every 100ms. I am observing at times that read() returns 256 (the size of buf[], that I have passed in to read() ). Because of this all the bytes are mixed up and I see checksum failures.
Is there a way, that I can poll on the file descriptor if there is a data and read only the valid data.
Yes! You can use the functions poll() or select() to know when data is available, but you will not know exactly how much. For that you can either do a regular blocking read of 120 bytes if it's a fixed-size message each time, or you'll have to read smaller parts, like the header first then the body once you know the size from the header, or you can read big chunks into a ring buffer and process them however you want in user-space.

Does __bread() always return PAGE_SIZE number of bytes?

The Linux kernel API has a __bread method:
__bread(struct block_device *bdev, sector_t block, unsigned size)
which returns a buffer_head pointer whose data field contains size worth of data.However, I noticed that reading beyond size bytes still gave me valid data up to PAGE_SIZE number of bytes. This got me wondering if I can presume the buffer_head returned by a *__bread* always contains valid data worth PAGE_SIZE bytes even if the size argument passed to it is lesser.
Or maybe it was just a coincidence.
The __bread perform a read IO from given block interface, but depending on the backing store, you get different results.
For harddrives, the block device will fetch data in sector sizes. Usually this is either 512 bytes or 4K. If 512 bytes, and you ask for 256 bytes, you'll be able to access the last parts of the sector. Thus, you may fetch up to the sector size. However, it is not always true. With memory backed devices, you may only access the 256 bytes, as it is not served up by the block layer, but by the VSL.
In short, no. You should not rely on this feature, as it depends on which block device is backing the storage and may also change with block layer implementation.

NodeJS ReadStream not reading bufferSize bytes at a time

I have a code where the NodeJS server reads a file and streams it to response, it looks like:
var fStream = fs.createReadStream(filePath, {'bufferSize': 128 * 1024});
fStream.pipe(response);
The issue is, Node reads the file exactly 40960 bytes a time. However, my app would be much more efficient (due to reasons not applicable to this question), if it reads 131072 (128 * 1024) bytes at a time.
Is there a way to force Node to read 128 * 1024 bytes at a time?
The accepted answer is wrong. You can force Node to read (128*1024) bytes at a time using the highWaterMark option.
var fStream = fs.createReadStream('/foo/bar', { highWaterMark: 128 * 1024 });
The Documentation specifically states that 'the amount of data potentially buffered depends on the highWaterMark option passed into the streams constructor. For normal streams, the highWaterMark option specifies a total number of bytes. For streams operating in object mode, the highWaterMark specifies a total number of objects.'
Also, see this. The default buffer size is 64 KiloBytes
I'm new here, so bear with me....
I found this in node's sources:
var toRead = Math.min(pool.length - pool.used, ~~this.bufferSize);
and:
var kPoolSize = 40 * 1024;
So it seems that the buffer size is limited to 40kb, no matter what you provide. You could try to change the value in the code and rebuild node. That's probably not a very maintainable solution though...

What's the maximum size of a Node.js Buffer

I got a fatal error reading a file that was too big to fit in a buffer.
FATAL ERROR: v8::Object::SetIndexedPropertiesToExternalArrayData() length exceeds max acceptable value
Or,
RangeError: "size" argument must not be larger than 2147483647
at Function.Buffer.allocUnsafe (buffer.js:209:3)
If I try to allocate a 1GB Buffer I get the same fatal Error,
var oneGigInBytes = 1073741824;
var my1GBuffer = new Buffer(oneGigInBytes); //Crash
What is the maximum size of a Node.js Buffer class instance?
Maximum length of a typed array in V8 is currently set to kSmiMaxValue which depending on the platform is either:
1Gb - 1byte on 32-bit
2Gb - 1byte on 64-bit
Relevant constant in the code is v8::internal::JSTypedArray::kMaxLength (source).
V8 team is working on increasing this even further on 64-bit platforms, where currently ArrayBuffer objects can be up to Number.MAX_SAFE_INTEGER large (2**53 - 1). See bug 4153.
This is now documented as part of Node's buffer api, the maximum size is buffer.constants.MAX_LENGTH.
buffer.constants.MAX_LENGTH <integer> The largest size allowed for a single Buffer instance.
On 32-bit architectures, this value is (2^30)-1 (~1GB).
On 64-bit architectures, this value is (2^31)-1 (~2GB).
This value is also available as buffer.kMaxLength.
So you can figure out how big it is by doing
> (require('buffer').constants.MAX_LENGTH + 1) / 2**30
2
Seems like the current max buffer size is 2147483647 bytes aka 2.147GB
Source: https://stackoverflow.com/a/44994896/3973137 (and my own code)
The actual maximum size of a buffer changes across platforms and
versions of Node.js. You can find out what's the limit
in bytes in a given platform, run this:
import buffer from "buffer";
console.log(buffer.constants.MAX_LENGTH);

Resources