You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Refactor BroadcastLogger; only execute blocks once
[Fixesrails#49745rails#52876]
[Related rails#51883rails#49771]
This commit refactors the implementation of dispatching method calls
to broadcasted loggers. The updated implementation ensures that any
block is only executed once. The first logger would recieve the block
as per normal, but subsequent loggers would only yield the result of
the initial execution.
The updated implementation of `dispatch` opened up an opportunity to
refactor the way each Logger method is delegatated to broadcasted
loggers - simplifying the delegator definitions.
Prior to these changes, BroadcastLoggers would iterate each broadcast
and re-execute the user provided block for each.
The consumer of any Logger would reasonably expect than when calling a
method with a block, that the block would only execute a single time.
That is, the fact that a Logger is a BroadcastLogger should be
irrelevant to consumer.
The most common example of this is when using
ActiveSupport::TaggedLogging and wrapping behaviour in a
`tagged(*tags) { }` block. But this also applies when using the block
form `info`, `warn` etc. If a BroadcastLogger is used, and there are
multiple loggers being broadcast to, then calling one of these methods
with a block would result in the block being executed multiple times.
For example:
```ruby
broadcasts = ActiveSupport::BroadcastLogger.new(
*Array.new(2) { ActiveSupport::Logger.new(STDOUT) }
)
number = 0
broadcasts.info {
number += 1
"Updated number to #{number}"
}
# Expected:
# Updated number to 1
# Updated number to 1
#
# Actual:
# Updated number to 1
# Updated number to 2
```
After these changes, the behaviour of BroadcastLogger reflects the
expected behaviour above.
0 commit comments