MemCacheStoreでMarshalシリアライザを明示的に指定
Rails 8.1では、ActiveSupport::Cache::MemCacheStoreがDalliクライアントを初期化する際に、Marshalシリアライザを明示的に指定するようになりました。
背景
Dalli 4.0.0では、シリアライザが明示的に指定されていない場合に警告メッセージを表示する仕様変更が行われました。一方、Rails側では従来からserializerオプションをユーザーが指定できないように削除していたため、Dalliのデフォルトシリアライザ(Marshal)が自動選択される際に警告が表示されていました。
#56588で報告されたこの問題は、MemCacheStoreを使用するたびに不要な警告が出力されるというユーザー体験の問題でした。
技術的な変更
変更箇所:
@mem_cache_options[:compress] = false
(OVERRIDDEN_OPTIONS - %i(compress)).each { |name| @mem_cache_options.delete(name) }
# Set the default serializer for Dalli to prevent warning about
# inheriting the default serializer.
@mem_cache_options[:serializer] = Marshal
@data = self.class.build_mem_cache(*(addresses + [@mem_cache_options]))
変更により、Dalliクライアントの初期化時にserializer: Marshalが明示的に渡されるようになります。これはRailsが常に使用していたデフォルトの挙動を明示化したもので、機能的な変更はありません。
テストコードの変更:
assert_called_with(Dalli::Client, :new, [%w[localhost], { compress: false, serializer: Marshal }]) do
store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost", pool: false
assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
end
テストでは、Dalliクライアントの初期化時にserializer: Marshalが含まれることを検証するように更新されています。
設計判断
このPRでは、以下の設計判断がなされています:
後方互換性の維持: Marshalシリアライザはこれまでも暗黙的に使用されていたため、明示的に指定しても既存の動作は変わりません。
ユーザーのオーバーライド不可: 従来通り、
serializerオプションはOVERRIDDEN_OPTIONSに含まれていないため、ユーザーが独自のシリアライザを指定することはできません。これはRailsのキャッシュストアの一貫性を保つための制約です。警告の抑制: Dalli 4.0.0の警告機能は、シリアライザの選択を意識的に行うことを促すものですが、Rails側では既に制御されているため、明示的な指定により警告を回避できます。
PRのDescriptionでは、ユーザーがsilence_marshal_warningオプションを使用する回避策にも言及されていますが、根本的な解決としてserializerを明示的に指定する方法が採用されました。
Dalli 4.0.0への対応
今回の変更に伴い、Gemfile.lockでDalliのバージョンが3.2.8から4.0.0に更新されています。Dalli 4.0.0では、シリアライザの扱いに関する重要な変更が含まれており、この対応が必要になりました。