Unclosed connections prevent dbt from exiting on Snowflake with keepalives enabled
## Issue

### Issue description
The `client_session_keep_alive` config for snowflake-connector-python is implemented using a threaded heartbeat. During the `dbt docs generate` command (and possibly others), dbt doesn't close 100% of the connections it opens. As a result, the snowflake-connector-python threads continue to heartbeat in perpetuity, preventing dbt from exiting. See the comment [here](https://github.com/snowflakedb/snowflake-connector-python/issues/104#issuecomment-424350077) while slowly and deliberately raising the palm of your hand  into the vicinity of your face.

We should, in general, ensure that dbt always closes any connections that it opens.

### Results
dbt finishes executing, but control is not returned to the terminal. Instead, python hangs on a lock held by snowflake-connector-python, and the user needs to ctrl-c to exit.

### System information
The output of `dbt --version`:
```
0.12.2
```

The operating system you're running on: Any

### Steps to reproduce
1. Set up a Snowflake profile, configuring `client_session_keep_alive` to be `True`
2. Run `dbt docs generate`
3. wait forever
diff --git a/core/dbt/main.py b/core/dbt/main.py
index fbfa02e17..655ea698a 100644
--- a/core/dbt/main.py
+++ b/core/dbt/main.py
@@ -23,7 +23,7 @@ import dbt.task.freshness as freshness_task
 import dbt.task.run_operation as run_operation_task
 from dbt.task.list import ListTask
 from dbt.task.rpc_server import RPCServerTask
-from dbt.adapters.factory import reset_adapters
+from dbt.adapters.factory import reset_adapters, cleanup_connections
 
 import dbt.tracking
 import dbt.ui.printer
@@ -123,6 +123,15 @@ def initialize_config_values(parsed):
     cfg.set_values(parsed.profiles_dir)
 
 
+@contextmanager
+def adapter_management():
+    reset_adapters()
+    try:
+        yield
+    finally:
+        cleanup_connections()
+
+
 def handle_and_check(args):
     with log_manager.applicationbound():
         parsed = parse_args(args)
@@ -143,10 +152,10 @@ def handle_and_check(args):
 
             initialize_config_values(parsed)
 
-            reset_adapters()
+            with adapter_management():
 
-            task, res = run_from_args(parsed)
-            success = task.interpret_results(res)
+                task, res = run_from_args(parsed)
+                success = task.interpret_results(res)
 
             return res, success
 
['core/dbt/main.py']