Kemal кэширует ответы с помощью промежуточного программного обеспечения обработчика
Kemal кэширует ответы с помощью промежуточного программного обеспечения обработчика
Я пытаюсь сделать кэширование некоторого запроса GET с Kemal.
class CachingHandler < Kemal::Handler
property cache : Hash(String, IO::Memory)
def initialize
@cache = Hash(String, IO::Memory).new
end
def call(context)
puts "Caching"
puts "Key: #{ context.request.resource }"
if output = @cache[context.request.resource]?
puts "Cache: true"
IO.copy output, context.response.output
else
puts "Cache: false"
puts "Cache: building"
context.response.output =
@cache[context.request.resource] = IO::Memory.new
# continue
puts "Cache: continue"
call_next context
end
end
end
Но в первом запросе браузер всегда ждет ответа. А во втором запросе отправить ошибку "Закрытый поток (IO::Error)".
1 ответ
Вы косвенно устанавливаете context.response.output
в IO::Memory.new
, Таким образом, следующий обработчик будет записывать не в выходной поток соединения, а в память ввода-вывода.
Вам нужно будет скопировать данные потока в память и сокет. Может быть IO::MultiWriter
может помочь с этим, как response.output = IO::MultiWriter.new(response.output, memory_io)
,
Кроме того, я бы рекомендовал не хранить IO::Memory
случаи, а скорее их необработанные данные как Bytes
(io.to_slice
). После того, как вы поместите его в кеш, больше нет смысла в IO. Вы можете просто записать байты непосредственно в выходной поток при попадании в кеш (response.write(bytes
).