Skip to content

convert to use tokio 0.1 #1462

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

Closed
wants to merge 1 commit into from
Closed

Conversation

srijs
Copy link
Contributor

@srijs srijs commented Mar 14, 2018

All the tests pass! 🎉 (at least locally -- let's see what CI says)

Spend this morning rebasing due to 0.12.x moving so fast!

Fixes #1443

@srijs srijs force-pushed the 0.12.x-tokio-0.1.x branch from ed10c2a to 52796df Compare March 14, 2018 23:48
@seanmonstar
Copy link
Member

Woo! Nice! (And sorry about 0.12.x, I had been rebasing master onto it for a while, assuming most people weren't actually depending on its history 😭 ).

@srijs
Copy link
Contributor Author

srijs commented Mar 15, 2018

No worries, I was just surprised by how quickly it had moved since I started a couple of days ago :)

One thing to note here is that I've tried to keep the API mostly the same (biggest exception being Server::run). It sounded like it would be a good idea to postpone improving the API until later, after the "raw" tokio integration landed. Let me know if you feel different!

Copy link
Member

@seanmonstar seanmonstar left a comment

Choose a reason for hiding this comment

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

This is fantastic! 🎉 So much goodness!

Looks like there's a hanging test, client::tests::retryable_request...

.bind(&addr, new_service)
.unwrap();

println!("Listening on http://{} with 1 thread.", server.local_addr().unwrap());
Copy link
Member

Choose a reason for hiding this comment

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

All the lines printing about using 1 thread can probably be adjusted now :D

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Heh, will do!

let mut core = tokio_core::reactor::Core::new().unwrap();
let handle = core.handle();
let client = Client::new(&handle);
tokio::run(lazy(move || {
Copy link
Member

Choose a reason for hiding this comment

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

I'm curious what the lazy usage is for. Is that because calling all this code outside of tokio::run will panic?

Copy link
Contributor Author

@srijs srijs Mar 15, 2018

Choose a reason for hiding this comment

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

Yeah, most constructors including Client::default now need a thread-local handle. When we change the API I think we should probably defer most or all I/O (like port binding) until the future is polled, but for now that's the compromise I made.

@srijs
Copy link
Contributor Author

srijs commented Mar 15, 2018

The hanging test is a weird one, it works on my machine (OS X), so I can't reproduce at the moment. I'll grab an AWS instance later to try and reproduce on Linux.

@seanmonstar
Copy link
Member

I'll try to rent an AWS instance later to try and reproduce on Linux.

Don't bother! I can debug it myself.

@srijs
Copy link
Contributor Author

srijs commented Mar 15, 2018

Thanks, much appreciated!

In other news, my PR to split off tokio-tcp (tokio-rs/tokio#224) was merged, so we can hopefully drop the direct dependency on tokio soon-ish

@seanmonstar
Copy link
Member

For the hanging test, it's a combination of mutexes in the mock duplex code, and using the ThreadPool executor. The hang went away when I made sure that the task.notify() and the read or write happened without releasing the lock. But the test fails in an error since the tasks are on separate threads, but with only 1 core and mutexes, the code can't happen in the order that is being tested.

The test is specifically designed to be a series of events we can control, because its testing those series of events. I suspect that switching to the tokio's current_thread executor for that test will fix it.

@srijs
Copy link
Contributor Author

srijs commented Mar 15, 2018

Hmm, so the issue with current_thread is that it's not Send nor Sync, making it unsuitable for a custom executor.

The only way I can think of solving that problem is to make it optional for Client to be Send, which would probably require tracking that as type state, e.g. Client<IsSend> vs Client<IsNotSend> or making the executor a type parameter itself, e.g. Client<TaskExecutor>.

Maybe there is another way to fix the tests so they could run on a multi-threaded executor?

@srijs srijs force-pushed the 0.12.x-tokio-0.1.x branch from 52796df to 78f13ee Compare March 15, 2018 08:15
@srijs
Copy link
Contributor Author

srijs commented Mar 15, 2018

Okay, so I think I fixed the initial problem by using a thread pool of size 1 as an executor. There are some other failures now on Travis that I still can't reproduce locally :/

Any chance you could have another look?

@srijs srijs force-pushed the 0.12.x-tokio-0.1.x branch 2 times, most recently from 7e0c6a1 to cd0e494 Compare March 15, 2018 08:43
@seanmonstar
Copy link
Member

I'll look into that test failure. Besides that, the benches don't compile XD.

@seanmonstar
Copy link
Member

So the failing keepalive client test is because of tasks being on separate threads, but with only 1 CPU, the order isn't preserved. Well, on one hand, it's good to find poorly written tests that break on multithreaded!

The test itself is ensuring that after we get a response back, a second request to same host should reuse the existing connection. However, knowing that the connection can be reused requires the Dispatch task to do some housekeeping after submitting the response back to the FutureResponse task. So, by the time the main thread has the response and starts a new request, the Dispatch task on the other thread hasn't had a chance to cleanup state and set itself ready for a new request, so it isn't back in the client's pool.

As a hack, we could just sleep the main thread for a few milliseconds, allowing the dispatch task to clean up...

Perhaps in a separate issue, the design of that can be changed, since changing this test definitely means that users may see on occasion requests not reusing a connection it could have.

@srijs
Copy link
Contributor Author

srijs commented Mar 15, 2018

Thanks for providing more info on that test! I thought I fixed that particular test earlier by introducing exactly the sort of thread::sleep that you suggested.

The latest Travis run showed two other tests failing instead: one with a ‚resource temporarily not available‘ error, and the other one (a dispatch test) timing out.

I‘ll try to fix the benches later!

@seanmonstar
Copy link
Member

I've got the benches passing, and fixed up that test, in https://github.com/hyperium/hyper/tree/new-tokio. I've been pushing to that to trigger CI, and looking at some panics.

Seems one was due to a race condition in the futures mpsc channel, so I've a work around there. Waiting for CI again...

@seanmonstar
Copy link
Member

Yay! CI is green! I'll see about merging this ... probably tomorrow, its getting late x_x

@srijs srijs force-pushed the 0.12.x-tokio-0.1.x branch from cd0e494 to 6b74077 Compare March 16, 2018 10:04
@srijs srijs force-pushed the 0.12.x-tokio-0.1.x branch from 6b74077 to 1d845f3 Compare March 16, 2018 10:07
@srijs
Copy link
Contributor Author

srijs commented Mar 16, 2018

@seanmonstar Nice! I pulled your changes into this branch, just in case you had any other feedback you wanted to see addressed before merging.

AppVeyor builds seem to be failing both on this as well as your new-tokio branch, could that be related to our changes?

@seanmonstar
Copy link
Member

The issue on Windows was that we needed to call bind on the TcpBuilder before connect. All good now. I also loosened the requirement of Entity, such that the trait itself doesn't require Send, only when used in Client and Server and thus interacts with an Executor. That way, if people want to work with non-Send things, they still can, using hyper::{client, server}::conn.

I merged those changes into your commit, and merged it into 0.12.x here: 603c3e4

Thank you sooo much!

@srijs srijs deleted the 0.12.x-tokio-0.1.x branch March 17, 2018 02:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants