-
Notifications
You must be signed in to change notification settings - Fork 5.5k
filesystem: move file object with stats, threading + flushing to AccessLogFile; add generic File object #5772
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
df39c67
62f8086
6ba486c
1f291bf
43e5665
3614b45
f50508a
779da9c
1b22c96
ac7d4c1
a2c8c4f
443a17a
8f48f6c
5db0857
7e219e7
05862aa
1b62da4
4b8fbb3
91c161c
f8e155d
685a541
85458c4
b973d12
7db72ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,58 +14,61 @@ namespace Envoy { | |
| namespace Filesystem { | ||
|
|
||
| /** | ||
| * Abstraction for a file on disk. | ||
| * Abstraction for a basic file on disk. | ||
| */ | ||
| class File { | ||
| class RawFile { | ||
| public: | ||
| virtual ~File() {} | ||
| virtual ~RawFile() {} | ||
|
|
||
| /** | ||
| * Write data to the file. | ||
| * Open the file with O_RDWR | O_APPEND | O_CREAT | ||
| * The file will be closed when this object is destructed | ||
| * | ||
| * @return bool whether the open succeeded | ||
| */ | ||
| virtual void write(absl::string_view) PURE; | ||
| virtual Api::SysCallBoolResult open() PURE; | ||
|
|
||
| /** | ||
| * Reopen the file. | ||
| * Write the buffer to the file. The file must be explicitly opened before writing. | ||
| * | ||
| * @return ssize_t number of bytes written, or -1 for failure | ||
| */ | ||
| virtual void reopen() PURE; | ||
| virtual Api::SysCallSizeResult write(absl::string_view buffer) PURE; | ||
|
|
||
| /** | ||
| * Synchronously flush all pending data to disk. | ||
| * Close the file. | ||
| * | ||
| * @return bool whether the close succeeded | ||
| */ | ||
| virtual void flush() PURE; | ||
| }; | ||
| virtual Api::SysCallBoolResult close() PURE; | ||
|
|
||
| typedef std::shared_ptr<File> FileSharedPtr; | ||
| /** | ||
| * @return bool is the file open | ||
| */ | ||
| virtual bool isOpen() PURE; | ||
|
|
||
| /** | ||
| * Captures state, properties, and stats of a file-system. | ||
| */ | ||
| class Instance { | ||
| public: | ||
| virtual ~Instance() {} | ||
| /** | ||
| * @return string the file path | ||
| */ | ||
| virtual std::string path() PURE; | ||
|
|
||
| /** | ||
| * Creates a file, overriding the flush-interval set in the class. | ||
| * | ||
| * @param path The path of the file to open. | ||
| * @param dispatcher The dispatcher used for set up timers to run flush(). | ||
| * @param lock The lock. | ||
| * @param file_flush_interval_msec Number of milliseconds to delay before flushing. | ||
| * @return string a human-readable string describing the error code | ||
| */ | ||
| virtual FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, | ||
| Thread::BasicLockable& lock, | ||
| std::chrono::milliseconds file_flush_interval_msec) PURE; | ||
| virtual std::string errorToString(int error) PURE; | ||
| }; | ||
|
|
||
| typedef std::unique_ptr<RawFile> RawFilePtr; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. prefer |
||
|
|
||
| class RawInstance { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems a little strange to me that we have a "raw" filesystem instance and then a "normal" filesystem instance. Why not just have a single filesystem that can create either "raw" or "regular" files? (Final names TBD).
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The issue is that creating the "regular" file requires a Dispatcher, a lock, stats, and threading. In the final version of this (with Windows support), we want to be able to inject the platform specific filesystem code from here: https://github.com/envoyproxy/envoy/blob/f9107b26ccca409a13716b7b094bd87fec9765fb/source/exe/win32/platform_impl.h, similarly to how we inject the platform specific threading code. To get around this, the "raw" filesystem instance doesn't know how to create "regular" files -- it is injected to the "normal" instance that does. If this too strange, then maybe just the Api object will be able to create "regular" files (since they are not platform specific). This would end up reverting a bit of #5692, which wouldn't be a problem, except for the small bit of churn
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See my comment above. Should we just have "regular" files be part of the access log manager interface since this is the interface the reopens them, etc.? |
||
| public: | ||
| virtual ~RawInstance() {} | ||
|
|
||
| /** | ||
| * Creates a file, using the default flush-interval for the class. | ||
| * | ||
| * @param path The path of the file to open. | ||
| * @param dispatcher The dispatcher used for set up timers to run flush(). | ||
| * @param lock The lock. | ||
| * @param path The path of the RawFile | ||
| * @return a RawFilePtr. The file is not opened. | ||
| */ | ||
| virtual FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, | ||
| Thread::BasicLockable& lock) PURE; | ||
| virtual RawFilePtr createRawFile(const std::string& path) PURE; | ||
|
|
||
| /** | ||
| * @return bool whether a file exists on disk and can be opened for read. | ||
|
|
@@ -109,6 +112,61 @@ class Instance { | |
| virtual bool illegalPath(const std::string& path) PURE; | ||
| }; | ||
|
|
||
| /** | ||
| * Abstraction for a file on disk. It is specifically designed for writing access logs. | ||
| */ | ||
| class File { | ||
| public: | ||
| virtual ~File() {} | ||
|
|
||
| /** | ||
| * Write data to the file. | ||
| */ | ||
| virtual void write(absl::string_view) PURE; | ||
|
|
||
| /** | ||
| * Reopen the file. | ||
| */ | ||
| virtual void reopen() PURE; | ||
|
|
||
| /** | ||
| * Synchronously flush all pending data to disk. | ||
| */ | ||
| virtual void flush() PURE; | ||
| }; | ||
|
|
||
| typedef std::shared_ptr<File> FileSharedPtr; | ||
|
|
||
| /** | ||
| * Captures state, properties, and stats of a file-system. | ||
| */ | ||
| class Instance : public RawInstance { | ||
| public: | ||
| virtual ~Instance() {} | ||
|
|
||
| /** | ||
| * Creates a file, overriding the flush-interval set in the class. | ||
| * | ||
| * @param path The path of the file to open. | ||
| * @param dispatcher The dispatcher used for set up timers to run flush(). | ||
| * @param lock The lock. | ||
| * @param file_flush_interval_msec Number of milliseconds to delay before flushing. | ||
| */ | ||
| virtual FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, | ||
| Thread::BasicLockable& lock, | ||
| std::chrono::milliseconds file_flush_interval_msec) PURE; | ||
|
|
||
| /** | ||
| * Creates a file, using the default flush-interval for the class. | ||
| * | ||
| * @param path The path of the file to open. | ||
| * @param dispatcher The dispatcher used for set up timers to run flush(). | ||
| * @param lock The lock. | ||
| */ | ||
| virtual FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, | ||
| Thread::BasicLockable& lock) PURE; | ||
| }; | ||
|
|
||
| typedef std::unique_ptr<Watcher> WatcherPtr; | ||
|
|
||
| enum class FileType { Regular, Directory, Other }; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From an interface perspective, I'm not really sure what the difference is between a "raw" file and a "file." Can you at minimum add more comments and maybe think of a more descriptive name for
Filebelow?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for more comments. From my perspective a RawFile is an OS abstraction, and a File (maybe a better name would be good) adds Envoy semantics like stats and auto-flush.
RawFile needs to be re-implemented for different physical file layers, but the stats & auto-flush functionality can be shared across multiple RawFile impls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can tell, the only use of the
Fileclass is by the AccessLogManager, so maybeAccessLogFileor something like that might be better?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we leave it here I would probably do something like
ThreadSafeFileorThreadSafeAutoFlushFileor something. One other option is to actually completely move this file type and its creation into the access log manager interface, and then the filesystem interface just knows how to make "raw" or basic files, and then we can just call itFile. WDYT?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think moving it into the access log manager interface makes sense -- we'll give it a look