Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

finish event fires too early #432

Closed
blackmad opened this issue Mar 7, 2023 · 3 comments
Closed

finish event fires too early #432

blackmad opened this issue Mar 7, 2023 · 3 comments

Comments

@blackmad
Copy link

blackmad commented Mar 7, 2023

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch avsc@5.7.7 for the project I'm working on.

I noticed that the "finish" event was being emitted on my stream before I had actually finished reading all the rows. I'm not sure if this is a consequence of using snappy with using an async callback to do its work. I observed this behavior empirically in a test, in production code, and via the use of logs. I think the issue is that the code passes through the finish event when it reads the last bytes, but not when it finishes decoding them.

I'm not sure if this is the right solution - I couldn't figure out how to make a Duplex stream swallow the "finish" event, so I added another "done" event that appears to more correctly finish.

Here is the diff that solved my problem:

diff --git a/node_modules/avsc/lib/containers.js b/node_modules/avsc/lib/containers.js
index cc71888..f990e0e 100644
--- a/node_modules/avsc/lib/containers.js
+++ b/node_modules/avsc/lib/containers.js
@@ -74,6 +74,9 @@ function RawDecoder(schema, opts) {
 
   this.on('finish', function () {
     this._finished = true;
+    if (this._remaining === 0) {
+      this.emit("done")
+    }
     this._read();
   });
 }
@@ -300,6 +303,11 @@ BlockDecoder.prototype._read = function () {
   }
 
   this._remaining--;
+
+  if (this._remaining === 0 && this._finished) {
+    this.emit("done")
+  } 
+
   var val;
   try {
     val = this._readValue(tap);

This issue body was partially generated by patch-package.

@blackmad
Copy link
Author

blackmad commented Mar 7, 2023

actually ... I think this doesn't work because the finish event still flows through to other streams too early

@blackmad
Copy link
Author

blackmad commented Mar 7, 2023

working on a reduced case repro for this, I spent a while in the avsc code trying to fix it and couldn't quite get there. it's something about overriding the _final function in the Duplex stream and not calling the passed callback until we know we're done, but I was struggling to know if there was another block left.

@mtth
Copy link
Owner

mtth commented Mar 8, 2023

Hi @blackmad. Thanks for the thorough report. The finish event signals the end of the stream's writing side - it sounds like you are looking for end instead, which is emitted when there is no more data to be consumed from the stream.

@mtth mtth closed this as not planned Won't fix, can't repro, duplicate, stale Apr 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants