We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Parsl internal bugs silently squashed then hangs
@benclifford reported an alarming bug in which a error in the parsl code does not throw an exception but is silently squashed. This is followed by the code hanging and not making progress. To make the situation even worse the strategy thread continues to run, giving the impression that parsl is doing something. 

My suspicion is the the exception silently kills some thread, and that goes unreported.

The string formatting bug added here (in memoization code) -> https://github.com/Parsl/parsl/tree/pr238-related-example reproduces this issue with a test script that hits this memoization code. 

Some recommendations:
1. Better exception handling
2. Logs to show thread-ids so that we can see when threads have gone missing

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `parsl/__init__.py`
Content:
```
1 """Parsl is a Parallel Scripting Library, designed to enable efficient workflow execution.
2 
3 Importing
4 ---------
5 
6 To get all the required functionality, we suggest importing the library as follows:
7 
8 >>> import parsl
9 >>> from parsl import *
10 
11 Logging
12 -------
13 
14 Following the general logging philosophy of python libraries, by default
15 `Parsl <https://github.com/swift-lang/swift-e-lab/>`_ doesn't log anything.
16 However the following helper functions are provided for logging:
17 
18 1. set_stream_logger
19     This sets the logger to the StreamHandler. This is quite useful when working from
20     a Jupyter notebook.
21 
22 2. set_file_logger
23     This sets the logging to a file. This is ideal for reporting issues to the dev team.
24 
25 """
26 import logging
27 
28 from parsl.version import VERSION
29 from parsl.app.app import App
30 from parsl.executors.threads import ThreadPoolExecutor
31 from parsl.executors.ipp import IPyParallelExecutor
32 from parsl.data_provider.files import File
33 
34 from parsl.dataflow.dflow import DataFlowKernel, DataFlowKernelLoader
35 from parsl.app.app_factory import AppFactoryFactory
36 APP_FACTORY_FACTORY = AppFactoryFactory('central')
37 
38 __author__ = 'Yadu Nand Babuji'
39 __version__ = VERSION
40 
41 __all__ = [
42     'App', 'DataFlowKernel', 'File', 'ThreadPoolExecutor',
43     'IPyParallelExecutor', 'set_stream_logger', 'set_file_logger'
44 ]
45 
46 clear = DataFlowKernelLoader.clear
47 load = DataFlowKernelLoader.load
48 dfk = DataFlowKernelLoader.dfk
49 
50 
51 def set_stream_logger(name='parsl', level=logging.DEBUG, format_string=None):
52     """Add a stream log handler.
53 
54     Args:
55          - name (string) : Set the logger name.
56          - level (logging.LEVEL) : Set to logging.DEBUG by default.
57          - format_string (sting) : Set to None by default.
58 
59     Returns:
60          - None
61     """
62     if format_string is None:
63         # format_string = "%(asctime)s %(name)s [%(levelname)s] Thread:%(thread)d %(message)s"
64         format_string = "%(asctime)s %(name)s:%(lineno)d [%(levelname)s]  %(message)s"
65 
66     logger = logging.getLogger(name)
67     logger.setLevel(logging.DEBUG)
68     handler = logging.StreamHandler()
69     handler.setLevel(level)
70     formatter = logging.Formatter(format_string, datefmt='%Y-%m-%d %H:%M:%S')
71     handler.setFormatter(formatter)
72     logger.addHandler(handler)
73 
74 
75 def set_file_logger(filename, name='parsl', level=logging.DEBUG, format_string=None):
76     """Add a stream log handler.
77 
78     Args:
79         - filename (string): Name of the file to write logs to
80         - name (string): Logger name
81         - level (logging.LEVEL): Set the logging level.
82         - format_string (string): Set the format string
83 
84     Returns:
85        -  None
86     """
87     if format_string is None:
88         format_string = "%(asctime)s %(name)s:%(lineno)d [%(levelname)s]  %(message)s"
89 
90     logger = logging.getLogger(name)
91     logger.setLevel(logging.DEBUG)
92     handler = logging.FileHandler(filename)
93     handler.setLevel(level)
94     formatter = logging.Formatter(format_string, datefmt='%Y-%m-%d %H:%M:%S')
95     handler.setFormatter(formatter)
96     logger.addHandler(handler)
97 
98 
99 class NullHandler(logging.Handler):
100     """Setup default logging to /dev/null since this is library."""
101 
102     def emit(self, record):
103         pass
104 
105 
106 logging.getLogger('parsl').addHandler(NullHandler())
107
```
--- 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/parsl/__init__.py b/parsl/__init__.py
--- a/parsl/__init__.py
+++ b/parsl/__init__.py
@@ -71,6 +71,12 @@
     handler.setFormatter(formatter)
     logger.addHandler(handler)
 
+    # Concurrent.futures errors are also of interest, as exceptions
+    # which propagate out of the top of a callback are logged this way
+    # and then discarded. (see #240)
+    futures_logger = logging.getLogger("concurrent.futures")
+    futures_logger.addHandler(handler)
+
 
 def set_file_logger(filename, name='parsl', level=logging.DEBUG, format_string=None):
     """Add a stream log handler.
@@ -95,6 +101,11 @@
     handler.setFormatter(formatter)
     logger.addHandler(handler)
 
+    # see note in set_stream_logger for notes about logging
+    # concurrent.futures
+    futures_logger = logging.getLogger("concurrent.futures")
+    futures_logger.addHandler(handler)
+
 
 class NullHandler(logging.Handler):
     """Setup default logging to /dev/null since this is library."""

{"golden_diff": "diff --git a/parsl/__init__.py b/parsl/__init__.py\n--- a/parsl/__init__.py\n+++ b/parsl/__init__.py\n@@ -71,6 +71,12 @@\n     handler.setFormatter(formatter)\n     logger.addHandler(handler)\n \n+    # Concurrent.futures errors are also of interest, as exceptions\n+    # which propagate out of the top of a callback are logged this way\n+    # and then discarded. (see #240)\n+    futures_logger = logging.getLogger(\"concurrent.futures\")\n+    futures_logger.addHandler(handler)\n+\n \n def set_file_logger(filename, name='parsl', level=logging.DEBUG, format_string=None):\n     \"\"\"Add a stream log handler.\n@@ -95,6 +101,11 @@\n     handler.setFormatter(formatter)\n     logger.addHandler(handler)\n \n+    # see note in set_stream_logger for notes about logging\n+    # concurrent.futures\n+    futures_logger = logging.getLogger(\"concurrent.futures\")\n+    futures_logger.addHandler(handler)\n+\n \n class NullHandler(logging.Handler):\n     \"\"\"Setup default logging to /dev/null since this is library.\"\"\"\n", "issue": "Parsl internal bugs silently squashed then hangs\n@benclifford reported an alarming bug in which a error in the parsl code does not throw an exception but is silently squashed. This is followed by the code hanging and not making progress. To make the situation even worse the strategy thread continues to run, giving the impression that parsl is doing something. \r\n\r\nMy suspicion is the the exception silently kills some thread, and that goes unreported.\r\n\r\nThe string formatting bug added here (in memoization code) -> https://github.com/Parsl/parsl/tree/pr238-related-example reproduces this issue with a test script that hits this memoization code. \r\n\r\nSome recommendations:\r\n1. Better exception handling\r\n2. Logs to show thread-ids so that we can see when threads have gone missing\n", "before_files": [{"content": "\"\"\"Parsl is a Parallel Scripting Library, designed to enable efficient workflow execution.\n\nImporting\n---------\n\nTo get all the required functionality, we suggest importing the library as follows:\n\n>>> import parsl\n>>> from parsl import *\n\nLogging\n-------\n\nFollowing the general logging philosophy of python libraries, by default\n`Parsl <https://github.com/swift-lang/swift-e-lab/>`_ doesn't log anything.\nHowever the following helper functions are provided for logging:\n\n1. set_stream_logger\n    This sets the logger to the StreamHandler. This is quite useful when working from\n    a Jupyter notebook.\n\n2. set_file_logger\n    This sets the logging to a file. This is ideal for reporting issues to the dev team.\n\n\"\"\"\nimport logging\n\nfrom parsl.version import VERSION\nfrom parsl.app.app import App\nfrom parsl.executors.threads import ThreadPoolExecutor\nfrom parsl.executors.ipp import IPyParallelExecutor\nfrom parsl.data_provider.files import File\n\nfrom parsl.dataflow.dflow import DataFlowKernel, DataFlowKernelLoader\nfrom parsl.app.app_factory import AppFactoryFactory\nAPP_FACTORY_FACTORY = AppFactoryFactory('central')\n\n__author__ = 'Yadu Nand Babuji'\n__version__ = VERSION\n\n__all__ = [\n    'App', 'DataFlowKernel', 'File', 'ThreadPoolExecutor',\n    'IPyParallelExecutor', 'set_stream_logger', 'set_file_logger'\n]\n\nclear = DataFlowKernelLoader.clear\nload = DataFlowKernelLoader.load\ndfk = DataFlowKernelLoader.dfk\n\n\ndef set_stream_logger(name='parsl', level=logging.DEBUG, format_string=None):\n    \"\"\"Add a stream log handler.\n\n    Args:\n         - name (string) : Set the logger name.\n         - level (logging.LEVEL) : Set to logging.DEBUG by default.\n         - format_string (sting) : Set to None by default.\n\n    Returns:\n         - None\n    \"\"\"\n    if format_string is None:\n        # format_string = \"%(asctime)s %(name)s [%(levelname)s] Thread:%(thread)d %(message)s\"\n        format_string = \"%(asctime)s %(name)s:%(lineno)d [%(levelname)s]  %(message)s\"\n\n    logger = logging.getLogger(name)\n    logger.setLevel(logging.DEBUG)\n    handler = logging.StreamHandler()\n    handler.setLevel(level)\n    formatter = logging.Formatter(format_string, datefmt='%Y-%m-%d %H:%M:%S')\n    handler.setFormatter(formatter)\n    logger.addHandler(handler)\n\n\ndef set_file_logger(filename, name='parsl', level=logging.DEBUG, format_string=None):\n    \"\"\"Add a stream log handler.\n\n    Args:\n        - filename (string): Name of the file to write logs to\n        - name (string): Logger name\n        - level (logging.LEVEL): Set the logging level.\n        - format_string (string): Set the format string\n\n    Returns:\n       -  None\n    \"\"\"\n    if format_string is None:\n        format_string = \"%(asctime)s %(name)s:%(lineno)d [%(levelname)s]  %(message)s\"\n\n    logger = logging.getLogger(name)\n    logger.setLevel(logging.DEBUG)\n    handler = logging.FileHandler(filename)\n    handler.setLevel(level)\n    formatter = logging.Formatter(format_string, datefmt='%Y-%m-%d %H:%M:%S')\n    handler.setFormatter(formatter)\n    logger.addHandler(handler)\n\n\nclass NullHandler(logging.Handler):\n    \"\"\"Setup default logging to /dev/null since this is library.\"\"\"\n\n    def emit(self, record):\n        pass\n\n\nlogging.getLogger('parsl').addHandler(NullHandler())\n", "path": "parsl/__init__.py"}], "after_files": [{"content": "\"\"\"Parsl is a Parallel Scripting Library, designed to enable efficient workflow execution.\n\nImporting\n---------\n\nTo get all the required functionality, we suggest importing the library as follows:\n\n>>> import parsl\n>>> from parsl import *\n\nLogging\n-------\n\nFollowing the general logging philosophy of python libraries, by default\n`Parsl <https://github.com/swift-lang/swift-e-lab/>`_ doesn't log anything.\nHowever the following helper functions are provided for logging:\n\n1. set_stream_logger\n    This sets the logger to the StreamHandler. This is quite useful when working from\n    a Jupyter notebook.\n\n2. set_file_logger\n    This sets the logging to a file. This is ideal for reporting issues to the dev team.\n\n\"\"\"\nimport logging\n\nfrom parsl.version import VERSION\nfrom parsl.app.app import App\nfrom parsl.executors.threads import ThreadPoolExecutor\nfrom parsl.executors.ipp import IPyParallelExecutor\nfrom parsl.data_provider.files import File\n\nfrom parsl.dataflow.dflow import DataFlowKernel, DataFlowKernelLoader\nfrom parsl.app.app_factory import AppFactoryFactory\nAPP_FACTORY_FACTORY = AppFactoryFactory('central')\n\n__author__ = 'Yadu Nand Babuji'\n__version__ = VERSION\n\n__all__ = [\n    'App', 'DataFlowKernel', 'File', 'ThreadPoolExecutor',\n    'IPyParallelExecutor', 'set_stream_logger', 'set_file_logger'\n]\n\nclear = DataFlowKernelLoader.clear\nload = DataFlowKernelLoader.load\ndfk = DataFlowKernelLoader.dfk\n\n\ndef set_stream_logger(name='parsl', level=logging.DEBUG, format_string=None):\n    \"\"\"Add a stream log handler.\n\n    Args:\n         - name (string) : Set the logger name.\n         - level (logging.LEVEL) : Set to logging.DEBUG by default.\n         - format_string (sting) : Set to None by default.\n\n    Returns:\n         - None\n    \"\"\"\n    if format_string is None:\n        # format_string = \"%(asctime)s %(name)s [%(levelname)s] Thread:%(thread)d %(message)s\"\n        format_string = \"%(asctime)s %(name)s:%(lineno)d [%(levelname)s]  %(message)s\"\n\n    logger = logging.getLogger(name)\n    logger.setLevel(logging.DEBUG)\n    handler = logging.StreamHandler()\n    handler.setLevel(level)\n    formatter = logging.Formatter(format_string, datefmt='%Y-%m-%d %H:%M:%S')\n    handler.setFormatter(formatter)\n    logger.addHandler(handler)\n\n    # Concurrent.futures errors are also of interest, as exceptions\n    # which propagate out of the top of a callback are logged this way\n    # and then discarded. (see #240)\n    futures_logger = logging.getLogger(\"concurrent.futures\")\n    futures_logger.addHandler(handler)\n\n\ndef set_file_logger(filename, name='parsl', level=logging.DEBUG, format_string=None):\n    \"\"\"Add a stream log handler.\n\n    Args:\n        - filename (string): Name of the file to write logs to\n        - name (string): Logger name\n        - level (logging.LEVEL): Set the logging level.\n        - format_string (string): Set the format string\n\n    Returns:\n       -  None\n    \"\"\"\n    if format_string is None:\n        format_string = \"%(asctime)s %(name)s:%(lineno)d [%(levelname)s]  %(message)s\"\n\n    logger = logging.getLogger(name)\n    logger.setLevel(logging.DEBUG)\n    handler = logging.FileHandler(filename)\n    handler.setLevel(level)\n    formatter = logging.Formatter(format_string, datefmt='%Y-%m-%d %H:%M:%S')\n    handler.setFormatter(formatter)\n    logger.addHandler(handler)\n\n    # see note in set_stream_logger for notes about logging\n    # concurrent.futures\n    futures_logger = logging.getLogger(\"concurrent.futures\")\n    futures_logger.addHandler(handler)\n\n\nclass NullHandler(logging.Handler):\n    \"\"\"Setup default logging to /dev/null since this is library.\"\"\"\n\n    def emit(self, record):\n        pass\n\n\nlogging.getLogger('parsl').addHandler(NullHandler())\n", "path": "parsl/__init__.py"}]}