{"action":"created","issue":{"url":"https://api.github.com/repos/grpc/grpc/issues/16025","repository_url":"https://api.github.com/repos/grpc/grpc","labels_url":"https://api.github.com/repos/grpc/grpc/issues/16025/labels{/name}","comments_url":"https://api.github.com/repos/grpc/grpc/issues/16025/comments","events_url":"https://api.github.com/repos/grpc/grpc/issues/16025/events","html_url":"https://github.com/grpc/grpc/pull/16025","id":341396200,"node_id":"MDExOlB1bGxSZXF1ZXN0MjAxNTQ0NzEx","number":16025,"title":"gRPC Python client-side fork support","user":{"login":"ericgribkoff","id":5067076,"node_id":"MDQ6VXNlcjUwNjcwNzY=","avatar_url":"https://avatars2.githubusercontent.com/u/5067076?v=4","gravatar_id":"","url":"https://api.github.com/users/ericgribkoff","html_url":"https://github.com/ericgribkoff","followers_url":"https://api.github.com/users/ericgribkoff/followers","following_url":"https://api.github.com/users/ericgribkoff/following{/other_user}","gists_url":"https://api.github.com/users/ericgribkoff/gists{/gist_id}","starred_url":"https://api.github.com/users/ericgribkoff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ericgribkoff/subscriptions","organizations_url":"https://api.github.com/users/ericgribkoff/orgs","repos_url":"https://api.github.com/users/ericgribkoff/repos","events_url":"https://api.github.com/users/ericgribkoff/events{/privacy}","received_events_url":"https://api.github.com/users/ericgribkoff/received_events","type":"User","site_admin":false},"labels":[{"id":155504842,"node_id":"MDU6TGFiZWwxNTU1MDQ4NDI=","url":"https://api.github.com/repos/grpc/grpc/labels/kind/bug","name":"kind/bug","color":"93732c","default":false},{"id":155504844,"node_id":"MDU6TGFiZWwxNTU1MDQ4NDQ=","url":"https://api.github.com/repos/grpc/grpc/labels/kind/enhancement","name":"kind/enhancement","color":"93732c","default":false},{"id":168238186,"node_id":"MDU6TGFiZWwxNjgyMzgxODY=","url":"https://api.github.com/repos/grpc/grpc/labels/lang/Python","name":"lang/Python","color":"fad8c7","default":false}],"state":"open","locked":false,"assignee":{"login":"kpayson64","id":18316330,"node_id":"MDQ6VXNlcjE4MzE2MzMw","avatar_url":"https://avatars2.githubusercontent.com/u/18316330?v=4","gravatar_id":"","url":"https://api.github.com/users/kpayson64","html_url":"https://github.com/kpayson64","followers_url":"https://api.github.com/users/kpayson64/followers","following_url":"https://api.github.com/users/kpayson64/following{/other_user}","gists_url":"https://api.github.com/users/kpayson64/gists{/gist_id}","starred_url":"https://api.github.com/users/kpayson64/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kpayson64/subscriptions","organizations_url":"https://api.github.com/users/kpayson64/orgs","repos_url":"https://api.github.com/users/kpayson64/repos","events_url":"https://api.github.com/users/kpayson64/events{/privacy}","received_events_url":"https://api.github.com/users/kpayson64/received_events","type":"User","site_admin":false},"assignees":[{"login":"kpayson64","id":18316330,"node_id":"MDQ6VXNlcjE4MzE2MzMw","avatar_url":"https://avatars2.githubusercontent.com/u/18316330?v=4","gravatar_id":"","url":"https://api.github.com/users/kpayson64","html_url":"https://github.com/kpayson64","followers_url":"https://api.github.com/users/kpayson64/followers","following_url":"https://api.github.com/users/kpayson64/following{/other_user}","gists_url":"https://api.github.com/users/kpayson64/gists{/gist_id}","starred_url":"https://api.github.com/users/kpayson64/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kpayson64/subscriptions","organizations_url":"https://api.github.com/users/kpayson64/orgs","repos_url":"https://api.github.com/users/kpayson64/repos","events_url":"https://api.github.com/users/kpayson64/events{/privacy}","received_events_url":"https://api.github.com/users/kpayson64/received_events","type":"User","site_admin":false}],"milestone":null,"comments":50,"created_at":"2018-07-16T05:44:36Z","updated_at":"2018-07-23T22:36:37Z","closed_at":null,"author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/grpc/grpc/pulls/16025","html_url":"https://github.com/grpc/grpc/pull/16025","diff_url":"https://github.com/grpc/grpc/pull/16025.diff","patch_url":"https://github.com/grpc/grpc/pull/16025.patch"},"body":"This PR allows gRPC Python clients to fork with active connections and in-progress RPCs. The three commits build upon each other but may be reviewed separately:\r\n\r\n1. Core changes to support fork. A global fork epoch (timestamp) allows forked processes to identify resources inherited from the parent process and avoid conflicting operations, e.g., socket shutdown. This currently supports the epoll1 polling engine, which is the default for the grpcio python distribution.\r\n2. Python changes: gRPC Python's internal threads are spawned for asynchronous calls, credentials, client-streaming request iterators, and connectivity monitoring. These are tracked, and paused in a Cython pre-fork handler to ensure the child process is in a consistent state after forking.\r\n3. Python fork test client containing end-to-end tests using fork() and gRPC. (Unit tests to follow soon)\r\n\r\nThe changes are hidden behind the existing fork compile flag for core and the runtime fork flag for Python to avoid performance impact on the standard (non-fork) use case.\r\n\r\nThe integration client must be run manually for now:\r\n\r\n```\r\n$ cd src/python/grpcio_tests\r\n$ GRPC_ENABLE_FORK_SUPPORT=1 GRPC_POLL_STRATEGY=epoll1 python setup.py run_fork \\ \r\n    --args=\"--server_host=localhost --server_port=8080 --test_case=all\"\r\n```\r\n\r\nA follow-up will integrate it with our CI to run it automatically, analogous to the Python interop client.\r\n\r\nThe corresponding design doc for these changes is available internally at go/grpc-fork-design.\r\n\r\nThis supersedes https://github.com/grpc/grpc/pull/15851\n\n<!-- Reviewable:start -->\n---\nThis change is [<img src=\"https://reviewable.io/review_button.svg\" height=\"34\" align=\"absmiddle\" alt=\"Reviewable\"/>](https://reviewable.io/reviews/grpc/grpc/16025)\n<!-- Reviewable:end -->\n"},"comment":{"url":"https://api.github.com/repos/grpc/grpc/issues/comments/407222974","html_url":"https://github.com/grpc/grpc/pull/16025#issuecomment-407222974","issue_url":"https://api.github.com/repos/grpc/grpc/issues/16025","id":407222974,"node_id":"MDEyOklzc3VlQ29tbWVudDQwNzIyMjk3NA==","user":{"login":"grpc-testing","id":28024233,"node_id":"MDQ6VXNlcjI4MDI0MjMz","avatar_url":"https://avatars1.githubusercontent.com/u/28024233?v=4","gravatar_id":"","url":"https://api.github.com/users/grpc-testing","html_url":"https://github.com/grpc-testing","followers_url":"https://api.github.com/users/grpc-testing/followers","following_url":"https://api.github.com/users/grpc-testing/following{/other_user}","gists_url":"https://api.github.com/users/grpc-testing/gists{/gist_id}","starred_url":"https://api.github.com/users/grpc-testing/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/grpc-testing/subscriptions","organizations_url":"https://api.github.com/users/grpc-testing/orgs","repos_url":"https://api.github.com/users/grpc-testing/repos","events_url":"https://api.github.com/users/grpc-testing/events{/privacy}","received_events_url":"https://api.github.com/users/grpc-testing/received_events","type":"User","site_admin":false},"created_at":"2018-07-23T22:36:37Z","updated_at":"2018-07-23T22:36:37Z","author_association":"NONE","body":"```\n[microbenchmarks] Performance differences noted:\nBenchmark                                                                              cpu_time    real_time\n-------------------------------------------------------------------------------------  ----------  -----------\nBM_StreamingPingPong<InProcess, NoOpMutator, NoOpMutator>/262144/1                     -5%         -5%\nBM_StreamingPingPongWithCoalescingApi<InProcess, NoOpMutator, NoOpMutator>/262144/1/1  -4%         -4%\n```"}}
{"actor":{"display_login":"grpc-testing"}}