I have a writable stream piped into a readable stream. The writable stream 
at some point fails and emits an error. Me, as a readable stream 
implementor, how am I supposed to handle this situation? Do I receive any 
event from the writable stream?

I have this example that shows what I'm trying to explain.

--------------------------------------

var fs = require ("fs");

var rs = fs.createReadStream ("in", { highWaterMark: 1 })
var ws = fs.createWriteStream ("out");

var i = 5;
var write = ws._write;
ws._write = function (){
    if (!--i) this.emit ("error", new Error ());
    else write.apply (this, arguments)
}

rs.on ("error", function (){
    console.log("rs error")
})

rs.on ("end", function (){
    console.log("rs end")
})

rs.on ("close", function (){
    console.log("rs close")
})

ws.on ("error", function (error){
    console.log(error)
})

ws.on ("finish", function (error){
    console.log("ws finish")
})

ws.on ("open", function (error){
    console.log("ws open")
})

ws.on ("pipe", function (error){
    console.log("ws pipe")
})

ws.on ("unpipe", function (error){
    console.log("ws unpipe")
})

rs.pipe (ws);

--------------------------------------

File "in" has the content "1234567890".
File "out" ends with the content "1234".

The console output is:

ws pipe
ws open
ws unpipe
[Error]

So, what I don't understand is what is occurring under the hood. I've been 
following the source code and what happens is:

- When rs calls to pipe(), an "error" handler (Line 
545<https://github.com/joyent/node/blob/master/lib/_stream_readable.js#L545>) 
and an "unpipe" handler (Line 
489<https://github.com/joyent/node/blob/master/lib/_stream_readable.js#L489>) 
are attached to the ws.
- When ws emits an error, the previous error handler is executed and it 
calls to unpipe() (Line 
576<https://github.com/joyent/node/blob/master/lib/_stream_readable.js#L576>
).
- Then the ws is unpiped from the rs, and emits an "unpipe" event (Line 
628<https://github.com/joyent/node/blob/master/lib/_stream_readable.js#L628>). 
This event calls the previous "unpipe" handler.
- When the "unpipe" handler is executed it calls to cleanup() (Line 
509<https://github.com/joyent/node/blob/master/lib/_stream_readable.js#L509>). 
It basically removes some attached listeners.

So... as you can see the readable stream never emits any event, just like 
the result of the previous example (none of the ws listeners are executed).

I don't understand this, the readable stream magically stops emitting data 
just because the destination stream is unpiped, but I don't see in the code 
where the Readable stream notifies its implementor 
(ReadStream<https://github.com/joyent/node/blob/master/lib/fs.js#L1415>) 
to close the underlying resource and stop pushing more data into it.

My readable stream implementation gets the data from internet. If the 
writable stream fails I need to close the socket. Right now I simply have 
an abort() function that is called when the writable stream fails:

var rs = getMyReadStream ();
var ws = fs.createWriteStream ("out");

ws.on ("error", function (){
    rs.abort ();
})

rs.pipe (ws);

I want to remove the call to abort(), it should be called implicitly from 
inside the readable stream. Maybe should I listen to an "unpipe" event? 
(the ReadStream 
<https://github.com/joyent/node/blob/master/lib/fs.js#L1415>doesn't 
do this)

-- 
-- 
Job Board: http://jobs.nodejs.org/
Posting guidelines: 
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

--- 
You received this message because you are subscribed to the Google Groups 
"nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to