-
-
Notifications
You must be signed in to change notification settings - Fork 181
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
Introduce WriteAsync to not swallow all exceptions and improve write performance and misc enhancements #130
base: master
Are you sure you want to change the base?
Conversation
…oducer/consumer write bytes
…nsive and also explicitly dispose tcp conn
…l switch. Also made easy to choose to write with Write or WriteAsync.
…cp connection is disconnected and reconnect.
Thanks @panot-hong for the PR! I will need to take some time to digest the changes and fully test, as the various failure scenarios are quite extensive with this library so it's quite difficult to uniformly validate the behavior (which in itself hints that we need a more exhaustive test harness, especially for TCP printers, but also in general), but I'll do a review when I can. I have some questions about your general approach though. It seems in this new model within this PR, if WriteAsync is using a blocking collection, and your underlying printer is not connected or in a bad state (eg. it has the cover open) the writes will block and timeout. So there's no mechanism to allow the writes to queue up if you want them to, which you can do with the current implementation. So while I agree with you that there should be a way to await a write request, I do think that there could be a way to support both patterns. What do you think about having the concept of each write request having an ID that you can then query to determine if it is written or not? That way, you could still Do you have something like this in your application (that manages print jobs, and knows if they have gone through or not / what the status of them is), or do you just do a blocking write every time you want to print, and if it doesn't get written to the underlying stream in the right amount of time you just throw errors and start over? I think this is an important conversation to have, because it sounds like you use the library primarily for making throwaway printer objects that you only use once, where others use it for, as you said, a single instance per printer (not really a singleton, but a 1:1 of physical printer to printer object, and they are long-lived). In this scenario the printer object is sort of a software-level mock of the hardware. This is also a beneficial pattern if you have a UI that shows information about the printers, because it can get automatic status back messages which allow you to reflect the printer state in real-time without having to poll the printer. I think this is a very powerful benefit to keeping a long-running reference to a printer in the application. |
Thank @lukevp for considering my PR.
I want to iterate that my PR does not tend to replace the existing functionality but to also supports awaitable write (not swallow exception) plus better performance. I would separate this into two main things.
I however just realized that the original PR missed retrying for the existing write function in the WriteLongRunningTask function. So I made a small change and commit to this PR to endlessly retry write to the stream (as long as the object is yet disposed) if it is bytes that submitted via Write function, not WriteAsync. With this, I recommend renaming the Write function to something like "WriteWithRetries" or "EnqueueWrite" like you said to be more explicit to its behavior. But if you mine backward compatibility - remain the same name and adding an explanation to the XML doc and README should also help.
I think the WriteAsync also does pretty similar to this. As a common usage of the task, as long as it is not awaited, it is pretty much like EnqueueWrite(). And once it is awaited, it is WaitForPrintToCompleteAsync(id).
I am not at that stage yet but quite certain that there will be and that is one of the reasons I decided to use this library in the first place. Again, this PR does not limit to only use blocking (await), the existing Write function should work properly as it was. Also, calling the
You are right, the most use case should be where a thermal printer is assigned to a device. But in some scenarios like when a thermal printer is set up in a kitchen as a kitchen printer and having multiple POS devices that write stream to the single kitchen printer. The TCP connection to the printer when one is currently connected, another one has to wait for the first connection to close. In this kind of scenario, the caller wouldn't mind tracking printer status and should release the connection right after the bytes are written to the stream. |
🚨 Issues found in the current version.
✨ Purpose changes in this PR
Sorry to pack many changes 📦📦 in a single PR 🙇