-
Notifications
You must be signed in to change notification settings - Fork 603
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
Mask getBasicFileAttributes
errors in Files[F].walk
#3120
Mask getBasicFileAttributes
errors in Files[F].walk
#3120
Conversation
Thanks for the reproducer! So the issue is partly related to this fs2/io/shared/src/main/scala/fs2/io/file/Files.scala Lines 472 to 475 in 134041f
If I take it away I get this.
|
Ah yes, more |
Files[F].walk
cannot delete files recursivelygetBasicFileAttributes
errors in Files[F].walk
getBasicFileAttributes
errors in Files[F].walk
getBasicFileAttributes
errors in Files[F].walk
Stream.eval(getBasicFileAttributes(start, followLinks = true)).mask.flatMap { | ||
attr => | ||
val fileKey = attr.fileKey | ||
val isCycle = Traverse[List].existsM(ancestry) { | ||
case Right(ancestorKey) => F.pure(fileKey.contains(ancestorKey)) | ||
case Left(ancestorPath) => isSameFile(start, ancestorPath) | ||
} | ||
|
||
Stream.eval(isCycle).flatMap { isCycle => | ||
if (!isCycle) | ||
list(start).mask.flatMap { path => | ||
go(path, maxDepth - 1, attr.fileKey.toRight(start) :: ancestry) | ||
} | ||
else | ||
Stream.raiseError(new FileSystemLoopException(start.toString)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if some of this could be contained within the F
effect itself, as there is no much use for streaming features:
Stream.eval(getBasicFileAttributes(start, followLinks = true)).mask.flatMap { | |
attr => | |
val fileKey = attr.fileKey | |
val isCycle = Traverse[List].existsM(ancestry) { | |
case Right(ancestorKey) => F.pure(fileKey.contains(ancestorKey)) | |
case Left(ancestorPath) => isSameFile(start, ancestorPath) | |
} | |
Stream.eval(isCycle).flatMap { isCycle => | |
if (!isCycle) | |
list(start).mask.flatMap { path => | |
go(path, maxDepth - 1, attr.fileKey.toRight(start) :: ancestry) | |
} | |
else | |
Stream.raiseError(new FileSystemLoopException(start.toString)) | |
} | |
getBasicFileAttributes(start, followLinks = true).handleError(_ => ()).flatMap { | |
attr => | |
val fileKey = attr.fileKey | |
val isCycle = Traverse[List].existsM(ancestry) { | |
case Right(ancestorKey) => F.pure(fileKey.contains(ancestorKey)) | |
case Left(ancestorPath) => isSameFile(start, ancestorPath) | |
} | |
isCycle.flatMap { | |
case false => | |
list(start).mask.flatMap { path => | |
go(path, maxDepth - 1, attr.fileKey.toRight(start) :: ancestry) | |
} | |
case true => F.raiseError(new FileSystemLoopException(start.toString)) | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
go
is a Stream[F, Path]
and you flatMap
from F
to it. I don't think this compiles.
This shows a problem with
Files[F].walk
where it does not walk the whole file tree if files are deleted during the process. The added tests fails with:Only 5 files out of 25 where deleted. I expected that the whole process deletes 25 files because
tempFilesHierarchy
creates 5 child directories with 5 files in each child directory.If
Files[IO].deleteIfExists(path).as(1)
is replaced withIO.pure(1)
the test passes.