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

Specifying a expiration Timespan with precision higher than 1 millisecond does not work with Redis #57

Closed
masterpoi opened this issue Apr 4, 2016 · 10 comments
Labels
Milestone

Comments

@masterpoi
Copy link

When you store a CacheItem in the cache and give it a Timespan like Timespan.FromMilliseconds(4564.264), the item cannot be properly deserialized because of an invalidcastexception due to the cast to (long) in
https://github.com/MichaCo/CacheManager/blob/dev/src/CacheManager.StackExchange.Redis/RedisCacheHandle.cs#L364

I ran into this by doing stuff like context.Ticket.Properties.ExpiresUtc - DateTimeOffset.UtcNow

@MichaCo
Copy link
Owner

MichaCo commented Apr 4, 2016

Yup, the code does not support floating point numbers for expiration in milliseconds.

But good point, I might have to change the set operation to store a valid number...

@MichaCo MichaCo added the bug label Apr 4, 2016
@jzabroski
Copy link

Please do not use floating point. Decimal is OK, but milliseconds should not be stored in a lossy format. Use TimeSpan.FromTicks(Int64) instead. There are 10,000 ticks in a millisecond, so this is strictly more expressive and non-lossy!

@masterpoi
Copy link
Author

Fwiw, i don't need sub-millisecond precision, so rounding to the nearest millisecond when setting is fine. I'm doing this as a workaround currently anyways.

@MichaCo
Copy link
Owner

MichaCo commented Apr 4, 2016

I changed it from Ticks (long) to millis at some point to save some space. The precision is not that high anyways.

Thanks for the feedback though

@jzabroski
Copy link

Save space where? I am suggesting the configuration still be milliseconds, but you don't use a .NET method that is inherently not portable across CPUs. Just take the value and multiply it by 10,000 and pass it to FromTicks(long)

@MichaCo
Copy link
Owner

MichaCo commented Apr 4, 2016

The point is that Redis EXPIRE sets the TTL in seconds and if you want to get more precise you can use PEXPIRE which uses milliseconds instead.
Which means, there is absolutely no reason to store or work with ticks.

Another reason I'm using milliseconds is that I can use it directly within the LUA script without any calculations.

Saving some space means, I don't store a larger number on each cache entry in Redis. It's a small save, but it adds up...

@jzabroski
Copy link

I think we're on the same page. All I am suggesting is that the .config file have the setting in ticks, but the actual .NET property that reads the ConfigurationManager setting convert it by multiplying by 10,000. Either way you are using a TimeSpan object, right? So I don't see where you accumulating "Small save" of space. But I do see how it is slightly possible to have precision loss due to storing doubles. Moreover, double and long are both 8 bytes... so I think we're really talking about portability?

@masterpoi
Copy link
Author

The point is, Timespan stores sub-millisecond precision which is not needed in this case because the most accurate precission Redis uses is apparently milliseconds. So just rouding the Timespan to the nearest millisecond when storing the thing in Redis is the best solution imo, as @MichaCo allready indicated. No ticks needed.

@MichaCo
Copy link
Owner

MichaCo commented Apr 5, 2016

@jzabroski we are talking about different things.

Yes I'm using TimeSpan internally in code and keeping the settings in process, no need to argue about if it is ticks or millis in that case, it is just TimeSpan...

But when it comes to Redis, CacheManager stores the actually configuration value for expiration along with the cache entry within Redis. To do so, I use a plain number, and store it in milliseconds, not ticks, (because ticks would just consume more memory on the Redis instance).

You see the difference now? ;)

@jzabroski
Copy link

Yes. Ok.

@MichaCo MichaCo added bug and removed bug labels Jun 19, 2016
@MichaCo MichaCo added this to the Version 0.9 milestone Jun 19, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants