prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  2024.4.0 LongRunningTransaction
  **Describe the bug**
  Prometheus alert for a long running transaction.
  
  I think the transaction is
  
  ```
  SELECT pg_advisory_unlock($1)
  ```
  
  **To Reproduce**
  No activity, sitting idle
  
  **Expected behavior**
  Shouldn't have the alert
  
  **Screenshots**
  
  **Logs**
  
  **Version and Deployment (please complete the following information):**
  2024.4.0 kubernetes
  
  **Additional context**
  Add any other context about the problem here.
  
  
  </issue>
  <code>
  [start of lifecycle/migrate.py]
  1 #!/usr/bin/env python
  2 """System Migration handler"""
  3 from importlib.util import module_from_spec, spec_from_file_location
  4 from inspect import getmembers, isclass
  5 from os import environ, system
  6 from pathlib import Path
  7 from typing import Any
  8 
  9 from psycopg import Connection, Cursor, connect
  10 from structlog.stdlib import get_logger
  11 
  12 from authentik.lib.config import CONFIG
  13 
  14 LOGGER = get_logger()
  15 ADV_LOCK_UID = 1000
  16 LOCKED = False
  17 
  18 
  19 class CommandError(Exception):
  20     """Error raised when a system_crit command fails"""
  21 
  22 
  23 class BaseMigration:
  24     """Base System Migration"""
  25 
  26     cur: Cursor
  27     con: Connection
  28 
  29     def __init__(self, cur: Any, con: Any):
  30         self.cur = cur
  31         self.con = con
  32 
  33     def system_crit(self, command: str):
  34         """Run system command"""
  35         LOGGER.debug("Running system_crit command", command=command)
  36         retval = system(command)  # nosec
  37         if retval != 0:
  38             raise CommandError("Migration error")
  39 
  40     def fake_migration(self, *app_migration: tuple[str, str]):
  41         """Fake apply a list of migrations, arguments are
  42         expected to be tuples of (app_label, migration_name)"""
  43         for app, _migration in app_migration:
  44             self.system_crit(f"./manage.py migrate {app} {_migration} --fake")
  45 
  46     def needs_migration(self) -> bool:
  47         """Return true if Migration needs to be run"""
  48         return False
  49 
  50     def run(self):
  51         """Run the actual migration"""
  52 
  53 
  54 def wait_for_lock(cursor: Cursor):
  55     """lock an advisory lock to prevent multiple instances from migrating at once"""
  56     LOGGER.info("waiting to acquire database lock")
  57     cursor.execute("SELECT pg_advisory_lock(%s)", (ADV_LOCK_UID,))
  58 
  59     global LOCKED  # noqa: PLW0603
  60     LOCKED = True
  61 
  62 
  63 def release_lock(cursor: Cursor):
  64     """Release database lock"""
  65     if not LOCKED:
  66         return
  67     LOGGER.info("releasing database lock")
  68     cursor.execute("SELECT pg_advisory_unlock(%s)", (ADV_LOCK_UID,))
  69 
  70 
  71 def run_migrations():
  72     conn = connect(
  73         dbname=CONFIG.get("postgresql.name"),
  74         user=CONFIG.get("postgresql.user"),
  75         password=CONFIG.get("postgresql.password"),
  76         host=CONFIG.get("postgresql.host"),
  77         port=CONFIG.get_int("postgresql.port"),
  78         sslmode=CONFIG.get("postgresql.sslmode"),
  79         sslrootcert=CONFIG.get("postgresql.sslrootcert"),
  80         sslcert=CONFIG.get("postgresql.sslcert"),
  81         sslkey=CONFIG.get("postgresql.sslkey"),
  82     )
  83     curr = conn.cursor()
  84     try:
  85         for migration_path in Path(__file__).parent.absolute().glob("system_migrations/*.py"):
  86             spec = spec_from_file_location("lifecycle.system_migrations", migration_path)
  87             if not spec:
  88                 continue
  89             mod = module_from_spec(spec)
  90             spec.loader.exec_module(mod)
  91 
  92             for name, sub in getmembers(mod, isclass):
  93                 if name != "Migration":
  94                     continue
  95                 migration = sub(curr, conn)
  96                 if migration.needs_migration():
  97                     wait_for_lock(curr)
  98                     LOGGER.info("Migration needs to be applied", migration=migration_path.name)
  99                     migration.run()
  100                     LOGGER.info("Migration finished applying", migration=migration_path.name)
  101                     release_lock(curr)
  102         LOGGER.info("applying django migrations")
  103         environ.setdefault("DJANGO_SETTINGS_MODULE", "authentik.root.settings")
  104         wait_for_lock(curr)
  105         try:
  106             from django.core.management import execute_from_command_line
  107         except ImportError as exc:
  108             raise ImportError(
  109                 "Couldn't import Django. Are you sure it's installed and "
  110                 "available on your PYTHONPATH environment variable? Did you "
  111                 "forget to activate a virtual environment?"
  112             ) from exc
  113         execute_from_command_line(["", "migrate_schemas"])
  114         execute_from_command_line(["", "migrate_schemas", "--schema", "template", "--tenant"])
  115         execute_from_command_line(
  116             ["", "check"] + ([] if CONFIG.get_bool("debug") else ["--deploy"])
  117         )
  118     finally:
  119         release_lock(curr)
  120 
  121 
  122 if __name__ == "__main__":
  123     run_migrations()
  124
  [end of lifecycle/migrate.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/lifecycle/migrate.py b/lifecycle/migrate.py
  --- a/lifecycle/migrate.py
  +++ b/lifecycle/migrate.py
  @@ -117,6 +117,8 @@
           )
       finally:
           release_lock(curr)
  +        curr.close()
  +        conn.close()
   
   
   if __name__ == "__main__":
  
verification_info: {"golden_diff": "diff --git a/lifecycle/migrate.py b/lifecycle/migrate.py\n--- a/lifecycle/migrate.py\n+++ b/lifecycle/migrate.py\n@@ -117,6 +117,8 @@\n         )\n     finally:\n         release_lock(curr)\n+        curr.close()\n+        conn.close()\n \n \n if __name__ == \"__main__\":\n", "issue": "2024.4.0 LongRunningTransaction\n**Describe the bug**\r\nPrometheus alert for a long running transaction.\r\n\r\nI think the transaction is\r\n\r\n```\r\nSELECT pg_advisory_unlock($1)\r\n```\r\n\r\n**To Reproduce**\r\nNo activity, sitting idle\r\n\r\n**Expected behavior**\r\nShouldn't have the alert\r\n\r\n**Screenshots**\r\n\r\n**Logs**\r\n\r\n**Version and Deployment (please complete the following information):**\r\n2024.4.0 kubernetes\r\n\r\n**Additional context**\r\nAdd any other context about the problem here.\r\n\n", "before_files": [{"content": "#!/usr/bin/env python\n\"\"\"System Migration handler\"\"\"\nfrom importlib.util import module_from_spec, spec_from_file_location\nfrom inspect import getmembers, isclass\nfrom os import environ, system\nfrom pathlib import Path\nfrom typing import Any\n\nfrom psycopg import Connection, Cursor, connect\nfrom structlog.stdlib import get_logger\n\nfrom authentik.lib.config import CONFIG\n\nLOGGER = get_logger()\nADV_LOCK_UID = 1000\nLOCKED = False\n\n\nclass CommandError(Exception):\n    \"\"\"Error raised when a system_crit command fails\"\"\"\n\n\nclass BaseMigration:\n    \"\"\"Base System Migration\"\"\"\n\n    cur: Cursor\n    con: Connection\n\n    def __init__(self, cur: Any, con: Any):\n        self.cur = cur\n        self.con = con\n\n    def system_crit(self, command: str):\n        \"\"\"Run system command\"\"\"\n        LOGGER.debug(\"Running system_crit command\", command=command)\n        retval = system(command)  # nosec\n        if retval != 0:\n            raise CommandError(\"Migration error\")\n\n    def fake_migration(self, *app_migration: tuple[str, str]):\n        \"\"\"Fake apply a list of migrations, arguments are\n        expected to be tuples of (app_label, migration_name)\"\"\"\n        for app, _migration in app_migration:\n            self.system_crit(f\"./manage.py migrate {app} {_migration} --fake\")\n\n    def needs_migration(self) -> bool:\n        \"\"\"Return true if Migration needs to be run\"\"\"\n        return False\n\n    def run(self):\n        \"\"\"Run the actual migration\"\"\"\n\n\ndef wait_for_lock(cursor: Cursor):\n    \"\"\"lock an advisory lock to prevent multiple instances from migrating at once\"\"\"\n    LOGGER.info(\"waiting to acquire database lock\")\n    cursor.execute(\"SELECT pg_advisory_lock(%s)\", (ADV_LOCK_UID,))\n\n    global LOCKED  # noqa: PLW0603\n    LOCKED = True\n\n\ndef release_lock(cursor: Cursor):\n    \"\"\"Release database lock\"\"\"\n    if not LOCKED:\n        return\n    LOGGER.info(\"releasing database lock\")\n    cursor.execute(\"SELECT pg_advisory_unlock(%s)\", (ADV_LOCK_UID,))\n\n\ndef run_migrations():\n    conn = connect(\n        dbname=CONFIG.get(\"postgresql.name\"),\n        user=CONFIG.get(\"postgresql.user\"),\n        password=CONFIG.get(\"postgresql.password\"),\n        host=CONFIG.get(\"postgresql.host\"),\n        port=CONFIG.get_int(\"postgresql.port\"),\n        sslmode=CONFIG.get(\"postgresql.sslmode\"),\n        sslrootcert=CONFIG.get(\"postgresql.sslrootcert\"),\n        sslcert=CONFIG.get(\"postgresql.sslcert\"),\n        sslkey=CONFIG.get(\"postgresql.sslkey\"),\n    )\n    curr = conn.cursor()\n    try:\n        for migration_path in Path(__file__).parent.absolute().glob(\"system_migrations/*.py\"):\n            spec = spec_from_file_location(\"lifecycle.system_migrations\", migration_path)\n            if not spec:\n                continue\n            mod = module_from_spec(spec)\n            spec.loader.exec_module(mod)\n\n            for name, sub in getmembers(mod, isclass):\n                if name != \"Migration\":\n                    continue\n                migration = sub(curr, conn)\n                if migration.needs_migration():\n                    wait_for_lock(curr)\n                    LOGGER.info(\"Migration needs to be applied\", migration=migration_path.name)\n                    migration.run()\n                    LOGGER.info(\"Migration finished applying\", migration=migration_path.name)\n                    release_lock(curr)\n        LOGGER.info(\"applying django migrations\")\n        environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"authentik.root.settings\")\n        wait_for_lock(curr)\n        try:\n            from django.core.management import execute_from_command_line\n        except ImportError as exc:\n            raise ImportError(\n                \"Couldn't import Django. Are you sure it's installed and \"\n                \"available on your PYTHONPATH environment variable? Did you \"\n                \"forget to activate a virtual environment?\"\n            ) from exc\n        execute_from_command_line([\"\", \"migrate_schemas\"])\n        execute_from_command_line([\"\", \"migrate_schemas\", \"--schema\", \"template\", \"--tenant\"])\n        execute_from_command_line(\n            [\"\", \"check\"] + ([] if CONFIG.get_bool(\"debug\") else [\"--deploy\"])\n        )\n    finally:\n        release_lock(curr)\n\n\nif __name__ == \"__main__\":\n    run_migrations()\n", "path": "lifecycle/migrate.py"}]}