Skip to content

filesystem: provide kqueue-based impl of Watcher#1363

Merged
mattklein123 merged 6 commits intoenvoyproxy:masterfrom
turbinelabs:osx-1-kqueue-watcher
Aug 2, 2017
Merged

filesystem: provide kqueue-based impl of Watcher#1363
mattklein123 merged 6 commits intoenvoyproxy:masterfrom
turbinelabs:osx-1-kqueue-watcher

Conversation

@zuercher
Copy link
Copy Markdown
Member

@zuercher zuercher commented Aug 1, 2017

(Split out of #1348, part of fixes for #128).

This implementation watches the given file, if it exists. Otherwise it watches the directory for writes and then checks to see if the directory modification caused the file to appear.

Copy link
Copy Markdown
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much for splitting this out. Few small comments. Generally LGTM.

linkstatic = 1,
linkstamp = linkstamp,
)
strip_include_prefix = strip_include_prefix,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: indent

reinterpret_cast<void*>(watch_fd));

if (kevent(queue_, &event, 1, NULL, 0, NULL) == -1) {
throw EnvoyException(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

watch->fd_ will leak here when you throw and in other cases. Can you add close() to the destructor of FileWatch, then you can make overall destruction simpler.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


WatcherImpl::FileWatchPtr WatcherImpl::addWatch_(const std::string& path, uint32_t events,
Watcher::OnChangedCb cb, bool pathMustExist) {
bool watchingDir = false;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: all variables should be snake_case (there are other examples).

flags = NOTE_DELETE | NOTE_WRITE;
}

struct kevent event;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: struct not needed in C++ code.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function kevent hides the struct, so I think it's necessary here.

void onKqueueEvent();
FileWatchPtr addWatch_(const std::string& path, uint32_t events, Watcher::OnChangedCb cb,
bool pathMustExist);
void removeWatch_(FileWatchPtr& watch);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: removeWatch_ doesn't really need the trailing _.

fmt::format("unable to add filesystem watch for file {}: {}", path, strerror(event.data)));
}

log_debug("added watch for file: '{}' fd: {}", path, watch_fd);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please switch all of these to ENVOY_LOG macros.

Copy link
Copy Markdown
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the test coverage results like on the kqueue implementation?

@zuercher
Copy link
Copy Markdown
Member Author

zuercher commented Aug 1, 2017

Coverage is about 85%. Everything but the error guards.

Copy link
Copy Markdown
Contributor

@alyssawilk alyssawilk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall, and very useful comments, thanks!


#include "common/common/assert.h"
#include "common/common/thread.h"
#include "common/filesystem/filesystem_impl.h"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Google include order has a special case for foo.cc including foo.h as the first line, so I think you can revert most of the include order changes.

I think the fix_format script will catch this for you, so it's worth running it locally and seeing what else it turns up!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could swear the fix script did this for me. Weird.


while (true) {
uint32_t events = 0;
int nevents = kevent(queue_, NULL, 0, &event, 1, &nullts);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NULL -> nullptr here?


void WatcherImpl::removeWatch(FileWatchPtr& watch) {
int fd = watch->fd_;
watches_.erase(fd);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was surprised that one didn't have to unregister but kevent docs note "Events which are attached to file descriptors are automatically deleted on the last close of the descriptor."

Can you add a comment here that the deletion will close the fd and result in automatic unregistration?

int watch_fd = reinterpret_cast<std::intptr_t>(event.udata);

FileWatchPtr file = watches_[watch_fd];
if (file == nullptr) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm all for this paranoia check but when can this happen? Should it be an ASSERT that it does not?

removeWatch(file);
file = new_file;

events |= Events::MovedTo;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't the events in this case the events for the directory? Do we want to |= or overwrite entirely?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

events is only ever 0 or Events::MovedTo (which is the only value defined in include/envoy/filesystem/filesystem.h). The inotify implementation does this as well. I assumed it was because someone expected to add more event types some day.

file->callback_(events);
}

ENVOY_LOG(debug, "notification: fd: {} flags: {:x} file: {}", file->fd_, event.fflags,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the callback may trigger a bunch of logs on its own, you may want to bump this log line up before so you get the log about the event on the file before all the things triggered by that event.

Copy link
Copy Markdown
Contributor

@alyssawilk alyssawilk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good - just two more nits on my end

typedef std::shared_ptr<FileWatch> FileWatchPtr;

void onKqueueEvent();
FileWatchPtr addWatch_(const std::string& path, uint32_t events, Watcher::OnChangedCb cb,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this needs the trailing _ either

int rc = symlink(TestEnvironment::temporaryPath("envoy_test/watcher_target").c_str(),
TestEnvironment::temporaryPath("envoy_test/watcher_new_link").c_str());
RELEASE_ASSERT(0 == rc);
UNREFERENCED_PARAMETER(rc);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice additions!

I wonder if the tests you're modeling predated gtest? I think you can replace these two lines with
ASSERT_EQ(0, rc); here and below and it'll be more consistent with tests elsewhere in the code base

if (file->watching_dir_) {
if (event.fflags & NOTE_DELETE) {
// directory was deleted
removeWatch(file);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does one of the tests cover this case?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Latest commit adds a test that hits this line.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent, thanks!


#include "common/common/assert.h"
#include "common/common/utility.h"
#include "common/filesystem/watcher_impl.h"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I missed this on the last pass but I think this include change still needs to be reverted

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing the new inotify prefix breaks the header format script (since this passed tests). I think it's probably not worth worrying about but we can potentially make a note to try to make the script deal with this somehow (by having it understand the strip stuff).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it works for you, it works for me :-)

if (file->watching_dir_) {
if (event.fflags & NOTE_DELETE) {
// directory was deleted
removeWatch(file);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent, thanks!

Copy link
Copy Markdown
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @zuercher this looks great! Thanks for adding new tests also and fixing missing coverage. This works for me. Will hold off on merging in case @alyssawilk has any further comments/thoughts on the header order issue.

@alyssawilk
Copy link
Copy Markdown
Contributor

LGTM on my front!

@mattklein123 mattklein123 merged commit 374c3bf into envoyproxy:master Aug 2, 2017
@zuercher zuercher deleted the osx-1-kqueue-watcher branch August 10, 2017 16:05
rshriram pushed a commit to rshriram/envoy that referenced this pull request Oct 30, 2018
…oxy#1364)

Automatic merge from submit-queue.

Remove JWT headers consumed by Istio authn and mixer filters

**What this PR does / why we need it**: This PR removes the JWT headers after they have been consumed by Istio authn and mixer filters.

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes envoyproxy#1363 

**Special notes for your reviewer**:

**Release note**:

```release-note
```
jpsim pushed a commit that referenced this pull request Nov 28, 2022
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: JP Simard <jp@jpsim.com>
jpsim pushed a commit that referenced this pull request Nov 29, 2022
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: JP Simard <jp@jpsim.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants