Line data Source code
1 : #pragma once 2 : 3 : #include <memory> 4 : 5 : #include "source/extensions/common/async_files/async_file_action.h" 6 : #include "source/extensions/common/async_files/async_file_handle.h" 7 : 8 : #include "absl/status/statusor.h" 9 : #include "absl/strings/string_view.h" 10 : #include "absl/types/optional.h" 11 : 12 : namespace Envoy { 13 : namespace Extensions { 14 : namespace Common { 15 : namespace AsyncFiles { 16 : 17 : // An AsyncFileManager should be a singleton or singleton-like. 18 : // Possible subclasses currently are: 19 : // * AsyncFileManagerThreadPool 20 : class AsyncFileManager { 21 : public: 22 2 : virtual ~AsyncFileManager() = default; 23 : 24 : // Action to create and open a temporary file. 25 : // 26 : // The path parameter is a path to a directory in which the anonymous file will be 27 : // created (commonly "/tmp", for example). Even though an anonymous file is not linked and 28 : // has no filename, the path can be important as it determines which physical hardware the file 29 : // is written to (i.e. if you were to link() the file later, linking it to a path on a different 30 : // device is an expensive operation; or you might prefer to write temporary files to a virtual 31 : // filesystem or to a mounted disposable SSD.) 32 : // on_complete receives an AsyncFileHandle on success, or an error on failure. 33 : // 34 : // Returns a cancellation function, which aborts the operation (and closes 35 : // the file if opened) unless the callback has already been called. 36 : virtual CancelFunction 37 : createAnonymousFile(absl::string_view path, 38 : std::function<void(absl::StatusOr<AsyncFileHandle>)> on_complete) PURE; 39 : 40 : // A mode for opening existing files. 41 : enum class Mode { ReadOnly, WriteOnly, ReadWrite }; 42 : 43 : // Action to asynchronously open a named file that already exists. 44 : // on_complete receives an AsyncFileHandle on success, or an error on failure. 45 : // 46 : // Returns a cancellation function, which aborts the operation (and closes 47 : // the file if opened) unless the callback has already been called. 48 : virtual CancelFunction 49 : openExistingFile(absl::string_view filename, Mode mode, 50 : std::function<void(absl::StatusOr<AsyncFileHandle>)> on_complete) PURE; 51 : 52 : // Action to stat a file. 53 : // on_complete receives a stat structure on success, or an error on failure. 54 : // 55 : // Returns a cancellation function, which aborts the operation 56 : // unless the callback has already been called. 57 : virtual CancelFunction stat(absl::string_view filename, 58 : std::function<void(absl::StatusOr<struct stat>)> on_complete) PURE; 59 : 60 : // Action to delete a named file. 61 : // on_complete receives OK on success, or an error on failure. 62 : // 63 : // Returns a cancellation function, which aborts the operation 64 : // unless it has already been performed. 65 : virtual CancelFunction unlink(absl::string_view filename, 66 : std::function<void(absl::Status)> on_complete) PURE; 67 : 68 : // whenReady can be used to only perform an action when the caller hits the 69 : // front of the thread pool's queue - this can be used to defer requesting 70 : // a file action until it could actually take place. For example, if you're 71 : // offloading data from memory to disk temporarily, if you queue the write 72 : // immediately then the filesystem thread owns the data until the write 73 : // completes, which may be blocked by heavy traffic, and it turns out you 74 : // want the data back before then - you can't get it back, you have to wait 75 : // for the write to complete and then read it back. 76 : // 77 : // If you used whenReady, you could keep the data belonging to the client 78 : // until it's actually the client's turn to do disk access. When whenReady's 79 : // callback is called, if you request the write at that time the performance 80 : // will be almost identical to if you had requested the write earlier, but 81 : // you have the opportunity to change your mind and do something different 82 : // in the meantime. 83 : // 84 : // The cost of using whenReady is that it requires the client to be lock 85 : // controlled (since the callback occurs in a different thread than the thread 86 : // the state belongs to), versus simpler unchained operations can use queue 87 : // based actions and not worry about ownership. 88 : CancelFunction whenReady(std::function<void(absl::Status)> on_complete); 89 : 90 : // Return a string description of the configuration of the manager. 91 : // (This is mostly to facilitate testing.) 92 : virtual std::string describe() const PURE; 93 : 94 : private: 95 : virtual CancelFunction enqueue(const std::shared_ptr<AsyncFileAction> context) PURE; 96 : 97 : friend class AsyncFileContextBase; 98 : friend class AsyncFileManagerTest; 99 : }; 100 : 101 : } // namespace AsyncFiles 102 : } // namespace Common 103 : } // namespace Extensions 104 : } // namespace Envoy