+1 to matching Redis-style INCR. Returning `nil` is useful in some cases, 
like lazy-initializing a counter to a value that's expensive to calculate, 
but for typical use it's a strange hassle.

Note that Memcached doesn't support negative counters, so 
`@data.decr(normalize_key(name, options), amount, options[:expires_in], 
-amount)` may have unexpected results (setting to 0).


On Monday, September 25, 2017 at 11:40:13 PM UTC-7, Aero Astro wrote:
>
> Hi there.
>
> I made a Pull Request to fix bug on 
> ActiveSupport::Cache::MemCacheStore#increment
> and decrement for initialization of not stored value.
>
> https://github.com/rails/rails/pull/30716
>
>
> Regarding initialization, the current document says as follows.
>
> ```
> # Increment a cached value. This method uses the memcached incr atomic
> # operator and can only be used on values written with the :raw option.
> # Calling it on a value not stored with :raw will initialize that value
> # to zero.
> ```
>
> However, I would rather initialize the value with `amount` for increment 
> and `- amount` for decrement
> as if the not stored value is initialized to 0 prior to the specified 
> operation.
>
> ```
> # Before
> @data.incr(normalize_key(name, options), amount, options[:expires_in], 0)
> @data.decr(normalize_key(name, options), amount, options[:expires_in], 0)
>
> # After
> @data.incr(normalize_key(name, options), amount, options[:expires_in], 
> amount)
> @data.decr(normalize_key(name, options), amount, options[:expires_in], 
> -amount)
> ```
>
>
> The reason is that we want to implement appropriate lazy initialization.
> For example, simple counter with lazy initialization can be written with 
> instance variable as follows.
>
> ```
> def increment(amount)
>   @counter ||= 0
>   @counter += amount
> end
> ```
>
> If we implement the above counter with current 
> ActiveSupport::Cache::MemCacheStore, it can be written as follows.
>
> ```
> def increment(amount)
>   result = @cache.increment(amount)
>   result != 0 ? result : @cache.increment(amount)
> end
> ```
>
> As you can see, the initialization to 0 inside @cache actually does not 
> help us write lazy initialization.
> We should still handle 0 instead of nil. What is worse, if we use 
> increment and decrement concurrently
> on the same key, there is no way to calculate the accurate count.
>
> With the proposed feature request the above code can be simplified as 
> follows.
>
> ```
> def increment(amount)
>   @cache.increment(amount)
> end
> ```
>
> Also, I have found the same specification on incr of Redis.
> https://redis.io/commands/incr
>
> If the idea is O.K., I will submit another PR or change the current PR to 
> address the issue.
> IMHO, as this initialization has been disabled for a long time, it is 
> about time to improve the specification.
>
> --
> Best Regards,
> Takumasa Ochi
>

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to rubyonrails-core+unsubscr...@googlegroups.com.
To post to this group, send email to rubyonrails-core@googlegroups.com.
Visit this group at https://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.

Reply via email to