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

refactor crates for better api stability #301

Merged
merged 14 commits into from
Mar 30, 2021
Merged

refactor crates for better api stability #301

merged 14 commits into from
Mar 30, 2021

Conversation

robjtede
Copy link
Member

@robjtede robjtede commented Mar 29, 2021

PR Type

Refactor / Semver improvement

PR Checklist

  • Tests for the changes have been added / updated.
  • Documentation comments have been added / updated.
  • A changelog entry has been made for the appropriate packages.
  • Format code with the latest stable rustfmt

Overview

  • actix-utils loses mpsc, task, timeout, dispatcher mods.
  • LocalWaker has own crate: local-waker.
  • MPSC channel has own crate: local-channel.

We want to reduce the number of 0.x items in the public API of stable crates like actix-web. Therefore, having some stable Ready futures is important for when/if futures crates have a version bump this year.

Dep tree of actix-net is now this:
2021-03-30_11 59 03-7dd746d9

@robjtede robjtede marked this pull request as ready for review March 29, 2021 09:24
@robjtede robjtede changed the title add local-waker crate refactor crates for better api stability Mar 29, 2021
@fakeshadow
Copy link
Contributor

fakeshadow commented Mar 29, 2021

I feel Dispatcher does not belong to actix-codec. With this change any crate import it would be tied to actix-service and actix-rt changes. (This is problemetic for some actix usage like use actors for Framed streaming as they would now import actix-service which was never a dep and exposed to it's changes)
It also worth to add that Dispatcher is only used in actix_http::ws module.

TimeoutService can be removed already. It's not used by anything now and it's not prefered when tokio timer is already very easy to use. For leaf future a Sleep and poll(Context).map(Error) and for async/await timeout(Future, Duration) are considerable easier to write than import a service type and an indirect error type(You either have to wrap it around an existing service type and boilerplate write it's service impl types or wrap them in boxed pipeline where the output is not namable anymore).

I don't feel the need to separate local-waker and local-channel too. As if we remove the useless timeout service and move dispatcher to actix-http where it belongs. actix-utils would only depends on futures-core and futures-sink. And if we remove the Sink impl of channel(It's not a very useful impl anyway and the current impl also have some issue on it. As all the impl actually does nothing other than return Ready so they basically does nothing) the only real dep is futures-core

@robjtede
Copy link
Member Author

robjtede commented Mar 30, 2021

The point of this change is to give better stability guarantees. Simply put, exposing tokio-util v0.6 items in actix-utils via dispatcher will not do because it is post v1. That said, I can provide further reasoning to your points.


With this change any crate import it would be tied to actix-service and actix-rt changes.

  1. any crate that uses codec is already expecting to use -rt or tokio
  2. crates that don't use the dispatcher will not be exposed to -service changes
  3. actix-service is very light extra dep
  4. -service and -rt are stable crates and we would not expect frequent breaking changes on them
  5. having dispatcher under -utils and tied to tokio-util is worse because breaking changes are more frequent on it due to it's release cadence being independnent from tokio

It also worth to add that Dispatcher is only used in actix_http::ws module.

Granted, this could also be solved by moving dispatcher to -http but then it would not be useful anywhere else. It could easily be useful for other purposes. Plus having it in -codec means we can break change whenever and move it if that's obviously a good choice in future.


TimeoutService can be removed already.

Yes, I think I agree with this point; that would make -utils a leaf crate which is good.

@fakeshadow
Copy link
Contributor

fakeshadow commented Mar 30, 2021

The thing about Dispatcher is it calls actix_rt::spawn for detach the service call. Making it only useful in actix,actix-web, awc and actix-server

In actix we don't use this pattern for dispatch future because actix_rt::spawn void the ability to run actor futures. This is why actix have it's own set of io module.

In actix-web we don't expose any type that can be AsyncRead/AsyncWrite.

In awc we indeed expose AsyncRead/AsyncWrite type with tunnel response but the returned io type is already framed. So we can not pass it to dispatcher either unless we want double the buffer memory usage and make the dispatcher run a doing nothing codec to avoid double encode/decode.

In actix-server indeed we can use dispatcher directly but one would still need actix-http to make a functional http server.

So basically dispatcher is almost not useful anywhere but if it's needed it mostly would couple with actix-http. The only case one can use it separately is using a actix-server for non http usage or usage light enough they can avoid import actix-http. In that case they probably don't want to use it still. As they would find it very limiting in APIs and would just handle framed service by themselves. (The reason of this is we actually don't have useful service type for handling non http usage. They would have to write custom service implement for their non http framed request which basically defeat the purpose of using it)

@robjtede
Copy link
Member Author

The only case one can use it separately is using a actix-server for non http usage or usage light enough they can avoid import actix-http

And indeed, the point of this repo is that there are no parts explicitly bound to using the HTTP protocol. The dispatcher here is useful exactly because WebSockets is not HTTP but is a much simpler TCP based protocol.

Given you feel strongly about this, we can move the dispatcher into either it's own crate or, more likely, into -http.

@fakeshadow
Copy link
Contributor

fakeshadow commented Mar 30, 2021

I believe websocket is on top of http right? The current usage of websocket through actix-util dispatcher is to use a double frame like Framed<Framed<TcpStream, H1Codec>, WsCodec>. So at least the http and websocket codec are needed where they are both lived in actix-http. Certainlly user can use their own codec but at the same time they would not have HttpService which would do the base codec for decode a request header and enter conditional upgrade service which give back the Framed<TcpStream, H1Codec> part.

I feel the dispatcher is used for other protocols like mqtt and amqp that Nikolay has transfered away from actix repos. They have their own service types and codec which are non exist anymore in actix repos.

@robjtede
Copy link
Member Author

I feel the dispatcher is used for other protocols like mqtt and amqp ...

This is my argument for not constraining a generic dispatcher to -http. But it's not an immediate concern, for sure.

@robjtede robjtede requested a review from fakeshadow March 30, 2021 10:37
actix-codec/CHANGES.md Outdated Show resolved Hide resolved
Copy link
Contributor

@fakeshadow fakeshadow left a comment

Choose a reason for hiding this comment

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

LGTM.

@robjtede robjtede merged commit 8becb0d into master Mar 30, 2021
@robjtede robjtede deleted the semver-structure branch March 30, 2021 12:39
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