prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <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}]}"
  ```
  
  </issue>
  <code>
  [start of elasticdl/python/worker/main.py]
  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 of elasticdl/python/worker/main.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: 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)
  
verification_info: {"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"}]}