1
#pragma once
2

            
3
#include <memory>
4

            
5
#include "source/extensions/common/async_files/async_file_manager.h"
6
#include "source/extensions/filters/http/cache_v2/http_cache.h"
7
#include "source/extensions/http/cache_v2/file_system_http_cache/cache_file_fixed_block.h"
8
#include "source/extensions/http/cache_v2/file_system_http_cache/cache_file_header.pb.h"
9

            
10
namespace Envoy {
11
namespace Extensions {
12
namespace HttpFilters {
13
namespace CacheV2 {
14
namespace FileSystemHttpCache {
15

            
16
struct CacheShared;
17

            
18
class FileInsertContext : public Logger::Loggable<Logger::Id::cache_filter> {
19
public:
20
  static void begin(Event::Dispatcher& dispatcher, Key key, std::string filepath,
21
                    Http::ResponseHeaderMapPtr headers, ResponseMetadata metadata,
22
                    HttpSourcePtr source, std::shared_ptr<CacheProgressReceiver> progress,
23
                    std::shared_ptr<CacheShared> stat_recorder,
24
                    Common::AsyncFiles::AsyncFileManager& async_file_manager);
25

            
26
private:
27
  FileInsertContext(Event::Dispatcher& dispatcher, Key key, std::string filepath,
28
                    Http::ResponseHeaderMapPtr headers, ResponseMetadata metadata,
29
                    HttpSourcePtr source, std::shared_ptr<CacheProgressReceiver> progress,
30
                    std::shared_ptr<CacheShared> stat_recorder);
31
  void fail(absl::Status status);
32
  void complete();
33

            
34
  // The sequence of actions involved in writing the cache entry to a file. Each
35
  // of these actions are posted to an async file thread, and the results posted back
36
  // to the dispatcher, so the callbacks are run on the original filter's thread.
37
  // Any failure calls CacheProgressReceiver::onInsertFailed.
38

            
39
  // The first step of writing the cache entry to a file. On success calls
40
  // dupFile.
41
  void createFile(Common::AsyncFiles::AsyncFileManager& file_manager);
42
  // Makes a duplicate file handle for the Reader.
43
  // On success calls writeEmptyHeaderBlock and CacheProgressReceiver::onHeadersInserted.
44
  void dupFile();
45
  // An empty header block is written at the start of the file, making room for
46
  // a populated header block to be written later. On success calls
47
  // either getBody or writeHeaders depending on if there is any body.
48
  void writeEmptyHeaderBlock();
49
  // Reads a chunk of body for insertion. Calls onBody on success. Calls getTrailers
50
  // if no body remained and there are trailers, or writeHeaders if no body remained
51
  // and there are no trailers.
52
  void getBody();
53
  // Writes a chunk of body to the file. Calls CacheProgressReceiver::onBodyInserted
54
  // and getBody, or writeHeaders if body ended and there are no trailers.
55
  void onBody(Buffer::InstancePtr buf, bool end_stream);
56
  // Reads trailers. Calls onTrailers on success.
57
  void getTrailers();
58
  // Writes the trailers to file. Calls CacheProcessReceiver::onTrailersInserted
59
  // and writeHeaders on success.
60
  void onTrailers(Http::ResponseTrailerMapPtr trailers);
61
  // Writes the headers to file. Calls commit on success.
62
  void writeHeaders();
63
  // Rewrites the header block of the file, and calls createHardLink.
64
  void commit();
65
  // Creates a hard link, and updates stats.
66
  void createHardLink();
67

            
68
  Event::Dispatcher& dispatcher_;
69
  std::string filepath_;
70
  CacheFileHeader cache_file_header_proto_;
71
  Http::ResponseHeaderMapPtr headers_;
72
  HttpSourcePtr source_;
73
  std::shared_ptr<CacheProgressReceiver> progress_receiver_;
74
  std::shared_ptr<CacheShared> stat_recorder_;
75
  CacheFileFixedBlock header_block_;
76
  Common::AsyncFiles::AsyncFileHandle file_handle_;
77
  off_t read_pos_{0};
78
};
79

            
80
} // namespace FileSystemHttpCache
81
} // namespace CacheV2
82
} // namespace HttpFilters
83
} // namespace Extensions
84
} // namespace Envoy