-
Notifications
You must be signed in to change notification settings - Fork 250
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
FIX: Ensure Rack::Test::UploadedFile closes its tempfile file descriptor on GC #180
FIX: Ensure Rack::Test::UploadedFile closes its tempfile file descriptor on GC #180
Conversation
Thanks @bsodmike for your contribution! This does unfortunately not build cleanly on JRuby, as the Travis logs indicate. Any idea on how we can make it work there also? (For reference: I did some minor cleanups to prepare the code for more uniform style compared to the existing codebase.) |
Thanks so much @perlun - will take a look at the CI logs and fix this up asap. |
Hey @perlun it's good to go now - thanks! I had a bad conflict resolution, so put back some corrections you had made. Oops! Interestingly, I ran the jRuby GC in a loop (without my patch) ~
For this spec, I reduced it to 20 and that seems to work fine. |
This would also close #118 |
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.
@perlun @junaruga I am not sure that finalizers are the best solution for this, due to some existing edge cases. However it is way better than having the current issue. I think we should accept this improvement and we can still improve/change the details later.
This PR directly changes an existing issue without changing the public API, thus I think it is good to merge.
.gitignore
Outdated
@@ -6,3 +6,4 @@ VERSION | |||
*.rbc | |||
*.swp | |||
/.bundle | |||
.idea/ |
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.
.idea
? A directory for "Intellij IDE"?
I am not know detail about it.
Kind of this case **/.idea
is possible?
/.idea
looks better, isn't it referring /.bundle
?
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.
.idea/
auto globs .idea/**
. You don't need to be that specific :)
Yes, it's for Intellij IDEs.
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 mean if aa/.idea
exists, .idea
makes sense. But if ./.idea/**
, /.idea
is correct. /.idea
in .gitignore
means ./.idea/**
.
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.
Sure, I'll change this to /.idea
@@ -30,6 +30,8 @@ def initialize(path, content_type = "text/plain", binary = false) | |||
@tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding) | |||
@tempfile.binmode if binary | |||
|
|||
ObjectSpace.define_finalizer(self, self.class.finalize(@tempfile)) | |||
|
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.
How about this?
It looks more simple.
ObjectSpace.define_finalizer(self, self.close)
def close()
@tempfile.close if @tempfile
end
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.
Check this out mate, http://www.mikeperham.com/2010/02/24/the-trouble-with-ruby-finalizers/
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.
Thanks, I check it. and I learned that we have to use the static method.
Sorry for my late replying. We can not close @tempfile file descriptor in In my opinion, if we can not close it, such as Ruby File class (http://ruby-doc.org/core-2.4.1/File.html) and Java The responsibility to close the file descriptor is likely to be for user side. Or provide static method?
Sorry, just I got idea. It may be wrong. |
Yes, that's the way this API has been setup and does make sense. The user is supposed to 'work' with the provided descriptor, and ideally close it when done. But this allows for user error.
Right, exactly. That's the reason I've set this up to auto-close the descriptor on GC if the user forgets to close the descriptor. It's also the reason one should typically use the block-form when working with IO in Ruby (as closing the descriptor is automatically handled). Think of this as a safe-guard. Of course, it wouldn't break if the user decides to close the descriptor either. |
Yes, I agree with you. |
Yes, they can call We do not need to provide this explicitly, as the user already has access to the tempfile descriptor. |
Added an improvement as recommended here https://ruby-doc.org/stdlib-2.4.0/libdoc/tempfile/rdoc/Tempfile.html
|
Thank you for the replying. Now at 23:30 in my area. So, let me check it later. |
Sure mate, here's a quick snippet for you - this is normally how a user should handle a tempfile, if they do not use the block format. file = File.join(Rails.root, 'tmp', 'foo.jpg')
FileUtils.touch file
tempfile = Rack::Test::UploadedFile.new file
# with my patch we are safe-guarding the user by doing this on GC
# even if they forget to do so.
tempfile.close
tempfile.unlink |
spec/rack/test/uploaded_file_spec.rb
Outdated
it "calls the destructor" do | ||
expect(Rack::Test::UploadedFile).to receive(:actually_finalize).at_least(:once) | ||
|
||
if RUBY_PLATFORM == 'java' && RUBY_VERSION == '2.3.1' |
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.
Current jruby-head 's Ruby version is 2.3.3. jruby-head
is failed because of the reason.
I do not want to write actual version number in the test code.
Can you remove && RUBY_VERSION == '2.3.1'
from the code?
@bsodmike ok thanks. I commented one thing about removing |
Sure, I'll push this in about 4 hours time.
Thanks mate.
On Mon, 5 Jun 2017 at 18:45, Jun Aruga ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In spec/rack/test/uploaded_file_spec.rb
<#180 (comment)>:
> @@ -26,4 +32,29 @@ def test_file_path
expect(File.extname(uploaded_file.path)).to eq(".txt")
end
+
+ context "it should call its destructor" do
+ it "calls the destructor" do
+ expect(Rack::Test::UploadedFile).to receive(:actually_finalize).at_least(:once)
+
+ if RUBY_PLATFORM == 'java' && RUBY_VERSION == '2.3.1'
Current JRuby 's Ruby version is 2.3.3. jruby-head is failed because of
the reason.
I do not want to write actual version number in the test code.
Can you remove && RUBY_VERSION == '2.3.1' from the code?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#180 (review)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAWehAM0O7n5VLuJX5oQLIepcTJ7H5yRks5sA_9kgaJpZM4NhJJQ>
.
--
-- Mike's on the move!
|
@junaruga I've updated this mate, thanks. |
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 approved the review! thanks.
Thanks mate, so how does this get merged? |
I did merged with squash option for your several commits. Check latest master branch.
|
@bsodmike Hi, I am just curious about the use case for this change—are the file descriptors left hanging when the ruby process exits? Or just during GC? I presume most people are using this class for tests, which shouldn't really be long-running processes. Just curious! |
Hi all - I noticed the file descriptor of the tempfile is left 'hanging' and have ensured it is closed on GC.
Cheers!