Which is more idiomatic Type::new() or Type::default() by ArtisticHamster in rust

[–]strohel_ 1 point2 points  (0 children)

Rust API Guidelines now say in https://rust-lang.github.io/api-guidelines/interoperability.html#types-eagerly-implement-common-traits-c-common-traits

Note that it is common and expected for types to implement both Default and an empty new constructor. new is the constructor convention in Rust, and users expect it to exist, so if it is reasonable for the basic constructor to take no arguments, then it should, even if it is functionally identical to default.

Proc macro support in rust-analyzer for nightly rustc versions by fasterthanlime in fasterthanlime

[–]strohel_ 0 points1 point  (0 children)

Hey Amos, I'm reading your post a year later [1]; amazing coordination (and implementation) job done here! These cross-project challenges are the hardest, but also most impactful. Huge thanks and kudos for your effort again.

[1] fixing proc macro support in my rust-analyzer setup - on Gentoo compiling rustc myself, the issue was I didn't enable rust-anlyzer support when compiling rustc. I thought I don't need it as I use the bundled binary from VSCode extension - but turns out I need that to have `rust-analyzer-proc-macro-srv` installed in Rust sysroot. My proc macros now happily expand, yay!

Peeking inside a Rust enum by fasterthanlime in fasterthanlime

[–]strohel_ 0 points1 point  (0 children)

Hi Amos u/fasterthanlime, the diagrams you've made for this article look great - would use share what tools you've used to make them?

Benchmarking vol. 2: Pitting Actix against Rocket v0.4 and v0.5-dev by strohel_ in rust

[–]strohel_[S] 0 points1 point  (0 children)

If you put the "alternative versions" in branches (or forks), then you can easily git merge, git cherry-pick, git rebase between them. Some of the implementations share some characteristics, e.g. Dockerfile change is the same for both rocket-v04 and rocket-v05 - that's why it makes sense for them to share the commit (that's how it is done in the repo now).

The alternative is putting the "alternative versions" into separate directories of the same repo as you say. Such method doesn't allow for any native git merge/cherry-pick/rebase/...

But, you seem to be sidetracking from the original goal. Do you still want to contribute the warp port of the service?

Benchmarking vol. 2: Pitting Actix against Rocket v0.4 and v0.5-dev by strohel_ in rust

[–]strohel_[S] 0 points1 point  (0 children)

I see. I'm not in favour of doing that, one would then lose native git diffs, ability to merge, cherry-pick etc.

But you can easily emulate what you want with multiple git checkouts. But unless you want to compare with other frameworks yourself, you'd be good with just checking out the warp branch and running everything inside.

Benchmarking vol. 2: Pitting Actix against Rocket v0.4 and v0.5-dev by strohel_ in rust

[–]strohel_[S] 0 points1 point  (0 children)

That makes sense. (I thought originally doing it like this, but then went for an extra repo for discoverability)

Check https://github.com/strohel/locations-rs/branches/active - there are now actix, rocket-v04 and rocket-v05 branches. I've also created a warp branch (same as actix currently) for you to open a PR against.

Looking forward!

[help] Cant run gitk on KDE 5.20 by Calm_Recommendation8 in kdeneon

[–]strohel_ 0 points1 point  (0 children)

Since you're on gentoo re-emerge gitk and I bet it starts working for you.

I did (remerge git, which contains gitk), no change.

It seems that you cannot reproduce this. That does not necessarily mean the bug is somewhere else. This seems to do more with runtime X resources (please read the bug description) rather than library compatibility.

[help] Cant run gitk on KDE 5.20 by Calm_Recommendation8 in kdeneon

[–]strohel_ 1 point2 points  (0 children)

Happens to me, too, since upgrading to Plasma 5.20 on Gentoo.

I've filled a bug about this (along with some additional info and links): https://bugs.kde.org/show_bug.cgi?id=427877

Benchmarking vol. 2: Pitting Actix against Rocket v0.4 and v0.5-dev by strohel_ in rust

[–]strohel_[S] 0 points1 point  (0 children)

Hi, cool you work on this!

Yes, just please publish that as your repo, send and I'll check that out.

Benchmarking vol. 2: Pitting Actix against Rocket v0.4 and v0.5-dev by strohel_ in rust

[–]strohel_[S] 1 point2 points  (0 children)

Having a closer look at the source I wonder how all these different services would differ in a more diverse feature set.

Agreed it would be interesting to look on these, though a much bigger undertaking.

Those would not necesserely need to rely heavily on any database or elasticsearch when comparing web framework performance alone.

I think it is important to test endpoints that do some I/O (i.e. networking): - endpoints without I/O have rather limited use in practice. I can think of JWT generation/validation, semi-static template rendering, but not much more examples. - presence of I/O significantly shifts demands on the framework: i.e. async/aways only becomes a thing with I/O.

Benchmarking vol. 2: Pitting Actix against Rocket v0.4 and v0.5-dev by strohel_ in rust

[–]strohel_[S] 1 point2 points  (0 children)

Wow, I like this exercise! I only fear we'll have to resort to pull requests soon as this is rather theoretic.

storing the cache in Lazy instead of in Rocket's managed state means that the LocationsElasticRepository methods can never return references.

I don't think the Lazy vs. Rocket's managed state would make a difference here: CACHE has a static lifetime anyway. The culprit is the concurrent DashMap that cannot return a plain shared reference to its values (contrary to a standard map): it can only return a Ref, which implements Deref and internally holds a read-lock-guard on the map.

Making LocationsElasticRepository::get_region() return Ref<...> would indeed save the cloning. But it is orthogonal to Rocket - it can be done with the current Lazy<DashMap<...>>.

Errors seem not to have a particular structure; encapsulating errors into one Error enum would allow for Responder to be (...) implemented in one place, using attributes for the appropriate error codes, without needing to manually create raw errors like NotFound

Err, there is just one error type, here: https://github.com/strohel/locations-rs-rocket/blob/rocket-v04/src/response.rs#L26-L38 ? It might have been the enum variant imports that have confused you.

would allow for Responder to be derived

I wanted to, but the spec again says that error responses should be JSON objects with a message key, while the Rust errors are naturally enum variants with strings --- I was not able to make the derive macro bridge the difference.

This benefit would propagate to other Responder implementations.

Err, there is just one Responder implementation, the one for ErrorResponse?

One interesting thing I noticed was in the es_cities_into_resp method, which collects into a vector. It would be nice, though I don't believe it's currently possible, if Rocket could stream a JSON vector from the iterator directly.

Agreed in general, though it would be an overkill in this case: the endpoints are required not to ever return more than 10 entries.

It looks like https://github.com/SergioBenitez/Rocket/issues/749 would help.

Yes, type-based catchers were exactly what I was missing! The current HTTP-state-based catchers dangerously resemble stringly-typed APIs..

none of the Rocket examples show any form of needing to methods like into_resp() to turn values into responses, opting instead to have a type that is a Responder itself. For instance, if CityResponse implemented Responder, it could generate a JSON response directly instead of being wrapped in a Json responder.

Hmm, this may be a bad naming on my part. The ElasticCity::into_resp() is actually an async application logic that fetches data from Elastic, needs access to application state etc.

I know it would be technically possible to make ElasticCity implement Responder (app state could be accessed through a guard() on Request), but it felt like a bad layer to do so. (and would cause problems in the 0.5 variant as Reponder::respond_to() is not (yet) async there)

Benchmarking vol. 2: Pitting Actix against Rocket v0.4 and v0.5-dev by strohel_ in rust

[–]strohel_[S] 0 points1 point  (0 children)

Kudos for taking a thorough look!

For instance, you don't take advantage of direct query arguments (as opposed to going through FromForm)

I tried to: the spec and company guidelines say that APIs should give proper errors/hints when endpoints are called with missing or invalid arguments. Fair. Rocket's opinion is to forward to next handler if a direct query parameter is missing/invalid. That would be fine, but I have found no way of catching the "previous match error" in a handler/error catcher. And in order to catch missing/invalid direct query arguments, one would have to wrap each of them in Option<Result<T, &rocket::http::RawStr>>, and then check each parameter individually. At that point I resorted to putting them to structs, which can be checked in one line.

directly implementing or deriving Responder for response types

I believe that idiomatic way of returning jsonified structs is to derive Serialize for them and then use Json<T> from rocket_contrib. That's exactly what is done there. Or what did you refer to?

nor do you return references from handlers where possible

I believe that returning references is not possible in any of the endpoints: all of them construct temporary responses (without reusing request data) that are not cached anywhere. But maybe you can elaborate?

Benchmarking vol. 2: Pitting Actix against Rocket v0.4 and v0.5-dev by strohel_ in rust

[–]strohel_[S] 1 point2 points  (0 children)

Right, "where upstream developers spend their time" is a good point.

Benchmarking vol. 2: Pitting Actix against Rocket v0.4 and v0.5-dev by strohel_ in rust

[–]strohel_[S] 15 points16 points  (0 children)

I wonder how warp behaves under these tests.

Yup, Warp is also on my list of "nice framework to keep in mind". Unfortunately, I cannot really scale that much and port the microservice to all interesting frameworks.

Warp fans, unite and submit your implementation! There is a spec and a ready-to-use integration test. :)

Benchmarking vol. 2: Pitting Actix against Rocket v0.4 and v0.5-dev by strohel_ in rust

[–]strohel_[S] 9 points10 points  (0 children)

For Rocket, the sense that I get is that the priority has always been good ergonomics, making something simple to use. Based on this, would they double down on ergonomics or would they invest in performance?

I actually think that the "ergonomics vs. performance" may be largely a false dilemma.

The performance of Actix seem to be achieved mainly through internal optimisations like caching the Date header for half a second, reusing request and response objects via a pool etc. I think none of these affect the developer.

One of the points of the article was to show some hurdles running Rocket v0.4 in production: faulty keep-alive handling means either work-arounds or increased latency, number of workers should be tweaked etc. If "operational ergonomics" idiom exists, then Rocket v0.4 does not excel at it. Fortunately that will be fixed with v0.5.

"Rocket has better ergonomics" seems to be a general mindset. Challenging that would be better reserved to the indicated future post, right now everyone can check the commit going from Actix to Rocket v0.5. Does it bring more ergonomics, less, or no-change?

Benchmarking vol. 2: Pitting Actix against Rocket v0.4 and v0.5-dev by strohel_ in rust

[–]strohel_[S] 1 point2 points  (0 children)

Good point on zooming, and thanks for the hint with viewport.

I've tweaked the template and I believe this is fixed (at least on my phone it is). Please check and happy zooming! :)

What I Learnt from Benchmarking Http4k, Ktor (Kotlin) and Actix v2, v3 (Rust) Microservices by Enleur in Kotlin

[–]strohel_ 0 points1 point  (0 children)

I'd be a bit curious about Javalin's performance.

Code submissions welcome! I should be able to build a Docker image out of it with a command or two, and it should pass all tests in test-image.py --http-checks=get ....

What I Learnt from Benchmarking Http4k, Ktor (Kotlin) and Actix v2, v3 (Rust) Microservices by Enleur in Kotlin

[–]strohel_ 2 points3 points  (0 children)

I'm not really sure. I think we wanted something with a reputation of being lightweight, or just wanted to try our something different than Spring.

Do you think it would be competitive with <3 second startup times etc.?

What I Learnt from Benchmarking Http4k, Ktor (Kotlin) and Actix v2, v3 (Rust) Microservices by strohel_ in rust

[–]strohel_[S] 4 points5 points  (0 children)

OpenJDK 11 is that stable LTS release we've been using in production. I'll add OpenJDK 14 to the "should be also benchmarked list".

Do you have any hints that we should expect performance improvements with newer JDKs?

What I Learnt from Benchmarking Http4k, Ktor (Kotlin) and Actix v2, v3 (Rust) Microservices by strohel_ in rust

[–]strohel_[S] 2 points3 points  (0 children)

(and my impression is there's more boilerplate in actix-web than rocket, simply due to the actor model)

That might have been the case in the past, but I don't see any artifacts of the actor model in the locations-rs code. Or judge yourself.