@@ -13,7 +13,7 @@ module AtomicDirectUpdate
1313 # Pass the current value to the given block, replacing it
1414 # with the block's result. May retry if the value changes
1515 # during the block's execution.
16- #
16+ #
1717 # @yield [Object] Calculate a new value for the atomic reference using
1818 # given (old) value
1919 # @yieldparam [Object] old_value the starting value of the atomic reference
@@ -27,17 +27,45 @@ def update
2727 # @!macro [attach] atomic_reference_method_try_update
2828 #
2929 # Pass the current value to the given block, replacing it
30+ # with the block's result. Return nil if the update fails.
31+ #
32+ # @yield [Object] Calculate a new value for the atomic reference using
33+ # given (old) value
34+ # @yieldparam [Object] old_value the starting value of the atomic reference
35+ #
36+ # @note This method was altered to avoid raising an exception by default.
37+ # Instead, this method now returns `nil` in case of failure. For more info,
38+ # please see: https://github.com/ruby-concurrency/concurrent-ruby/pull/336
39+ #
40+ # @return [Object] the new value, or nil if update failed
41+ def try_update
42+ old_value = get
43+ new_value = yield old_value
44+
45+ return unless compare_and_set old_value , new_value
46+
47+ new_value
48+ end
49+
50+ # @!macro [attach] atomic_reference_method_try_update!
51+ #
52+ # Pass the current value to the given block, replacing it
3053 # with the block's result. Raise an exception if the update
3154 # fails.
32- #
55+ #
3356 # @yield [Object] Calculate a new value for the atomic reference using
3457 # given (old) value
3558 # @yieldparam [Object] old_value the starting value of the atomic reference
3659 #
60+ # @note This behavior mimics the behavior of the original
61+ # `AtomicReference#try_update` API. The reason this was changed was to
62+ # avoid raising exceptions (which are inherently slow) by default. For more
63+ # info: https://github.com/ruby-concurrency/concurrent-ruby/pull/336
64+ #
3765 # @return [Object] the new value
3866 #
3967 # @raise [Concurrent::ConcurrentUpdateError] if the update fails
40- def try_update
68+ def try_update!
4169 old_value = get
4270 new_value = yield old_value
4371 unless compare_and_set ( old_value , new_value )
0 commit comments