Skip to content
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 eof() and read*() behaviour for ::File and ::LibuvStream #14699

Merged
merged 7 commits into from
Jan 24, 2016

Conversation

samoconnor
Copy link
Contributor

@tkelman tkelman added the domain:io Involving the I/O subsystem: libuv, read, write, etc. label Jan 17, 2016
@samoconnor samoconnor force-pushed the uv_fs_read_eof branch 2 times, most recently from 1061c85 to f7da086 Compare January 17, 2016 10:15
@samoconnor
Copy link
Contributor Author

It looks like this new test is failing on Win32

    From worker 2:    Expression: readall(io()) == text
    From worker 2:     Evaluated: "C1,C2 1,2 a,b" == "C1,C2\n1,2\na,b\n"

Maybe a DOS line-ending issue?

Could someone who has windows please look at this?

edit: I think this is resolved now, the last appveyor build ran fine except for a crash deleting a tmp directory due to open files, running again now with a fix for that...

@tkelman
Copy link
Contributor

tkelman commented Jan 17, 2016

Please separate the introduction of new methods from bug fixes into separate PRs.

@samoconnor
Copy link
Contributor Author

Appveyor now says rmdir: Directory not empty after a mktempdir() do dir ... end block ??

@samoconnor
Copy link
Contributor Author

separate the introduction of new methods from bug fixes

Adding the missing methods is the bug fix.

Handling uv_fs_read() EOF requires eof(::File) because calling eof(::File) is a precondition of calling read(::File, ::UInt8). That in-turn requires skip(::File), and you can't really have skip(::File) without having seek(::File) and seekend(::File) as well.

@samoconnor samoconnor changed the title Fix uv_fs_read() EOF handling. Fix uv_fs_read() EOF handling, add eof(::File), seek(::File) etc. Jan 18, 2016
@tkelman
Copy link
Contributor

tkelman commented Jan 18, 2016

Adding the missing methods is the bug fix.

Then what was the purpose of opening the PR with a single commit, then adding additional content to it? The new test in the first commit didn't seem to need these new methods to pass, so why are these in the same PR?

@samoconnor samoconnor changed the title Fix uv_fs_read() EOF handling, add eof(::File), seek(::File) etc. Fix eof() and read*() behaviour for ::File and ::LibuvStream Jan 19, 2016
@samoconnor
Copy link
Contributor Author

@vtjnash, does this fix look right to you?


# TCPSocket

# PR#14627
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just merged this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one. I've just rebased.

@samoconnor
Copy link
Contributor Author

Thanks to @mmaxs for #14630 which found a LibuvStream gap in the coverage of test/read.jl. This PR (#14699) now incorporates a revised version of @mmaxs fix from #14630.

@samoconnor samoconnor force-pushed the uv_fs_read_eof branch 3 times, most recently from 6ca31cd to acde35e Compare January 20, 2016 03:04
@samoconnor
Copy link
Contributor Author

Windows now passing CI.
Linux i686 is passing CI.
Linux x86_64 is failing early in the build with make[1]: *** [julia-deps] Error 2

end)
end

if !haskey(ENV, "TRAVIS")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this can't run on travis, chances are it can't run on distro buildbots either. Not a good idea to special-case for CI like this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most definitely agree!
Just attempting to discover which part of the code is causing deadlock...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahk. did you track it down? I'm finding TCPSockets kind of challenging to add tests for myself. This branch helps get MbedTLS working again, though I'm not sure what its impacts are on the optimizations Jameson had been working towards.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope that this yield() will fix the deadlock. Waiting for Travis to start up to find out...

@tkelman
Copy link
Contributor

tkelman commented Jan 20, 2016

the commit samoconnor@29e5455 2161af4 that has nothing to do with File would be better suited for its own separate pr.

@tkelman
Copy link
Contributor

tkelman commented Jan 21, 2016

remaining untested methods from #14608:

  • readlines of a filename
  • readuntil of a filename
  • eachline of a filename
  • write(::IO, ::IO) for IO types that are not subtypes of AbstractIOBuffer

not-directly-tested newly introduced methods:

  • readavailable

@test read(io(), UInt8) == read(filename, UInt8)
@test read(io(), Int) == read(IOBuffer(text), Int)
@test read(io(), Int) == read(filename,Int)
cleanup()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the strange spacing is really distracting here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just taken out most of the temporary cleanup() calls.
That was an attempt to figure out why CI was hanging (i.e. maybe because of too many tasks/file handles/sockets ...).

@samoconnor
Copy link
Contributor Author

@tkelman: untested newly introduced methods: readavailable

You're talking about these right?

readavailable(io::File) = read(io)
readavailable(io::AbstractIOBuffer) = read(io)
readavailable(s::IOStream) = read!(s, Vector{UInt8}(nb_available(s)))

... called from here:

function write(to::IO, from::IO)
    while !eof(from)
        write(to, readavailable(from))
    end
end

...which is tested with 15 combinations of to and from stream types here.

What, in your opinion, would be an adequate test???

@tkelman
Copy link
Contributor

tkelman commented Jan 21, 2016

That's fine. An indirect test is better than no test, but that's literally the only call site of readavailable other than one line in examples/clustermanager/0mq/ZMQCM.jl.

@samoconnor
Copy link
Contributor Author

All the CI is passing now. (with #14747 test disabled).

Passing tests cover something like:
{filename, File, IOStream, IOBuffer, TCPSocket, PipeEndpoint}
X {read(s, T), read!(s) read!(s, a), eof(s), readstring(s), read(s), read bytes!(s, a), readuntil(s,c), readline(s), readlines(s), eachline(s), countlines(s), readcsv(s), position(s), seek(s,n), skip(s), seekend(s)}
X {short CSV string, + 4 x longer test strings approx SZ_UNBUFFERED_IO in length.}

@samoconnor
Copy link
Contributor Author

... that's literally the only call site of readavailable other than ...

I think I understand your concern. I think that readavailable should eventually be deprecated (or not exported).
See #14546 (comment) and #7478.

I also think that this generic implementation of write(to::IO, from::IO) should almost never be used once appropriate stream-type specialised methods are added. e.g. specialised methods should use sendfile in some cases or maybe mmap in others.

@tkelman
Copy link
Contributor

tkelman commented Jan 22, 2016

It is pretty widely used in packages according to github code search, which is most of my concern about it not being directly unit-tested here. So un-exporting it or deprecating it would break code / introduce warnings outside of base but not the tests within base (still probably worth the cleanup to do at some point though). "untested" was imprecise and unfair wording, sorry.

Add eof(::File), seek(::File) etc
to be consisitent with other ::IOs
See test case
JuliaLang#14747

clean up (hopefully) redundant celanup() calls in test/read.jl (left over from debugging hanging CI)
@samoconnor
Copy link
Contributor Author

ready to merge?

@vtjnash
Copy link
Sponsor Member

vtjnash commented Jan 24, 2016

It is pretty widely used in packages according to github code search...

that's annoying. i just read through the 12 pages of search results and found the following use cases for readavailable:

  1. a few were correct reimplementations of sendfile (aka write(to::IO, from::IO)), half of the time to is another real IO object, the other half of the time, it's a pseudo-IO / display object (like a WebSocket or GUI console)
  2. the rest were examples of broken code that might hang or print incomplete fragments if the output was non-trivial

vtjnash added a commit that referenced this pull request Jan 24, 2016
Fix eof() and read*() behaviour for ::File and ::LibuvStream
@vtjnash vtjnash merged commit d239fae into JuliaLang:master Jan 24, 2016
@coveralls
Copy link

Coverage Status

Changes Unknown when pulling 98744de on samoconnor:uv_fs_read_eof into ** on JuliaLang:master**.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:io Involving the I/O subsystem: libuv, read, write, etc.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants