-
Notifications
You must be signed in to change notification settings - Fork 1
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
Allow set
and add
methods to take uint types in addition to &str
#28
Conversation
set
method to take uint types in addition to &strset
and add
methods to take uint types in addition to &str
src/parser/mod.rs
Outdated
impl_to_memcached_value_for_uint!(u8); | ||
impl_to_memcached_value_for_uint!(u16); | ||
impl_to_memcached_value_for_uint!(u32); | ||
impl_to_memcached_value_for_uint!(u64); | ||
impl_to_memcached_value_for_uint!(usize); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only covered uint
s up to u64
here because afaik we should not be initializing negative counters, and u64
is the largest size of uint
that SFR is expecting.
8d22dc8
to
e2da127
Compare
8ce7e23
to
e1844e4
Compare
@mrattle some conflicts need to be resolved |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good
e1844e4
to
ca43669
Compare
ca43669
to
605fc21
Compare
src/parser/mod.rs
Outdated
@@ -103,6 +109,67 @@ pub struct KeyMetadata { | |||
pub size: u32, | |||
} | |||
|
|||
/// A trait for parsing multiple types of values to memcached values. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this in parser/mod.rs
? Isn't this only used for serializing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, doesn't quite make sense in there. Chopped it out into it's own file to try to avoid bloat in lib.rs
.
src/parser/mod.rs
Outdated
fn length(&self) -> usize; | ||
/// Writes the value to a writer. | ||
fn write_to<W: AsyncWriteExt + Unpin>( | ||
&self, | ||
writer: &mut W, | ||
) -> impl Future<Output = Result<(), crate::Error>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we collapse this into an fn as_bytes(&self) -> &[u8]
method? (Or maybe returning std::borrow::Cow<'_, [u8]>
if we need the option of returning owned values). This way we could avoid writing the uint types to the buffer twice and do so only once
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion, I was actually trying to work out a way to do exactly that so I'll play around with it a bit more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm running in to a couple of issues when trying to return bytes (either directly or through a Cow<_>
:
- for
-> &[u8]
- trying to return an owned value and there doesn't seem to be a concise way to satisfy the compiler - for
-> Cow<'_, [u8]>
:Cow
is looking for a vector which requires another allocation, but also seems to just return a reference to empty memory since the underlying data is dropped before it's used.
The path of least resistance to satisfy the compiler is to return a Vec<u8>
but this is very slow for long strings so it's a non-starter. I agree that parsing as bytes / writing to a buffer more than once is not great if it can be avoided but any performance cost seems to be negligible compared to a lot of the functional alternatives, though I could definitely be missing something.
src/parser/mod.rs
Outdated
@@ -103,6 +109,67 @@ pub struct KeyMetadata { | |||
pub size: u32, | |||
} | |||
|
|||
/// A trait for parsing multiple types of values to memcached values. | |||
pub trait ToMemcachedValue { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the intention that we want library consumers to be able to implement this on their own types? My preference would be to not allow that unless there is a need, and to prevent that with a private supertrait as described here.
Something like:
mod private {
pub(super) trait ToMemcachedValue {
...
}
}
pub trait ToMemcachedValue: private::ToMemcachedValue {
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I've refactored this with the sealed trait pattern.
src/parser/mod.rs
Outdated
) -> impl Future<Output = Result<(), crate::Error>>; | ||
} | ||
|
||
impl ToMemcachedValue for &[u8] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we do this so that we can continue to support all types that we did previously
impl ToMemcachedValue for &[u8] { | |
impl<T: AsRef<[u8]>> ToMemcachedValue for T { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When going down this route I end up having to create a standalone wrapper struct for u64 inputs which sort of defeats the intention behind this change, since it ends up making it more awkward to use a uint
value.
I've included String
and &String
implementations for ToMemcachedValue
which I think covers everything from AsRef
that we would realistically see as input for the set
and add
functions here. For reference, this rust-memcache crate is where we picked up this pattern from and they have implemented on the same set of types that I have updated this PR to include.
…sealed trait pattern to prevent external impl on consumer types
17af8e7
to
c4c9eb0
Compare
Closes: https://github.com/Shopify/caching-platform/issues/694
The original implementation of the
set
andadd
methods did not allow integer inputs, which doesn't make sense in the context of arithmetic methods likeincrement
anddecrement
.This PR introduces an
AsMemcachedValue
trait that serializes value inputs of different types into bytes to be used in memcached commands.