[Note: parts of this message were removed to make it a legal post.]
Hi all,
I have a build tool that I've written in Ruby that uses this construct to
enter a directory, perform some long-running (several seconds) tasks then
exit back to the original working directory:
FileUtils.cd(dir) do
# expensive operations
end
Now I'm trying to write another tool that uses this build library to run
several builds at once in different Threads. Problem is, the FileUtils.cd
commands overlap and conflict with each other, causing the builds to fail. I
have a lot of code already out in production that relies on this directory
being set correctly (users can write hooks into the build system, and these
hooks assume a certain working directory), so I can't remove the cd() call.
My question is, is there a way of setting the working directory on a
per-thread basis, or is it a global property of the Ruby process that cannot
be made thread-safe?
Cheers,
James
--
James Coglan
http://jcoglan.com
|
|
0
|
|
|
|
Reply
|
jcoglan (199)
|
9/20/2009 5:50:30 PM |
|
The current working process is a global property of the underlaying
system process.
A system Process has one currency working directory, not two, or more.
You can do your directory / filename calculations, using the absolute
directory path, without any race conditions.
--
Markus
James Coglan wrote:
> Hi all,
>
> I have a build tool that I've written in Ruby that uses this construct to
> enter a directory, perform some long-running (several seconds) tasks then
> exit back to the original working directory:
>
> FileUtils.cd(dir) do
> # expensive operations
> end
>
> Now I'm trying to write another tool that uses this build library to run
> several builds at once in different Threads. Problem is, the FileUtils.cd
> commands overlap and conflict with each other, causing the builds to fail. I
> have a lot of code already out in production that relies on this directory
> being set correctly (users can write hooks into the build system, and these
> hooks assume a certain working directory), so I can't remove the cd() call.
>
> My question is, is there a way of setting the working directory on a
> per-thread basis, or is it a global property of the Ruby process that cannot
> be made thread-safe?
>
> Cheers,
> James
>
|
|
0
|
|
|
|
Reply
|
mbj1 (28)
|
9/20/2009 5:57:38 PM
|
|
[Note: parts of this message were removed to make it a legal post.]
2009/9/20 Markus Schirp <mbj@seonic.net>
> The current working process is a global property of the underlaying system
> process.
>
> A system Process has one currency working directory, not two, or more.
>
> You can do your directory / filename calculations, using the absolute
> directory path, without any race conditions.
Yes, I realise now I should have forced users to use absolute paths, but as
it stands there's code out in the wild with stuff like:
hook :after_build do |build|
FileUtils.cp 'README', File.join(build.build_dir, 'README')
end
So the working directory needs to be set so that 'README' can be found
correctly. Internally the tool uses absolute paths, so e.g.
`build.build_dir` is an absolute path, but code written by users is likely
to use relative paths.
|
|
0
|
|
|
|
Reply
|
jcoglan (199)
|
9/20/2009 6:03:26 PM
|
|
Forcing the users to use absolute paths may just hides the problem.
Maybe you should expand the users "relative" paths before using them.
Or monkeypatch FileUtils, and maybe dozens ruby core classes to support
a "thread-safe" cwd.
James Coglan wrote:
> 2009/9/20 Markus Schirp <mbj@seonic.net>
>
>> The current working process is a global property of the underlaying system
>> process.
>>
>> A system Process has one currency working directory, not two, or more.
>>
>> You can do your directory / filename calculations, using the absolute
>> directory path, without any race conditions.
>
>
> Yes, I realise now I should have forced users to use absolute paths, but as
> it stands there's code out in the wild with stuff like:
>
> hook :after_build do |build|
> FileUtils.cp 'README', File.join(build.build_dir, 'README')
> end
>
> So the working directory needs to be set so that 'README' can be found
> correctly. Internally the tool uses absolute paths, so e.g.
> `build.build_dir` is an absolute path, but code written by users is likely
> to use relative paths.
>
|
|
0
|
|
|
|
Reply
|
mbj1 (28)
|
9/20/2009 6:10:49 PM
|
|
2009/9/20 Markus Schirp <mbj@seonic.net>:
> Forcing the users to use absolute paths may just hides the problem. Maybe
> you should expand the users "relative" paths before using them.
>
> Or monkeypatch FileUtils, and maybe dozens ruby core classes to support a
> "thread-safe" cwd.
That would be an option but IMHO it would be tedious and error prone.
You can easily miss a class and introduce unwanted effects.
As far as I can see the only way to make cwd thread safe would be to
use the block form and synchronize access, i.e. one thread changes
cwd, does its work and returns cwd to the old status. For obvious
reasons this is not really a good idea. IMHO the only reasonable way
to go is to
a) use cwd only in single threaded programs or with explicit
synchronization guards
b) do not change cwd and use absolute path names, even if that means
converting user input / method arguments
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
|
|
0
|
|
|
|
Reply
|
shortcutter (5766)
|
9/22/2009 8:41:18 AM
|
|
|
4 Replies
24 Views
(page loaded in 0.059 seconds)
Similiar Articles:7/15/2012 7:26:20 PM
|