何が起きたか
以下の force_encoding
実行時に body
が凍結されていたようで、 FrozenError が発生した。
# Licensed to Elasticsearch B.V under one or more agreements.
# Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
# See the LICENSE file in the project root for more information
module Elasticsearch
module Transport
module Transport
# Wraps the response from Elasticsearch.
#
class Response
attr_reader :status, :body, :headers
# @param status [Integer] Response status code
# @param body [String] Response body
# @param headers [Hash] Response headers
def initialize(status, body, headers={})
@status, @body, @headers = status, body, headers
@body = body.force_encoding('UTF-8') if body.respond_to?(:force_encoding)
end
end
end
end
end
前提
- Ruby 2.6.1
- AWS Elasticsearch Service Engine version 7.1
- elasticsearch-ruby 7.3
- faraday 0.16.2
なぜ凍結されているか
すいません、調査していません。ググっても情報が出てこないので、この組み合わせだと発生するのかなーと。
対処内容
Faraday の Middleware を実装して対処しました。
require "faraday"
# Elasticsearch::Transport::Transport::Response で body.force_encoding の際に
# FrozenError が発生するため、body を解凍するミドルウェアをかませる。
module Faraday
class Response
class Unfreeze < Middleware
def parse(body)
+body # 解凍
end
end
register_middleware unfreeze: Unfreeze
end
end
上記ミドルウェアを Elasticsearch::Client
の初期化時に追加。
ES = Elasticsearch::Client.new(url: url) do |faraday|
faraday.request(:aws_sigv4,
service: 'es',
region: aws_region,
credentials_provider: credentials_provider)
faraday.response :unfreeze # <= ここに追加
faraday.adapter Faraday.default_adapter
end
これで上手くいきました。