Repository: rails/rails
File: activesupport/lib/active_support/cache/strategy/local_cache.rb (Ruby)

Code before:
            if cache = local_cache
              hit = true
              entry = cache.fetch_entry(key) do
                hit = false
                super
              end
              options[:event][:store] = cache.class.name if hit && options[:event]
              entry
            else
              super
            end
          end

          def read_multi_entries(names, **options)
            return super unless local_cache

            keys_to_names = names.index_by { |name| normalize_key(name, options) }

            local_entries = local_cache.read_multi_entries(keys_to_names.keys)

            results = local_entries.each_with_object({}) do |(key, value), result|
              normalized_key = keys_to_names[key]
              version = normalize_version(normalized_key, options)

              entry = deserialize_entry(value, **options)
              if entry && (entry.expired? || entry.mismatched?(version))
                local_cache.delete_entry(key)
              else
                result[normalized_key] = entry&.value
              end
            end

            missed_names = names - results.keys

            results.merge!(super(missed_names, **options)) if missed_names.any?
            results
          end

          def write_serialized_entry(key, payload, **)
            if return_value = super
              local_cache.write_entry(key, payload) if local_cache
            else
              local_cache.delete_entry(key) if local_cache
            end
            return_value
          end

          def delete_entry(key, **)
            local_cache.delete_entry(key) if local_cache
            super
          end

Review comment (suggestion):
```suggestion
              if entry && (entry.expired? || entry.mismatched?(normalize_version(keys_to_names[key], options)))
```

Would be better, because while more verbose we'd save on computing the version for missing and expired entries.

Code after:
            if cache = local_cache
              hit = true
              entry = cache.fetch_entry(key) do
                hit = false
                super
              end
              options[:event][:store] = cache.class.name if hit && options[:event]
              entry
            else
              super
            end
          end

          def read_multi_entries(names, **options)
            return super unless local_cache

            keys_to_names = names.index_by { |name| normalize_key(name, options) }

            local_entries = local_cache.read_multi_entries(keys_to_names.keys)

            results = local_entries.each_with_object({}) do |(key, value), result|
              entry = deserialize_entry(value, **options)

              normalized_key = keys_to_names[key]
              if entry.nil?
                result[normalized_key] = nil
              elsif entry.expired? || entry.mismatched?(normalize_version(normalized_key, options))
                local_cache.delete_entry(key)
              else
                result[normalized_key] = entry.value
              end
            end

            if results.size < names.size
              results.merge!(super(names - results.keys, **options))
            end

            results
          end

          def write_serialized_entry(key, payload, **)
            if return_value = super
              local_cache.write_entry(key, payload) if local_cache
            else
              local_cache.delete_entry(key) if local_cache
            end
            return_value
          end

          def delete_entry(key, **)
            local_cache.delete_entry(key) if local_cache