We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
The worker should wait all channels are ready.
If the worker has started to train and the grpc channels to connect PS are not ready, a connection error will be raised.

```
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
	status = StatusCode.UNAVAILABLE
	details = "failed to connect to all addresses"
	debug_error_string = "{"created":"@1574320322.398282300","description":"Failed to pick subchannel","file":"src/core/ext/filters/client_channel/client_channel.cc","file_line":3876,"referenced_errors":[{"created":"@1574320322.398280426","description":"failed to connect to all addresses","file":"src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc","file_line":395,"grpc_status":14}]}"
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `elasticdl/python/worker/main.py`
Content:
```
1 import time
2 
3 import grpc
4 from kubernetes import client, config
5 
6 from elasticdl.python.common import log_utils
7 from elasticdl.python.common.args import parse_worker_args
8 from elasticdl.python.common.constants import GRPC
9 from elasticdl.python.common.grpc_utils import build_channel
10 from elasticdl.python.worker.worker import Worker
11 
12 
13 def main():
14     args = parse_worker_args()
15     logger = log_utils.get_logger(__name__)
16     logger.info("Starting worker %d", args.worker_id)
17     if args.master_addr is None:
18         raise ValueError("master_addr is missing for worker")
19 
20     master_channel = build_channel(args.master_addr)
21 
22     ps_channels = []
23     if args.ps_addrs:
24         # TODO: use ps_addrs from master directly after ps service is working.
25         #       Get ps pod ip for ps grpc connection for now.
26         ps_addrs = args.ps_addrs.split(",")
27 
28         config.load_incluster_config()
29         api = client.CoreV1Api()
30 
31         for addr in ps_addrs:
32             # addr is in the form as "ps-pod-name.namespace.svc:port"
33             addr_splitted = addr.split(".")
34             while True:
35                 pod = api.read_namespaced_pod(
36                     namespace=addr_splitted[1], name=addr_splitted[0]
37                 )
38                 if pod.status.pod_ip:
39                     break
40                 # If ps pod is not ready yet, sleep 2 seconds and try again.
41                 time.sleep(2)
42             addr = pod.status.pod_ip + ":" + addr.split(":")[-1]
43             channel = grpc.insecure_channel(
44                 addr,
45                 options=[
46                     (
47                         "grpc.max_send_message_length",
48                         GRPC.MAX_SEND_MESSAGE_LENGTH,
49                     ),
50                     (
51                         "grpc.max_receive_message_length",
52                         GRPC.MAX_RECEIVE_MESSAGE_LENGTH,
53                     ),
54                 ],
55             )
56             ps_channels.append(channel)
57 
58     worker = Worker(args, channel=master_channel, ps_channels=ps_channels)
59     worker.run()
60 
61 
62 if __name__ == "__main__":
63     main()
64
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/elasticdl/python/worker/main.py b/elasticdl/python/worker/main.py
--- a/elasticdl/python/worker/main.py
+++ b/elasticdl/python/worker/main.py
@@ -53,6 +53,13 @@
                     ),
                 ],
             )
+
+            # Wait the channel is ready by a Future object.
+            grpc.channel_ready_future(channel).result()
+            logger.info(
+                "grpc channel %s to connect pod %s is ready"
+                % (addr, pod.metadata.name)
+            )
             ps_channels.append(channel)
 
     worker = Worker(args, channel=master_channel, ps_channels=ps_channels)

{"golden_diff": "diff --git a/elasticdl/python/worker/main.py b/elasticdl/python/worker/main.py\n--- a/elasticdl/python/worker/main.py\n+++ b/elasticdl/python/worker/main.py\n@@ -53,6 +53,13 @@\n                     ),\n                 ],\n             )\n+\n+            # Wait the channel is ready by a Future object.\n+            grpc.channel_ready_future(channel).result()\n+            logger.info(\n+                \"grpc channel %s to connect pod %s is ready\"\n+                % (addr, pod.metadata.name)\n+            )\n             ps_channels.append(channel)\n \n     worker = Worker(args, channel=master_channel, ps_channels=ps_channels)\n", "issue": "The worker should wait all channels are ready.\nIf the worker has started to train and the grpc channels to connect PS are not ready, a connection error will be raised.\r\n\r\n```\r\ngrpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:\r\n\tstatus = StatusCode.UNAVAILABLE\r\n\tdetails = \"failed to connect to all addresses\"\r\n\tdebug_error_string = \"{\"created\":\"@1574320322.398282300\",\"description\":\"Failed to pick subchannel\",\"file\":\"src/core/ext/filters/client_channel/client_channel.cc\",\"file_line\":3876,\"referenced_errors\":[{\"created\":\"@1574320322.398280426\",\"description\":\"failed to connect to all addresses\",\"file\":\"src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc\",\"file_line\":395,\"grpc_status\":14}]}\"\r\n```\n", "before_files": [{"content": "import time\n\nimport grpc\nfrom kubernetes import client, config\n\nfrom elasticdl.python.common import log_utils\nfrom elasticdl.python.common.args import parse_worker_args\nfrom elasticdl.python.common.constants import GRPC\nfrom elasticdl.python.common.grpc_utils import build_channel\nfrom elasticdl.python.worker.worker import Worker\n\n\ndef main():\n    args = parse_worker_args()\n    logger = log_utils.get_logger(__name__)\n    logger.info(\"Starting worker %d\", args.worker_id)\n    if args.master_addr is None:\n        raise ValueError(\"master_addr is missing for worker\")\n\n    master_channel = build_channel(args.master_addr)\n\n    ps_channels = []\n    if args.ps_addrs:\n        # TODO: use ps_addrs from master directly after ps service is working.\n        #       Get ps pod ip for ps grpc connection for now.\n        ps_addrs = args.ps_addrs.split(\",\")\n\n        config.load_incluster_config()\n        api = client.CoreV1Api()\n\n        for addr in ps_addrs:\n            # addr is in the form as \"ps-pod-name.namespace.svc:port\"\n            addr_splitted = addr.split(\".\")\n            while True:\n                pod = api.read_namespaced_pod(\n                    namespace=addr_splitted[1], name=addr_splitted[0]\n                )\n                if pod.status.pod_ip:\n                    break\n                # If ps pod is not ready yet, sleep 2 seconds and try again.\n                time.sleep(2)\n            addr = pod.status.pod_ip + \":\" + addr.split(\":\")[-1]\n            channel = grpc.insecure_channel(\n                addr,\n                options=[\n                    (\n                        \"grpc.max_send_message_length\",\n                        GRPC.MAX_SEND_MESSAGE_LENGTH,\n                    ),\n                    (\n                        \"grpc.max_receive_message_length\",\n                        GRPC.MAX_RECEIVE_MESSAGE_LENGTH,\n                    ),\n                ],\n            )\n            ps_channels.append(channel)\n\n    worker = Worker(args, channel=master_channel, ps_channels=ps_channels)\n    worker.run()\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "elasticdl/python/worker/main.py"}], "after_files": [{"content": "import time\n\nimport grpc\nfrom kubernetes import client, config\n\nfrom elasticdl.python.common import log_utils\nfrom elasticdl.python.common.args import parse_worker_args\nfrom elasticdl.python.common.constants import GRPC\nfrom elasticdl.python.common.grpc_utils import build_channel\nfrom elasticdl.python.worker.worker import Worker\n\n\ndef main():\n    args = parse_worker_args()\n    logger = log_utils.get_logger(__name__)\n    logger.info(\"Starting worker %d\", args.worker_id)\n    if args.master_addr is None:\n        raise ValueError(\"master_addr is missing for worker\")\n\n    master_channel = build_channel(args.master_addr)\n\n    ps_channels = []\n    if args.ps_addrs:\n        # TODO: use ps_addrs from master directly after ps service is working.\n        #       Get ps pod ip for ps grpc connection for now.\n        ps_addrs = args.ps_addrs.split(\",\")\n\n        config.load_incluster_config()\n        api = client.CoreV1Api()\n\n        for addr in ps_addrs:\n            # addr is in the form as \"ps-pod-name.namespace.svc:port\"\n            addr_splitted = addr.split(\".\")\n            while True:\n                pod = api.read_namespaced_pod(\n                    namespace=addr_splitted[1], name=addr_splitted[0]\n                )\n                if pod.status.pod_ip:\n                    break\n                # If ps pod is not ready yet, sleep 2 seconds and try again.\n                time.sleep(2)\n            addr = pod.status.pod_ip + \":\" + addr.split(\":\")[-1]\n            channel = grpc.insecure_channel(\n                addr,\n                options=[\n                    (\n                        \"grpc.max_send_message_length\",\n                        GRPC.MAX_SEND_MESSAGE_LENGTH,\n                    ),\n                    (\n                        \"grpc.max_receive_message_length\",\n                        GRPC.MAX_RECEIVE_MESSAGE_LENGTH,\n                    ),\n                ],\n            )\n\n            # Wait the channel is ready by a Future object.\n            grpc.channel_ready_future(channel).result()\n            logger.info(\n                \"grpc channel %s to connect pod %s is ready\"\n                % (addr, pod.metadata.name)\n            )\n            ps_channels.append(channel)\n\n    worker = Worker(args, channel=master_channel, ps_channels=ps_channels)\n    worker.run()\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "elasticdl/python/worker/main.py"}]}