-
Notifications
You must be signed in to change notification settings - Fork 71
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
refactor(cache): simplify clean
method
#358
Conversation
- `cache().clean()` is only called during instantiation in `options`, so we can instead just call it inside of the constructor - there is no need to call `this.init()` in `clean` as it's only used in the constructor anyway, which already calls `this.init()` - and if `noCache` is `true`, `init` is basically a no-op too - so technically we don't need to call `init` _at all_ if `noCache`, but that's a larger refactor that I'm splitting into a separate commit/PR - now that `clean` is just one conditional, we can invert it and return early instead - it's also not necessary and less efficient to call `emptyDir` before `remove`; `remove` will unlink all the contents anyway - docs here: https://github.com/jprichardson/node-fs-extra/blob/0220eac966d7d6b9a595d69b1242ab8a397fba7f/docs/remove-sync.md - though this also just normal FS behavior - IMO, it's also not necessary to check if it's a directory, we can `remove` it either way - and not necessary to log out if we _don't_ clean it - then also just simplify the logic to use a `filter` instead of a nested `if` - which we already do in several places, so this follows existing code style
Making clean() private might be ok in current usage, but it makes cache class incomplete on its own. I guess contract changes so client should create new instance in this case, so that's fine. Checking that what we delete is a directory is needed though, deleting cache is the most dangerous action this plugin does, so we should do as many sanity checks as we can. If the path is suddenly not a directory, something went very wrong. Ideally there should also be a manifest with a file list or something, and if it is well formed, we should be deleting only the files listed inside. |
Basically agreed. I recognized that in changing it, but it's only used like this anyway. From the Rollup perspective, That's more relevant if we were to ever split off the cache implementation into its own library, but otherwise, in the usage here, I could leave it as
Mmm I see, I think we have different operating assumptions here. I'm thinking more in terms of unit testing this, where it's an invariant that it's a directory, so that situation should never happen and is therefore untestable. "Should never happen" also sounds like dead code to me, so my operating assumption is that it can be removed. I see that your operating assumption is more that random stuff can happen and users can do random things, so be as safe as possible (#243 is a great example of a race condition that really shouldn't happen, but does during parallel processing. that being said, that specific race may actually be fixable and would be a performance improvement -- but we should probably check and not error hard anyway even if the race is handled).
Yea I was thinking something like this gives more guarantees if working from that operating assumption. But at the same time that seems like unnecessary complexity for a marginal safety benefit -- especially for something that really should be considered ephemeral. I'm fine going with your safety assumption though if that's what you'd prefer. In that case, I would definitely add a comment that it shouldn't ever happen though, and probably throw a |
Yeah, cache is ephemeral, but only if that's really our cache folder and the root of it isn't somehow in a bad place (due to bugs in our code, or in the library we use to find cache root, or someplace else). There is a reason |
- as requested in code review, will go with a safety-first operating assumption - as such, with safety as modus operandus, make the logging more detailed in these scenarios, since they're not supposed to happen - and don't check code coverage on these as they're not supposed to happen in normal usage
@ezolenko made the requested changes 👍 This is now a smaller change: an |
Summary
Simplify
TsCache
'sclean
method to be more straightforward, less nesting, etcDetails
cache().clean()
is only called during instantiation inoptions
, so we can instead just call it inside of the constructorthis.init()
inclean
as it's only used in the constructor anyway, which already callsthis.init()
noCache
istrue
,init
is basically a no-op tooinit
at all ifnoCache
, but that's a larger refactor that I'm splitting into a separate commit/PRclean
is just one conditional, we can invert it and return early insteademptyDir
beforeremove
;remove
will unlink all the contents anywayremove
it either wayfilter
instead of a nestedif
Future Reference
This refactor and some upcoming refactors mentioned above are going to make it a good bit easier to unit test this because the code will be simpler with less branches and less nesting.