-
Notifications
You must be signed in to change notification settings - Fork 78
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
Deserialize series using field names, not order #62
Deserialize series using field names, not order #62
Conversation
I made a further branch after realising that the current design does not handle My API experiment sped up by around 70% by using a "group by" on the three tags I have, presumably due to the reduction in redundancy in the payload. Oh, and I just ran into an issue: if you don't get any results, |
Thanks for this pull request! 👍🚀 Please excuse my slow response time, I am quite busy with university exams right now. I will be reviewing your pull request now. |
I have taken a look at your branches and want to thank you again for all the thoughts you have poured into improving the handling. Using the field order was one of the easier solutions at the time, but always felt quite hacky. I'm very happy with your implementation. Correctness improvements are always very welcome! 🏅 Personally, I'd have no problem adding How do you want to proceed with this PR? :)
Nice catch! I think you can open another pull-request for that and I'll merge it right away. |
Thanks for taking a look! And no worries, I've just been pointing at my branch, naturally. Good luck with the exams!
Glad to hear that you like it.
Absolutely. I originally used
Sure, I'll extract that into a separate PR.
I've been using the I also notice that you already did the lint fixes in a previous commit, so I'll remove them from this PR. |
Oh, I forgot to ask: do you want the |
6f46512
to
a574e88
Compare
I'm not too worried about the API changing, as we're still below 1.0.0 and there's other breaking changes scheduled for the next release. If the changes are too big to be explained in the CHANGELOG.md, I think adding a MIGRATING.md document will make sense.
It's an addition that's going to benefit everyone, so I'm interested in it. I will need to play around with the new API a bit to get a feeling for the changes. Maybe there could be a way to zip together tags and series again, maybe with a custom iterator, but I'd consider such usability improvements out of scope for this PR. |
a574e88
to
e5f0c63
Compare
OK, so the new dependencies have been removed. I had forgotten that I could just pass around a
Yeah, that makes sense. Rust expects patch changes to be compatible before 1.0.0, but as long the breaking change is a minor version bump that's fine.
Feel free. I tried a second type parameter on
In my case I don't want them zipped, so I don't have any strong feelings on such a feature. It would also be possible to make a
I wouldn't assume that - I've only done some Rust as a hobby now and then over two years. This has been a learning experience for me too :) Oh, and I'm off for the day, so if there's anything, I'll pick this back up tomorrow sometime. |
7ee7b37
to
8785ebc
Compare
I have played around with the changes and am quite happy with them! I will merge when you give the final go, that you're happy with everything at its current status.
I find this project to be more of a community effort to create a modern and easy to use InfluxDb client, than my personal thing. I'm happy to see contributions and progress, everything else is decided together! |
I just checked this one out, and it seems it double-quotes strings, at least in my case, just FYI. I did run into the problem it solves, and, otherwise, it seems to be a pretty drop-in replacement. |
Hi, is there any way this branch can be merged into master? It does work, and since there's a fix in the other branch for double quotes, hopefully this solves both issues, yeah? @SafariMonkey Can you merge master into this branch and give us the final go? If you like, I can give you a thumbs up from my codebase. |
Hi, sorry for the long silence. Life things have been getting in the way of my being able to go in and figure out how to address the issue raised by @cryptoquick. I keep meaning to pick it up but not getting to it - I was hoping to finally do so now that I'm on holiday. I appreciate your patience, as well as the encouragement to get it done :) . I did not realize that the quoting issue had already been independently resolved, in which case it's basically good to go - that was my only outstanding concern, so I'll just rebase it, confirm it works with my code, and then give it a once over before approving. By the way, the way this library does data insertion doesn't work with my use case at all, as we have custom quoting requirements. (We have our own escaping system to deal with InfluxDB's ridiculous quoting issues.) Fortunately, I'm not looking to use this library to insert data, so as long as it gives me the raw form of the metrics and doesn't try to escape them on the way out itself, it should work fine. |
Add a custom Deserialize impl for Series which uses the field names in the columns field of the response to allow the inner type to deserialize itself as a map instead of relying on the field order.
8785ebc
to
d0396f5
Compare
I've rebased, tried it out, and it seems to work. I've read through the changes again and they look fine, so if you are happy with them too, feel free to merge them. I'll open a PR for the Thank you for your patience. |
Thank you again for this contribution! Will merge now! |
As promised, I posted the |
BTW, we're using this code in our production branch and it works perfectly. Great work! ❤️ |
Description
Add a custom
Deserialize
impl forSeries
which uses the field names in the columns field of the response to allow the inner type to deserialize itself as a map instead of relying on the field order. This means that the field order of your structs do not need to match the query field order, and prevents mistakes due to inconsistencies between those. It also means aSELECT *
could go into a hashmap and work just fine if you wanted to.I added a couple of crates while I was prototyping:
smol_str
andmaplit
(dev). These can easily be removed, but I found a 10% speedup on deserialising+serving (mocking the databse response) when using allSmolStr
overString
in both headers and my field values, andhashmap
literals are nice in tests. (It's probably worth noting that the SmolStr change improved performance from 1700 to 1900 requests per second, but actually hitting the database it was more like a difference of 213 to 218 - certainly nothing to write home about.)If you were interested in improving the performance, though, I imagine that the Results struct could hold the full response body + a
Vec
ofserde_json::value::RawValue
, and then you could also have adeserialize_next_borrowed<'de, T>(&'de self) -> Result<Return<T>, Error> where T: Deserialize<'de> + Send
or something. I experimented with such an implementation on thedeserialize-borrowed
branch. I didn't go the whole way with the RawValues borrowing from the body, but using something likeowning_ref
it should be possible - it requires unsafe with the current API ofowning_ref
, though, and speaking briefly with the creator of that project today, they made it clear that they are not maintaining it at this time. I don't know if an API that copies each entire query result is really a win vs. an API that deserialises it into a structured JSON representation instead, especially as the current (structured JSON) one can just reuse the string allocations from the JSON in the result. Using the borrowing based API is also more awkward, of course, as theDatabaseQueryResult
can't be a temporary... it's probably a case of overengineering.In summary, I think the core of this PR is I think a correctness win without an API change. There are some performance improvements possible, but given the slowness of InfluxDB, they're unlikely to make enough of a difference to be noticeable.
Checklist
cargo fmt --all
cargo clippy --all-targets --all-features -- -D warnings
(first commit in PR)cargo readme > README.md
(no, because it mostly just deleted stuff)