[PATCH] "incr" supports wraparound
Evan Miller
emiller at imvu.com
Fri Aug 17 18:50:11 UTC 2007
Marc wrote:
> I think this patch is right. docs/protocol.txt clearly states it's meant to
> be unsigned. I think wrapping to zero best satisfies the principle of least
> astonishment.
>
> FWIW, I think the strtol instead of strtoul is my fault. I'm not sure how I
> missed that. In my defense, I'm guessing I just tried to preserve the
> signedness of the orignal implementation.
Hey no worries. At least there's a test now. :)
If wrapping around is going to break some application code out there,
should we go ahead and up the counter size to 64 bits and make
wraparound virtually a non-issue? That is, does anyone whose counters
reach the billions rely on the counters' 32-bittedness?
Evan
>
> On 8/16/07 7:39 PM, "Evan Miller" <emiller at imvu.com> wrote:
>
>> Clint Webb wrote:
>>> Why would you *want* a wraparound when incrementing?
>>> Quite the opposite for me, I do not want it to wrap around, because then
>>> I would require additional code to check that. Right now, very
>>> simply... if my increment fails, I reset all the data that is associated
>>> with that key, and start again.
>> Wraparound might actually be a better solution for you, because it
>> solves the concurrency problems. Currently, several clients that
>> simultaneously attempt to increment past the size limit will all receive
>> errors, and they will all attempt to run your reset logic. I don't know
>> about your specific use-case, but for us this means that increments get
>> lost in the meantime (multiple clients reset the counter to 1).
>>
>> With wraparound, only one client will receive a "0" return value, and so
>> only one client will run the additional reset logic.
>>
>> It's true that clients which rely on the increment errors will need
>> tweaking, but overall wraparound makes Memcached more useful and robust
>> as a generic counter service.
>>
>> It would be even more useful if calling "incr" on a non-existent key set
>> the value to "1" in order to avoid race conditions similar to what I
>> describe above, but that's a different can of worms...
>>
>> Evan
>>
>>> Although, it is possible that treat a '0' returned as a wrap failure in
>>> your scenario, it is easier for me to treat the wrap error the same as
>>> if the key had expired, or the service had been restarted, causing me to
>>> replenish the data that appears to be missing.
>>>
>>> On 8/17/07, *Evan Miller* <emiller at imvu.com <mailto:emiller at imvu.com>>
>>> wrote:
>>>
>>> Currently Memcached gives an error when incrementing large counters:
>>>
>>> set foobar 0 0 10
>>> 2147483647
>>> STORED
>>> incr foobar 1
>>> 2147483648
>>> incr foobar 1
>>> CLIENT_ERROR cannot increment or decrement non-numeric value
>>>
>>> I believe this is a bug. Attached is a patch to make counters wrap
>>> around the 2**32 mark, similar to counters in routers. New behavior:
>>>
>>> set foobar 0 0 10
>>> 4294967294
>>> STORED
>>> incr foobar 1
>>> 4294967295
>>> incr foobar 1
>>> 0
>>>
>>> A CLIENT_ERROR will continue to be returned if a value above 2**32 is
>>> incremented, but the "incr" command will never push the value over that
>>> mark.
>>>
>>> A future version of Memcached should probably use a 64-bit counter
>>> instead, but the 32-bit limit is in line with the existing docs. ("The
>>> data for the item is treated as decimal representation of a 32-bit
>>> unsigned integer.")
>>>
>>> The patch also adds "const" keywords to arguments of do_add_delta and
>>> mt_add_delta, to be consistent with the header file.
>>>
>>> Documentation and tests have been updated.
>>>
>>> Evan Miller
>>> IMVU, Inc.
>>>
>>>
>>>
>>>
>>> --
>>> "Be excellent to each other"
>
>
>
More information about the memcached
mailing list