{"action":"created","comment":{"url":"https://api.github.com/repos/istio/istio/pulls/comments/226115586","pull_request_review_id":165856565,"id":226115586,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyNjExNTU4Ng==","diff_hunk":"@@ -0,0 +1,179 @@\n+// Copyright 2018 Istio Authors\n+//\n+// Licensed under the Apache License, Version 2.0 (the \"License\");\n+// you may not use this file except in compliance with the License.\n+// You may obtain a copy of the License at\n+//\n+//     http://www.apache.org/licenses/LICENSE-2.0\n+//\n+// Unless required by applicable law or agreed to in writing, software\n+// distributed under the License is distributed on an \"AS IS\" BASIS,\n+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+// See the License for the specific language governing permissions and\n+// limitations under the License.\n+\n+package filewatcher\n+\n+import (\n+\t\"fmt\"\n+\t\"path/filepath\"\n+\t\"sync\"\n+\n+\t\"github.com/fsnotify/fsnotify\"\n+\t\"github.com/hashicorp/go-multierror\"\n+)\n+\n+type FileWatcher interface {\n+\tAdd(path string) error\n+\tRemove(path string) error\n+\tClose() error\n+\tEvents(path string) chan fsnotify.Event\n+\tErrors(path string) chan error\n+}\n+\n+type fsNotifyWatcher struct {\n+\tmu sync.RWMutex\n+\t// The watcher maintain a map of fsnotify watchers,\n+\t// keyed by path.\n+\twatchers map[string]*fsnotify.Watcher\n+\t// The watcher maintain a map of event channel,\n+\t// keyed by path.\n+\t// The watcher watches parent path of given path,\n+\t// and filter out events of given path, then redirect\n+\t// to the result channel.\n+\t// Note that for symlink files, the content in received events\n+\t// do not have to be related to the file itself.\n+\tevents map[string]chan fsnotify.Event\n+}\n+\n+// NewWatcher return with a FileWatcher instance that implemented with fsnotify.\n+func NewWatcher() FileWatcher {\n+\tw := &fsNotifyWatcher{\n+\t\twatchers: map[string]*fsnotify.Watcher{},\n+\t\tevents:   map[string]chan fsnotify.Event{},\n+\t}\n+\n+\treturn w\n+}\n+\n+// Add is implementation of Add interface of FileWatcher.\n+func (w *fsNotifyWatcher) Add(path string) error {\n+\tw.mu.Lock()\n+\tdefer w.mu.Unlock()\n+\n+\tif _, exist := w.watchers[path]; exist {\n+\t\treturn fmt.Errorf(\"path %s already added\", path)\n+\t}\n+\n+\twatcher, err := fsnotify.NewWatcher()\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\n+\tevents := make(chan fsnotify.Event, 1)\n+\n+\tcleanedPath := filepath.Clean(path)\n+\tparentPath, _ := filepath.Split(cleanedPath)\n+\t// Ignore the error here as the file can be an \"usual\" file.\n+\trealPath, _ := filepath.EvalSymlinks(path)\n+\n+\twatcher.Add(parentPath)\n+\n+\tgo func() {","path":"pkg/filewatcher/filewatcher.go","position":82,"original_position":82,"commit_id":"02ab872465505a450d60739dce7c9e08ea554951","original_commit_id":"02ab872465505a450d60739dce7c9e08ea554951","user":{"login":"ozevren","id":17071139,"node_id":"MDQ6VXNlcjE3MDcxMTM5","avatar_url":"https://avatars0.githubusercontent.com/u/17071139?v=4","gravatar_id":"","url":"https://api.github.com/users/ozevren","html_url":"https://github.com/ozevren","followers_url":"https://api.github.com/users/ozevren/followers","following_url":"https://api.github.com/users/ozevren/following{/other_user}","gists_url":"https://api.github.com/users/ozevren/gists{/gist_id}","starred_url":"https://api.github.com/users/ozevren/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ozevren/subscriptions","organizations_url":"https://api.github.com/users/ozevren/orgs","repos_url":"https://api.github.com/users/ozevren/repos","events_url":"https://api.github.com/users/ozevren/events{/privacy}","received_events_url":"https://api.github.com/users/ozevren/received_events","type":"User","site_admin":false},"body":"Any chance we can get a single go routine, instead of one-per-file? I suspect, if we had a single watcher, then it should follow that there would be one go-routine.","created_at":"2018-10-17T22:28:47Z","updated_at":"2018-10-17T22:37:46Z","html_url":"https://github.com/istio/istio/pull/9370#discussion_r226115586","pull_request_url":"https://api.github.com/repos/istio/istio/pulls/9370","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/istio/istio/pulls/comments/226115586"},"html":{"href":"https://github.com/istio/istio/pull/9370#discussion_r226115586"},"pull_request":{"href":"https://api.github.com/repos/istio/istio/pulls/9370"}}},"pull_request":{"url":"https://api.github.com/repos/istio/istio/pulls/9370","id":223532930,"node_id":"MDExOlB1bGxSZXF1ZXN0MjIzNTMyOTMw","html_url":"https://github.com/istio/istio/pull/9370","diff_url":"https://github.com/istio/istio/pull/9370.diff","patch_url":"https://github.com/istio/istio/pull/9370.patch","issue_url":"https://api.github.com/repos/istio/istio/issues/9370","number":9370,"state":"open","locked":false,"title":"Add shared filewatcher mechanism","user":{"login":"lichuqiang","id":12265352,"node_id":"MDQ6VXNlcjEyMjY1MzUy","avatar_url":"https://avatars3.githubusercontent.com/u/12265352?v=4","gravatar_id":"","url":"https://api.github.com/users/lichuqiang","html_url":"https://github.com/lichuqiang","followers_url":"https://api.github.com/users/lichuqiang/followers","following_url":"https://api.github.com/users/lichuqiang/following{/other_user}","gists_url":"https://api.github.com/users/lichuqiang/gists{/gist_id}","starred_url":"https://api.github.com/users/lichuqiang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lichuqiang/subscriptions","organizations_url":"https://api.github.com/users/lichuqiang/orgs","repos_url":"https://api.github.com/users/lichuqiang/repos","events_url":"https://api.github.com/users/lichuqiang/events{/privacy}","received_events_url":"https://api.github.com/users/lichuqiang/received_events","type":"User","site_admin":false},"body":"Fix: #7877\r\n\r\nThe PR\r\n1. Provide shared filewatcher mechanism for usage\r\n2. handles symlinks properly for k8s secrets/configmaps.\r\n\r\nTODO: add a fake implementation for testing purposes.","created_at":"2018-10-17T09:38:15Z","updated_at":"2018-10-17T22:37:46Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c61941a78e9633ff94f44cd7c3e27f22d79e76e2","assignee":{"login":"ayj","id":116378,"node_id":"MDQ6VXNlcjExNjM3OA==","avatar_url":"https://avatars1.githubusercontent.com/u/116378?v=4","gravatar_id":"","url":"https://api.github.com/users/ayj","html_url":"https://github.com/ayj","followers_url":"https://api.github.com/users/ayj/followers","following_url":"https://api.github.com/users/ayj/following{/other_user}","gists_url":"https://api.github.com/users/ayj/gists{/gist_id}","starred_url":"https://api.github.com/users/ayj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ayj/subscriptions","organizations_url":"https://api.github.com/users/ayj/orgs","repos_url":"https://api.github.com/users/ayj/repos","events_url":"https://api.github.com/users/ayj/events{/privacy}","received_events_url":"https://api.github.com/users/ayj/received_events","type":"User","site_admin":false},"assignees":[{"login":"ayj","id":116378,"node_id":"MDQ6VXNlcjExNjM3OA==","avatar_url":"https://avatars1.githubusercontent.com/u/116378?v=4","gravatar_id":"","url":"https://api.github.com/users/ayj","html_url":"https://github.com/ayj","followers_url":"https://api.github.com/users/ayj/followers","following_url":"https://api.github.com/users/ayj/following{/other_user}","gists_url":"https://api.github.com/users/ayj/gists{/gist_id}","starred_url":"https://api.github.com/users/ayj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ayj/subscriptions","organizations_url":"https://api.github.com/users/ayj/orgs","repos_url":"https://api.github.com/users/ayj/repos","events_url":"https://api.github.com/users/ayj/events{/privacy}","received_events_url":"https://api.github.com/users/ayj/received_events","type":"User","site_admin":false},{"login":"ozevren","id":17071139,"node_id":"MDQ6VXNlcjE3MDcxMTM5","avatar_url":"https://avatars0.githubusercontent.com/u/17071139?v=4","gravatar_id":"","url":"https://api.github.com/users/ozevren","html_url":"https://github.com/ozevren","followers_url":"https://api.github.com/users/ozevren/followers","following_url":"https://api.github.com/users/ozevren/following{/other_user}","gists_url":"https://api.github.com/users/ozevren/gists{/gist_id}","starred_url":"https://api.github.com/users/ozevren/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ozevren/subscriptions","organizations_url":"https://api.github.com/users/ozevren/orgs","repos_url":"https://api.github.com/users/ozevren/repos","events_url":"https://api.github.com/users/ozevren/events{/privacy}","received_events_url":"https://api.github.com/users/ozevren/received_events","type":"User","site_admin":false}],"requested_reviewers":[{"login":"geeknoid","id":22780957,"node_id":"MDQ6VXNlcjIyNzgwOTU3","avatar_url":"https://avatars3.githubusercontent.com/u/22780957?v=4","gravatar_id":"","url":"https://api.github.com/users/geeknoid","html_url":"https://github.com/geeknoid","followers_url":"https://api.github.com/users/geeknoid/followers","following_url":"https://api.github.com/users/geeknoid/following{/other_user}","gists_url":"https://api.github.com/users/geeknoid/gists{/gist_id}","starred_url":"https://api.github.com/users/geeknoid/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/geeknoid/subscriptions","organizations_url":"https://api.github.com/users/geeknoid/orgs","repos_url":"https://api.github.com/users/geeknoid/repos","events_url":"https://api.github.com/users/geeknoid/events{/privacy}","received_events_url":"https://api.github.com/users/geeknoid/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":491318011,"node_id":"MDU6TGFiZWw0OTEzMTgwMTE=","url":"https://api.github.com/repos/istio/istio/labels/cla:%20yes","name":"cla: yes","color":"bfdadc","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/istio/istio/pulls/9370/commits","review_comments_url":"https://api.github.com/repos/istio/istio/pulls/9370/comments","review_comment_url":"https://api.github.com/repos/istio/istio/pulls/comments{/number}","comments_url":"https://api.github.com/repos/istio/istio/issues/9370/comments","statuses_url":"https://api.github.com/repos/istio/istio/statuses/02ab872465505a450d60739dce7c9e08ea554951","head":{"label":"lichuqiang:filewatcher","ref":"filewatcher","sha":"02ab872465505a450d60739dce7c9e08ea554951","user":{"login":"lichuqiang","id":12265352,"node_id":"MDQ6VXNlcjEyMjY1MzUy","avatar_url":"https://avatars3.githubusercontent.com/u/12265352?v=4","gravatar_id":"","url":"https://api.github.com/users/lichuqiang","html_url":"https://github.com/lichuqiang","followers_url":"https://api.github.com/users/lichuqiang/followers","following_url":"https://api.github.com/users/lichuqiang/following{/other_user}","gists_url":"https://api.github.com/users/lichuqiang/gists{/gist_id}","starred_url":"https://api.github.com/users/lichuqiang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lichuqiang/subscriptions","organizations_url":"https://api.github.com/users/lichuqiang/orgs","repos_url":"https://api.github.com/users/lichuqiang/repos","events_url":"https://api.github.com/users/lichuqiang/events{/privacy}","received_events_url":"https://api.github.com/users/lichuqiang/received_events","type":"User","site_admin":false},"repo":{"id":126926498,"node_id":"MDEwOlJlcG9zaXRvcnkxMjY5MjY0OTg=","name":"istio","full_name":"lichuqiang/istio","private":false,"owner":{"login":"lichuqiang","id":12265352,"node_id":"MDQ6VXNlcjEyMjY1MzUy","avatar_url":"https://avatars3.githubusercontent.com/u/12265352?v=4","gravatar_id":"","url":"https://api.github.com/users/lichuqiang","html_url":"https://github.com/lichuqiang","followers_url":"https://api.github.com/users/lichuqiang/followers","following_url":"https://api.github.com/users/lichuqiang/following{/other_user}","gists_url":"https://api.github.com/users/lichuqiang/gists{/gist_id}","starred_url":"https://api.github.com/users/lichuqiang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lichuqiang/subscriptions","organizations_url":"https://api.github.com/users/lichuqiang/orgs","repos_url":"https://api.github.com/users/lichuqiang/repos","events_url":"https://api.github.com/users/lichuqiang/events{/privacy}","received_events_url":"https://api.github.com/users/lichuqiang/received_events","type":"User","site_admin":false},"html_url":"https://github.com/lichuqiang/istio","description":"An open platform to connect, manage, and secure microservices.","fork":true,"url":"https://api.github.com/repos/lichuqiang/istio","forks_url":"https://api.github.com/repos/lichuqiang/istio/forks","keys_url":"https://api.github.com/repos/lichuqiang/istio/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lichuqiang/istio/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lichuqiang/istio/teams","hooks_url":"https://api.github.com/repos/lichuqiang/istio/hooks","issue_events_url":"https://api.github.com/repos/lichuqiang/istio/issues/events{/number}","events_url":"https://api.github.com/repos/lichuqiang/istio/events","assignees_url":"https://api.github.com/repos/lichuqiang/istio/assignees{/user}","branches_url":"https://api.github.com/repos/lichuqiang/istio/branches{/branch}","tags_url":"https://api.github.com/repos/lichuqiang/istio/tags","blobs_url":"https://api.github.com/repos/lichuqiang/istio/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lichuqiang/istio/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lichuqiang/istio/git/refs{/sha}","trees_url":"https://api.github.com/repos/lichuqiang/istio/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lichuqiang/istio/statuses/{sha}","languages_url":"https://api.github.com/repos/lichuqiang/istio/languages","stargazers_url":"https://api.github.com/repos/lichuqiang/istio/stargazers","contributors_url":"https://api.github.com/repos/lichuqiang/istio/contributors","subscribers_url":"https://api.github.com/repos/lichuqiang/istio/subscribers","subscription_url":"https://api.github.com/repos/lichuqiang/istio/subscription","commits_url":"https://api.github.com/repos/lichuqiang/istio/commits{/sha}","git_commits_url":"https://api.github.com/repos/lichuqiang/istio/git/commits{/sha}","comments_url":"https://api.github.com/repos/lichuqiang/istio/comments{/number}","issue_comment_url":"https://api.github.com/repos/lichuqiang/istio/issues/comments{/number}","contents_url":"https://api.github.com/repos/lichuqiang/istio/contents/{+path}","compare_url":"https://api.github.com/repos/lichuqiang/istio/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lichuqiang/istio/merges","archive_url":"https://api.github.com/repos/lichuqiang/istio/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lichuqiang/istio/downloads","issues_url":"https://api.github.com/repos/lichuqiang/istio/issues{/number}","pulls_url":"https://api.github.com/repos/lichuqiang/istio/pulls{/number}","milestones_url":"https://api.github.com/repos/lichuqiang/istio/milestones{/number}","notifications_url":"https://api.github.com/repos/lichuqiang/istio/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lichuqiang/istio/labels{/name}","releases_url":"https://api.github.com/repos/lichuqiang/istio/releases{/id}","deployments_url":"https://api.github.com/repos/lichuqiang/istio/deployments","created_at":"2018-03-27T03:58:29Z","updated_at":"2018-09-10T01:14:51Z","pushed_at":"2018-10-17T09:34:18Z","git_url":"git://github.com/lichuqiang/istio.git","ssh_url":"git@github.com:lichuqiang/istio.git","clone_url":"https://github.com/lichuqiang/istio.git","svn_url":"https://github.com/lichuqiang/istio","homepage":"https://istio.io","size":49821,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"istio:master","ref":"master","sha":"35d10b3720b01999d346a017c3a62e0d5a7c7722","user":{"login":"istio","id":23534644,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIzNTM0NjQ0","avatar_url":"https://avatars1.githubusercontent.com/u/23534644?v=4","gravatar_id":"","url":"https://api.github.com/users/istio","html_url":"https://github.com/istio","followers_url":"https://api.github.com/users/istio/followers","following_url":"https://api.github.com/users/istio/following{/other_user}","gists_url":"https://api.github.com/users/istio/gists{/gist_id}","starred_url":"https://api.github.com/users/istio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/istio/subscriptions","organizations_url":"https://api.github.com/users/istio/orgs","repos_url":"https://api.github.com/users/istio/repos","events_url":"https://api.github.com/users/istio/events{/privacy}","received_events_url":"https://api.github.com/users/istio/received_events","type":"Organization","site_admin":false},"repo":{"id":74175805,"node_id":"MDEwOlJlcG9zaXRvcnk3NDE3NTgwNQ==","name":"istio","full_name":"istio/istio","private":false,"owner":{"login":"istio","id":23534644,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIzNTM0NjQ0","avatar_url":"https://avatars1.githubusercontent.com/u/23534644?v=4","gravatar_id":"","url":"https://api.github.com/users/istio","html_url":"https://github.com/istio","followers_url":"https://api.github.com/users/istio/followers","following_url":"https://api.github.com/users/istio/following{/other_user}","gists_url":"https://api.github.com/users/istio/gists{/gist_id}","starred_url":"https://api.github.com/users/istio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/istio/subscriptions","organizations_url":"https://api.github.com/users/istio/orgs","repos_url":"https://api.github.com/users/istio/repos","events_url":"https://api.github.com/users/istio/events{/privacy}","received_events_url":"https://api.github.com/users/istio/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/istio/istio","description":"Connect, secure, control, and observe services.","fork":false,"url":"https://api.github.com/repos/istio/istio","forks_url":"https://api.github.com/repos/istio/istio/forks","keys_url":"https://api.github.com/repos/istio/istio/keys{/key_id}","collaborators_url":"https://api.github.com/repos/istio/istio/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/istio/istio/teams","hooks_url":"https://api.github.com/repos/istio/istio/hooks","issue_events_url":"https://api.github.com/repos/istio/istio/issues/events{/number}","events_url":"https://api.github.com/repos/istio/istio/events","assignees_url":"https://api.github.com/repos/istio/istio/assignees{/user}","branches_url":"https://api.github.com/repos/istio/istio/branches{/branch}","tags_url":"https://api.github.com/repos/istio/istio/tags","blobs_url":"https://api.github.com/repos/istio/istio/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/istio/istio/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/istio/istio/git/refs{/sha}","trees_url":"https://api.github.com/repos/istio/istio/git/trees{/sha}","statuses_url":"https://api.github.com/repos/istio/istio/statuses/{sha}","languages_url":"https://api.github.com/repos/istio/istio/languages","stargazers_url":"https://api.github.com/repos/istio/istio/stargazers","contributors_url":"https://api.github.com/repos/istio/istio/contributors","subscribers_url":"https://api.github.com/repos/istio/istio/subscribers","subscription_url":"https://api.github.com/repos/istio/istio/subscription","commits_url":"https://api.github.com/repos/istio/istio/commits{/sha}","git_commits_url":"https://api.github.com/repos/istio/istio/git/commits{/sha}","comments_url":"https://api.github.com/repos/istio/istio/comments{/number}","issue_comment_url":"https://api.github.com/repos/istio/istio/issues/comments{/number}","contents_url":"https://api.github.com/repos/istio/istio/contents/{+path}","compare_url":"https://api.github.com/repos/istio/istio/compare/{base}...{head}","merges_url":"https://api.github.com/repos/istio/istio/merges","archive_url":"https://api.github.com/repos/istio/istio/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/istio/istio/downloads","issues_url":"https://api.github.com/repos/istio/istio/issues{/number}","pulls_url":"https://api.github.com/repos/istio/istio/pulls{/number}","milestones_url":"https://api.github.com/repos/istio/istio/milestones{/number}","notifications_url":"https://api.github.com/repos/istio/istio/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/istio/istio/labels{/name}","releases_url":"https://api.github.com/repos/istio/istio/releases{/id}","deployments_url":"https://api.github.com/repos/istio/istio/deployments","created_at":"2016-11-18T23:57:21Z","updated_at":"2018-10-17T22:31:25Z","pushed_at":"2018-10-17T22:33:34Z","git_url":"git://github.com/istio/istio.git","ssh_url":"git@github.com:istio/istio.git","clone_url":"https://github.com/istio/istio.git","svn_url":"https://github.com/istio/istio","homepage":"https://istio.io","size":51144,"stargazers_count":12447,"watchers_count":12447,"language":"Go","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1838,"mirror_url":null,"archived":false,"open_issues_count":994,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":1838,"open_issues":994,"watchers":12447,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/istio/istio/pulls/9370"},"html":{"href":"https://github.com/istio/istio/pull/9370"},"issue":{"href":"https://api.github.com/repos/istio/istio/issues/9370"},"comments":{"href":"https://api.github.com/repos/istio/istio/issues/9370/comments"},"review_comments":{"href":"https://api.github.com/repos/istio/istio/pulls/9370/comments"},"review_comment":{"href":"https://api.github.com/repos/istio/istio/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/istio/istio/pulls/9370/commits"},"statuses":{"href":"https://api.github.com/repos/istio/istio/statuses/02ab872465505a450d60739dce7c9e08ea554951"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"ozevren"}}