Open alb-i986 opened 3 years ago
@alb-i986 how does your solution compare to SmbFiles.mkdirs ? https://github.com/hierynomus/smbj/blob/master/src/main/java/com/hierynomus/smbj/utils/SmbFiles.java#L79
@alb-i986 how does your solution compare to SmbFiles.mkdirs ? https://github.com/hierynomus/smbj/blob/master/src/main/java/com/hierynomus/smbj/utils/SmbFiles.java#L79
The problem with SmbFiles.mkdirs
is that it's not atomic.
So you would still incur the concurrency issue which this PR fixes.
See what I wrote in my original post:
What happened was that I had 3 threads executing the following client code:
if (!share.folderExists(dirPath)) { share.mkdir(dirPath); }
This is a method I wrote myself in order to deal with the fact that
#mkdir
throws an exception when the directory already exists. But it was flawed, as the operation was not atomic.
I bumped into a race condition while using the existing
DiskShare#mkdir
What happened was that I had 3 threads executing the following client code:
This is a method I wrote myself in order to deal with the fact that
#mkdir
throws an exception when the directory already exists.But it was flawed, as the operation was not atomic.
A better way to deal with this problem could have been to silent the exception in case the status is STATUS_OBJECT_NAME_COLLISION:
That's ok but still it's not the best.
The best is to have
#mkdir
not throw in the first place, when the directory already exists.So here I'm proposing to add a
#mkdirs
method along with#mkdir
, with the same semantics as Files#createDirectories (I even copied its Javadoc :) )I didn't write tests for a couple of reasons:
#mkdirs
, together with any other method providing high level, client-facing functionality (e.g.SmbFiles#copy
, which could be very useful to users; it's unfortunate it is so "hidden"), in a Facade class which depended on a lower level, mockable class. So then it would be possible to write a simple test with mocks like this one:Also (but this should be another topic actually), I think it would be good if the path arguments we take from the user were of type
Path
. It would make our lives easier:Path#resolve
), joining paths (it's so annoying having to dopath + "\\" file
all the time, isn't it? ;) )Plus, it would make sense from a domain point of view: we're really dealing with paths!
As an example, this is how my
#mkdirs
could look like: