{"html_url": "https://github.com/simonw/datasette/issues/935#issuecomment-674450607", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/935", "id": 674450607, "node_id": "MDEyOklzc3VlQ29tbWVudDY3NDQ1MDYwNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-15T21:50:41Z", "updated_at": "2020-08-15T21:50:41Z", "author_association": "OWNER", "body": "The bug is here:\r\n\r\nhttps://github.com/simonw/datasette/blob/13b3b51087964d5e1a8c1cdd2495e07bdbe176b8/datasette/database.py#L89-L100\r\n\r\nIf `conn = self.connect(write=True)` raises an exception the entire server hangs, like this:\r\n```\r\n% datasette -i fixtures.db --get / \r\nException in thread Thread-1:\r\nTraceback (most recent call last):\r\n File \"/usr/local/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/lib/python3.8/threading.py\", line 932, in _bootstrap_inner\r\n self.run()\r\n File \"/usr/local/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/lib/python3.8/threading.py\", line 870, in run\r\n self._target(*self._args, **self._kwargs)\r\n File \"/Users/simon/.local/share/virtualenvs/latest-datasette-with-all-plugins-PJL_Xy9e/lib/python3.8/site-packages/datasette/database.py\", line 92, in _execute_writes\r\n conn = self.connect(write=True)\r\n File \"/Users/simon/.local/share/virtualenvs/latest-datasette-with-all-plugins-PJL_Xy9e/lib/python3.8/site-packages/datasette/database.py\", line 55, in connect\r\n assert not (write and not self.is_mutable)\r\nAssertionError\r\n\r\n... server hangs here ...\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 679646710, "label": "db.execute_write_fn(create_tables, block=True) hangs a thread if connection fails"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/935#issuecomment-674450652", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/935", "id": 674450652, "node_id": "MDEyOklzc3VlQ29tbWVudDY3NDQ1MDY1Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-15T21:51:22Z", "updated_at": "2020-08-15T21:51:22Z", "author_association": "OWNER", "body": "The easiest way to recreate this is to attempt a write against an immutable database, which triggers this assertion error:\r\n\r\nhttps://github.com/simonw/datasette/blob/13b3b51087964d5e1a8c1cdd2495e07bdbe176b8/datasette/database.py#L47-L55", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 679646710, "label": "db.execute_write_fn(create_tables, block=True) hangs a thread if connection fails"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/935#issuecomment-674451012", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/935", "id": 674451012, "node_id": "MDEyOklzc3VlQ29tbWVudDY3NDQ1MTAxMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-15T21:56:13Z", "updated_at": "2020-08-15T21:56:13Z", "author_association": "OWNER", "body": "This implementation seems to fix it, need to work out how to test though.\r\n```diff\r\ndiff --git a/datasette/database.py b/datasette/database.py\r\nindex ffa7a79..7ba1456 100644\r\n--- a/datasette/database.py\r\n+++ b/datasette/database.py\r\n@@ -89,14 +89,22 @@ class Database:\r\n def _execute_writes(self):\r\n # Infinite looping thread that protects the single write connection\r\n # to this database\r\n- conn = self.connect(write=True)\r\n+ conn_exception = None\r\n+ conn = None\r\n+ try:\r\n+ conn = self.connect(write=True)\r\n+ except Exception as e:\r\n+ conn_exception = e\r\n while True:\r\n task = self._write_queue.get()\r\n- try:\r\n- result = task.fn(conn)\r\n- except Exception as e:\r\n- print(e)\r\n- result = e\r\n+ if conn_exception is not None:\r\n+ result = conn_exception\r\n+ else:\r\n+ try:\r\n+ result = task.fn(conn)\r\n+ except Exception as e:\r\n+ print(e)\r\n+ result = e\r\n task.reply_queue.sync_q.put(result)\r\n \r\n async def execute_fn(self, fn):\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 679646710, "label": "db.execute_write_fn(create_tables, block=True) hangs a thread if connection fails"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/936#issuecomment-674453318", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/936", "id": 674453318, "node_id": "MDEyOklzc3VlQ29tbWVudDY3NDQ1MzMxOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-15T22:29:15Z", "updated_at": "2020-08-15T22:32:58Z", "author_association": "OWNER", "body": "Test failure:\r\n```\r\ntests/test_canned_queries.py F\r\n>>> captured stdout >>> \r\n__enter__\r\n>>> traceback >>> \r\n\r\ncanned_write_client = \r\n\r\n def test_insert(canned_write_client):\r\n response = canned_write_client.post(\r\n \"/data/add_name\",\r\n {\"name\": \"Hello\"},\r\n allow_redirects=False,\r\n csrftoken_from=True,\r\n cookies={\"foo\": \"bar\"},\r\n )\r\n assert 302 == response.status\r\n> assert \"/data/add_name?success\" == response.headers[\"Location\"]\r\nE AssertionError: assert '/data/add_name?success' == '/data/add_name'\r\nE - /data/add_name\r\nE + /data/add_name?success\r\nE ? ++++++++\r\n\r\n/Users/simon/Dropbox/Development/datasette/tests/test_canned_queries.py:66: AssertionError\r\n```\r\nNo idea why this change would affect that test.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 679650632, "label": "Don't hang in db.execute_write_fn() if connection fails"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/936#issuecomment-674453772", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/936", "id": 674453772, "node_id": "MDEyOklzc3VlQ29tbWVudDY3NDQ1Mzc3Mg==", "user": {"value": 22429695, "label": "codecov[bot]"}, "created_at": "2020-08-15T22:35:29Z", "updated_at": "2020-08-15T22:35:29Z", "author_association": "NONE", "body": "# [Codecov](https://codecov.io/gh/simonw/datasette/pull/936?src=pr&el=h1) Report\n> Merging [#936](https://codecov.io/gh/simonw/datasette/pull/936?src=pr&el=desc) into [main](https://codecov.io/gh/simonw/datasette/commit/13b3b51087964d5e1a8c1cdd2495e07bdbe176b8&el=desc) will **increase** coverage by `0.02%`.\n> The diff coverage is `n/a`.\n\n[![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/936/graphs/tree.svg?width=650&height=150&src=pr&token=eSahVY7kw1)](https://codecov.io/gh/simonw/datasette/pull/936?src=pr&el=tree)\n\n```diff\n@@ Coverage Diff @@\n## main #936 +/- ##\n==========================================\n+ Coverage 84.02% 84.04% +0.02% \n==========================================\n Files 28 28 \n Lines 3774 3774 \n==========================================\n+ Hits 3171 3172 +1 \n+ Misses 603 602 -1 \n```\n\n\n| [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/936?src=pr&el=tree) | Coverage \u0394 | |\n|---|---|---|\n| [datasette/app.py](https://codecov.io/gh/simonw/datasette/pull/936/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `96.18% <0.00%> (+0.18%)` | :arrow_up: |\n\n------\n\n[Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/936?src=pr&el=continue).\n> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)\n> `\u0394 = absolute (impact)`, `\u00f8 = not affected`, `? = missing data`\n> Powered by [Codecov](https://codecov.io/gh/simonw/datasette/pull/936?src=pr&el=footer). Last update [13b3b51...94a68b9](https://codecov.io/gh/simonw/datasette/pull/936?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 679650632, "label": "Don't hang in db.execute_write_fn() if connection fails"}, "performed_via_github_app": null}