Store icon indicating copy to clipboard operation
Store copied to clipboard

Make readAll() resilient to exceptions reading a single file

Open riclage opened this issue 7 years ago • 8 comments

Currently, if an exception occurs on a fileSystem.read(s) call inside the FSAllReader.readAll() method, then the whole chain will stop with an onError emission. This prevents us from getting subsequent files on the path.

This PR proposes a solution to flat map each individual file read, wrapping its observable. If an exception occurs for a file read, then we return a ReadResultBufferedSource for that file that wraps the exception.

Current known issues:

  • A ReadResultBufferedSource seems like an unnecessary wrapping of a buffer just to fit the contract of the Observable<BufferedSource> readAll() method, which requires a BufferedSource. Ideally, we could return an Observable<ReadResult> instead which wraps either the exception or the BufferedSource. This would be, however, an API breaking change.
  • Propagating an empty buffer down the chain will cause existing parsers (e.g., GsonSourceParser) to return null for an empty buffer. This will throw a NPE on the chain instead of the original exception when reading the file.
  • We could have a safeReadAll() that filters out all the results that came from an exception?

This PR fixes #293

riclage avatar Nov 28 '17 15:11 riclage

Ideally I'd prefer the safeReadAll as another path of execution with a way to configure when instantiating the persister. We can then deprecate readAll and remove it in the next major version

digitalbuddha avatar Dec 05 '17 14:12 digitalbuddha

@digitalbuddha I updated the PR, adding a new method, safeReadAll() to the DiskAllRead<Raw> interface. Since I added this new method, I had to add a generic ReadResult<Raw> class to the base module as well. Hope it's clearer.

riclage avatar Dec 11 '17 16:12 riclage

@digitalbuddha @ramonaharrison Any chance we could merge this?

riclage avatar Jan 04 '18 07:01 riclage

So sorry for delay. I wasn't clear with last request. What still needs to be done is adding a builder configuration for when you build the store. This configuration would be to either use the safe read all or the regular one. You would also need to change RealInternalStore to read the flag and properly call the correct persister. Alternatively you can make a new persister who's readAll is the safe version and then pass that persister in. Whichever way you go pls include a test showing usage.

digitalbuddha avatar Jan 11 '18 06:01 digitalbuddha

@digitalbuddha Apologies for the delay in replying. I'm finally having the time to go back to this but it's not quite clear to me what you mean.

As far as I understood the code, there is currently no explicit builder configuration for any of the AllPersister implementations. In fact, as far as I can tell, the Store doesn't even use the current readAll() method at all. It doesn't seem to make sense to me to add a builder config for this.

Unless in your comment, did you mean to also add a kind of getAll() to the Store?

riclage avatar Apr 04 '18 08:04 riclage

hey there @riclage i'm so sorry we dropped the ball on this, i am planning a holiday here shortly and will be doing some store work. i will pick this up where you left off and add to this pr if that is ok with you? i'm looking forwards to getting this in. thank you!

brianPlummer avatar Jul 07 '18 18:07 brianPlummer

Hi @brianPlummer , that's ok with me. However, I feel like this PR could be merged as is. Your contributions could be made in subsequent PRs. Do you have any particular reasons to make commits to this PR specifically? Thanks!

riclage avatar Jul 20 '18 05:07 riclage

@brianPlummer Any update on this?

riclage avatar Aug 17 '18 16:08 riclage