prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Flower hangs from version 5.4.0.
  **Describe the bug**: 
  Flower hangs (no answer from http connection to browser) when a version >= 5.4.0 is installed
  
  **To Reproduce**
  
  1. pip install elastic-apm==5.4.0
  2. restart flower and try to access
  
  **Environment (please complete the following information)**
  - OS: Ubuntu 18.04
  - Python version: 3.6
  - Framework and version: Django 2.2
  - APM Server version: NA
  - Agent version: 5.4.0+ 
  
  
  </issue>
  <code>
  [start of elasticapm/instrumentation/packages/tornado.py]
  1 #  BSD 3-Clause License
  2 #
  3 #  Copyright (c) 2019, Elasticsearch BV
  4 #  All rights reserved.
  5 #
  6 #  Redistribution and use in source and binary forms, with or without
  7 #  modification, are permitted provided that the following conditions are met:
  8 #
  9 #  * Redistributions of source code must retain the above copyright notice, this
  10 #    list of conditions and the following disclaimer.
  11 #
  12 #  * Redistributions in binary form must reproduce the above copyright notice,
  13 #    this list of conditions and the following disclaimer in the documentation
  14 #    and/or other materials provided with the distribution.
  15 #
  16 #  * Neither the name of the copyright holder nor the names of its
  17 #    contributors may be used to endorse or promote products derived from
  18 #    this software without specific prior written permission.
  19 #
  20 #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21 #  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22 #  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23 #  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  24 #  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25 #  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  26 #  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  27 #  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28 #  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29 #  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30 """
  31 Instrumentation for Tornado
  32 """
  33 import elasticapm
  34 from elasticapm.conf import constants
  35 from elasticapm.instrumentation.packages.asyncio.base import AbstractInstrumentedModule, AsyncAbstractInstrumentedModule
  36 from elasticapm.traces import capture_span
  37 from elasticapm.utils.disttracing import TraceParent
  38 
  39 
  40 class TornadoRequestExecuteInstrumentation(AsyncAbstractInstrumentedModule):
  41     name = "tornado_request_execute"
  42     creates_transactions = True
  43     instrument_list = [("tornado.web", "RequestHandler._execute")]
  44 
  45     async def call(self, module, method, wrapped, instance, args, kwargs):
  46         # Late import to avoid ImportErrors
  47         from elasticapm.contrib.tornado.utils import get_data_from_request, get_data_from_response
  48 
  49         request = instance.request
  50         trace_parent = TraceParent.from_headers(request.headers)
  51         client = instance.application.elasticapm_client
  52         client.begin_transaction("request", trace_parent=trace_parent)
  53         elasticapm.set_context(
  54             lambda: get_data_from_request(instance, request, client.config, constants.TRANSACTION), "request"
  55         )
  56         # TODO: Can we somehow incorporate the routing rule itself here?
  57         elasticapm.set_transaction_name("{} {}".format(request.method, type(instance).__name__), override=False)
  58 
  59         ret = await wrapped(*args, **kwargs)
  60 
  61         elasticapm.set_context(
  62             lambda: get_data_from_response(instance, client.config, constants.TRANSACTION), "response"
  63         )
  64         result = "HTTP {}xx".format(instance.get_status() // 100)
  65         elasticapm.set_transaction_result(result, override=False)
  66         client.end_transaction()
  67 
  68         return ret
  69 
  70 
  71 class TornadoHandleRequestExceptionInstrumentation(AbstractInstrumentedModule):
  72     name = "tornado_handle_request_exception"
  73 
  74     instrument_list = [("tornado.web", "RequestHandler._handle_request_exception")]
  75 
  76     def call(self, module, method, wrapped, instance, args, kwargs):
  77 
  78         # Late import to avoid ImportErrors
  79         from tornado.web import Finish, HTTPError
  80         from elasticapm.contrib.tornado.utils import get_data_from_request
  81 
  82         e = args[0]
  83         if isinstance(e, Finish):
  84             # Not an error; Finish is an exception that ends a request without an error response
  85             return wrapped(*args, **kwargs)
  86 
  87         client = instance.application.elasticapm_client
  88         request = instance.request
  89         client.capture_exception(
  90             context={"request": get_data_from_request(instance, request, client.config, constants.ERROR)}
  91         )
  92         if isinstance(e, HTTPError):
  93             elasticapm.set_transaction_result("HTTP {}xx".format(int(e.status_code / 100)), override=False)
  94             elasticapm.set_context({"status_code": e.status_code}, "response")
  95         else:
  96             elasticapm.set_transaction_result("HTTP 5xx", override=False)
  97             elasticapm.set_context({"status_code": 500}, "response")
  98 
  99         return wrapped(*args, **kwargs)
  100 
  101 
  102 class TornadoRenderInstrumentation(AbstractInstrumentedModule):
  103     name = "tornado_render"
  104 
  105     instrument_list = [("tornado.web", "RequestHandler.render")]
  106 
  107     def call(self, module, method, wrapped, instance, args, kwargs):
  108         if "template_name" in kwargs:
  109             name = kwargs["template_name"]
  110         else:
  111             name = args[0]
  112 
  113         with capture_span(name, span_type="template", span_subtype="tornado", span_action="render"):
  114             return wrapped(*args, **kwargs)
  115
  [end of elasticapm/instrumentation/packages/tornado.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/elasticapm/instrumentation/packages/tornado.py b/elasticapm/instrumentation/packages/tornado.py
  --- a/elasticapm/instrumentation/packages/tornado.py
  +++ b/elasticapm/instrumentation/packages/tornado.py
  @@ -43,6 +43,11 @@
       instrument_list = [("tornado.web", "RequestHandler._execute")]
   
       async def call(self, module, method, wrapped, instance, args, kwargs):
  +        if not hasattr(instance.application, "elasticapm_client"):
  +            # If tornado was instrumented but not as the main framework
  +            # (i.e. in Flower), we should skip it.
  +            return await wrapped(*args, **kwargs)
  +
           # Late import to avoid ImportErrors
           from elasticapm.contrib.tornado.utils import get_data_from_request, get_data_from_response
   
  @@ -74,6 +79,10 @@
       instrument_list = [("tornado.web", "RequestHandler._handle_request_exception")]
   
       def call(self, module, method, wrapped, instance, args, kwargs):
  +        if not hasattr(instance.application, "elasticapm_client"):
  +            # If tornado was instrumented but not as the main framework
  +            # (i.e. in Flower), we should skip it.
  +            return wrapped(*args, **kwargs)
   
           # Late import to avoid ImportErrors
           from tornado.web import Finish, HTTPError
  
verification_info: {"golden_diff": "diff --git a/elasticapm/instrumentation/packages/tornado.py b/elasticapm/instrumentation/packages/tornado.py\n--- a/elasticapm/instrumentation/packages/tornado.py\n+++ b/elasticapm/instrumentation/packages/tornado.py\n@@ -43,6 +43,11 @@\n     instrument_list = [(\"tornado.web\", \"RequestHandler._execute\")]\n \n     async def call(self, module, method, wrapped, instance, args, kwargs):\n+        if not hasattr(instance.application, \"elasticapm_client\"):\n+            # If tornado was instrumented but not as the main framework\n+            # (i.e. in Flower), we should skip it.\n+            return await wrapped(*args, **kwargs)\n+\n         # Late import to avoid ImportErrors\n         from elasticapm.contrib.tornado.utils import get_data_from_request, get_data_from_response\n \n@@ -74,6 +79,10 @@\n     instrument_list = [(\"tornado.web\", \"RequestHandler._handle_request_exception\")]\n \n     def call(self, module, method, wrapped, instance, args, kwargs):\n+        if not hasattr(instance.application, \"elasticapm_client\"):\n+            # If tornado was instrumented but not as the main framework\n+            # (i.e. in Flower), we should skip it.\n+            return wrapped(*args, **kwargs)\n \n         # Late import to avoid ImportErrors\n         from tornado.web import Finish, HTTPError\n", "issue": "Flower hangs from version 5.4.0.\n**Describe the bug**: \r\nFlower hangs (no answer from http connection to browser) when a version >= 5.4.0 is installed\r\n\r\n**To Reproduce**\r\n\r\n1. pip install elastic-apm==5.4.0\r\n2. restart flower and try to access\r\n\r\n**Environment (please complete the following information)**\r\n- OS: Ubuntu 18.04\r\n- Python version: 3.6\r\n- Framework and version: Django 2.2\r\n- APM Server version: NA\r\n- Agent version: 5.4.0+ \r\n\n", "before_files": [{"content": "#  BSD 3-Clause License\n#\n#  Copyright (c) 2019, Elasticsearch BV\n#  All rights reserved.\n#\n#  Redistribution and use in source and binary forms, with or without\n#  modification, are permitted provided that the following conditions are met:\n#\n#  * Redistributions of source code must retain the above copyright notice, this\n#    list of conditions and the following disclaimer.\n#\n#  * Redistributions in binary form must reproduce the above copyright notice,\n#    this list of conditions and the following disclaimer in the documentation\n#    and/or other materials provided with the distribution.\n#\n#  * Neither the name of the copyright holder nor the names of its\n#    contributors may be used to endorse or promote products derived from\n#    this software without specific prior written permission.\n#\n#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n#  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n#  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n#  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n#  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n#  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n#  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n#  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\"\"\"\nInstrumentation for Tornado\n\"\"\"\nimport elasticapm\nfrom elasticapm.conf import constants\nfrom elasticapm.instrumentation.packages.asyncio.base import AbstractInstrumentedModule, AsyncAbstractInstrumentedModule\nfrom elasticapm.traces import capture_span\nfrom elasticapm.utils.disttracing import TraceParent\n\n\nclass TornadoRequestExecuteInstrumentation(AsyncAbstractInstrumentedModule):\n    name = \"tornado_request_execute\"\n    creates_transactions = True\n    instrument_list = [(\"tornado.web\", \"RequestHandler._execute\")]\n\n    async def call(self, module, method, wrapped, instance, args, kwargs):\n        # Late import to avoid ImportErrors\n        from elasticapm.contrib.tornado.utils import get_data_from_request, get_data_from_response\n\n        request = instance.request\n        trace_parent = TraceParent.from_headers(request.headers)\n        client = instance.application.elasticapm_client\n        client.begin_transaction(\"request\", trace_parent=trace_parent)\n        elasticapm.set_context(\n            lambda: get_data_from_request(instance, request, client.config, constants.TRANSACTION), \"request\"\n        )\n        # TODO: Can we somehow incorporate the routing rule itself here?\n        elasticapm.set_transaction_name(\"{} {}\".format(request.method, type(instance).__name__), override=False)\n\n        ret = await wrapped(*args, **kwargs)\n\n        elasticapm.set_context(\n            lambda: get_data_from_response(instance, client.config, constants.TRANSACTION), \"response\"\n        )\n        result = \"HTTP {}xx\".format(instance.get_status() // 100)\n        elasticapm.set_transaction_result(result, override=False)\n        client.end_transaction()\n\n        return ret\n\n\nclass TornadoHandleRequestExceptionInstrumentation(AbstractInstrumentedModule):\n    name = \"tornado_handle_request_exception\"\n\n    instrument_list = [(\"tornado.web\", \"RequestHandler._handle_request_exception\")]\n\n    def call(self, module, method, wrapped, instance, args, kwargs):\n\n        # Late import to avoid ImportErrors\n        from tornado.web import Finish, HTTPError\n        from elasticapm.contrib.tornado.utils import get_data_from_request\n\n        e = args[0]\n        if isinstance(e, Finish):\n            # Not an error; Finish is an exception that ends a request without an error response\n            return wrapped(*args, **kwargs)\n\n        client = instance.application.elasticapm_client\n        request = instance.request\n        client.capture_exception(\n            context={\"request\": get_data_from_request(instance, request, client.config, constants.ERROR)}\n        )\n        if isinstance(e, HTTPError):\n            elasticapm.set_transaction_result(\"HTTP {}xx\".format(int(e.status_code / 100)), override=False)\n            elasticapm.set_context({\"status_code\": e.status_code}, \"response\")\n        else:\n            elasticapm.set_transaction_result(\"HTTP 5xx\", override=False)\n            elasticapm.set_context({\"status_code\": 500}, \"response\")\n\n        return wrapped(*args, **kwargs)\n\n\nclass TornadoRenderInstrumentation(AbstractInstrumentedModule):\n    name = \"tornado_render\"\n\n    instrument_list = [(\"tornado.web\", \"RequestHandler.render\")]\n\n    def call(self, module, method, wrapped, instance, args, kwargs):\n        if \"template_name\" in kwargs:\n            name = kwargs[\"template_name\"]\n        else:\n            name = args[0]\n\n        with capture_span(name, span_type=\"template\", span_subtype=\"tornado\", span_action=\"render\"):\n            return wrapped(*args, **kwargs)\n", "path": "elasticapm/instrumentation/packages/tornado.py"}]}