nickel-org / nickel.rs

An expressjs inspired web framework for Rust

Home Page:http://nickel-org.github.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Upgrade to support hyper 0.14

jolhoeft opened this issue · comments

Just announced - http://seanmonstar.com/post/161786147642/hyper-v011

This introduces some breaking changes, so may take a bit of time on a separate branch.

Quite a number of compile errors with a simple upgrade. Mostly unresolved imports, and types now private to hyper.

I've started working on this. There are a fair number of API changes, so I expect we will want support the 0.10 train a bit, as I expect we will need to break our API in turn.

For the curious, the tip of my fork, which doesn't yet build - https://github.com/jolhoeft/nickel.rs/tree/async_402

The upgrade is going to require some breaking API changes. One I am working on now is how values are handled in body_parser.rs, which converts the request body to a String, Json, or Param struct. Currently it returns those values directly, but that is not feasible with futures. I am considering two approaches:

  1. Change them to return Box<Future<Item=String, Error=NickelError>>, etc. This will prevent code using nickel 0.10.x from compiling, and require everything to be migrated over right away.
  2. Create a new body_transformer.rs that returns the values above, and have body_parser.rs use Future::wait() to synchronize and preserve the old behavior. Since synchronizing will significantly hurt performance, body_parser.rs will need to be deprecated and eventually removed, but this will ease migrating from nickel 0.10 to 0.11.

Any thoughts or preferences?

I've currently gone for option 2 on my personal branch. All that remains to to fix response handling, and update examples. I will probably wait until most or all of the examples are working before creating a pull request, unless someone would like to see it sooner.

Pull request #410 gets hello_world to work. So far it is pretty rough. More comments there.

Hey, I had worked on this a while back, but didn't have time to finish. I just cleaned it up a bit and put in #413, hope you can use some of my work if it is helpful.

Thanks for the PR. I've been looking over it as I can find time. We took two different approaches to handling the futures. I pushed the future in the Response, and let/make the middleware writers deal with it, while you unwrap the future and provide the contents to the middleware writer.

I like how your approach simplifies things for the middleware for a large majority of use cases. Most of the time, when there is a request body, the middleware needs the whole body before it can do much, so hiding the future is useful. I've been trying to figure out how to adapt this approach, but have run into a problem with the rest of the use cases.

Large request bodies, for example a video file upload, need to be fully uploaded and stored in a memory before the middleware can handle them. In that case though we would like to handle the stream as the upload proceeds and avoid large memory allocations.

At the moment my plan is to provide convenience methods to ease dealing with futures in the simple case (body_transformer.rs in my PR is a start on this). I will be keeping you approach in mind, though because I like the simpler API. Perhaps some outside the future hook for the streaming data case.

The current plan is to start this once async/await lands in stable. That will be in a development branch until hyper unitl it and hyper are stable under the new syntax.

Just curious, do we plan to support async/await? If so, is it being worked upon?

Yes, I am hoping to work on it soon. I may get a week free from work in the next month or so.

Just an update, I'm about halfway through.

I have a question for anyone following this. I have ran into an issue with the plugin crate, which has not been updated in about 5 years. plugin::Extensible is not Send as written, and given the age of the crate, getting it updated may be a problem. I'm thinking of removing the plugin mechanism completely, in favor of just implementing a trait on Request or Response. If the caching plugin provides is important enough, it can be added back in after async is working.

Thoughts?

At long last we have a pull request - #459. Some items still need to be added/fixed, but most of it is there. See the PR for a full discussion.

Tip of master now has about 3/4 of the features migrated to Hyper-0.14. Leaving this open, since still a lot to do.