We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Mess in integrations setup
Currently we have two issues with integrations setup:
1. 'setup' is call for all integrations, regardless 'publish' flag.
2. if integration exists in db and in config file with same name, then only integration from db will be setup. That bad, because any integration from config file will be copied to db right after mindsdb start, and any changes in config file after that will have no effect.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mindsdb/__main__.py`
Content:
```
1 import atexit
2 import traceback
3 import sys
4 import os
5 import time
6 import asyncio
7 import signal
8 
9 import torch.multiprocessing as mp
10 
11 from mindsdb.utilities.config import Config, STOP_THREADS_EVENT
12 from mindsdb.interfaces.model.model_interface import ray_based, ModelInterface
13 from mindsdb.api.http.start import start as start_http
14 from mindsdb.api.mysql.start import start as start_mysql
15 from mindsdb.api.mongo.start import start as start_mongo
16 from mindsdb.utilities.ps import is_pid_listen_port, get_child_pids
17 from mindsdb.utilities.functions import args_parse
18 from mindsdb.interfaces.database.database import DatabaseWrapper
19 from mindsdb.utilities.log import log
20 
21 from mindsdb.interfaces.database.integrations import get_db_integrations
22 
23 COMPANY_ID = os.environ.get('MINDSDB_COMPANY_ID', None)
24 
25 
26 def close_api_gracefully(apis):
27     try:
28         for api in apis.values():
29             process = api['process']
30             childs = get_child_pids(process.pid)
31             for p in childs:
32                 try:
33                     os.kill(p, signal.SIGTERM)
34                 except Exception:
35                     p.kill()
36             sys.stdout.flush()
37             process.terminate()
38             process.join()
39             sys.stdout.flush()
40         if ray_based:
41             os.system('ray stop --force')
42     except KeyboardInterrupt:
43         sys.exit(0)
44 
45 
46 if __name__ == '__main__':
47     mp.freeze_support()
48     args = args_parse()
49     config = Config()
50 
51     if args.verbose is True:
52         # Figure this one out later
53         pass
54 
55     os.environ['DEFAULT_LOG_LEVEL'] = config['log']['level']['console']
56     os.environ['LIGHTWOOD_LOG_LEVEL'] = config['log']['level']['console']
57 
58     # Switch to this once the native interface has it's own thread :/
59     ctx = mp.get_context('spawn')
60 
61     from mindsdb.__about__ import __version__ as mindsdb_version
62     print(f'Version {mindsdb_version}')
63 
64     print(f'Configuration file:\n   {config.config_path}')
65     print(f"Storage path:\n   {config['paths']['root']}")
66 
67     # @TODO Backwards compatibiltiy for tests, remove later
68     from mindsdb.interfaces.database.integrations import add_db_integration, get_db_integration
69     dbw = DatabaseWrapper(COMPANY_ID)
70     model_interface = ModelInterface()
71     raw_model_data_arr = model_interface.get_models()
72     model_data_arr = []
73     for model in raw_model_data_arr:
74         if model['status'] == 'complete':
75             x = model_interface.get_model_data(model['name'])
76             try:
77                 model_data_arr.append(model_interface.get_model_data(model['name']))
78             except Exception:
79                 pass
80 
81     is_cloud = config.get('cloud', False)
82     if not is_cloud:
83         for integration_name in get_db_integrations(COMPANY_ID, sensitive_info=True):
84             print(f"Setting up integration: {integration_name}")
85             dbw.setup_integration(integration_name)
86 
87     for integration_name in config.get('integrations', {}):
88         print(f'Adding: {integration_name}')
89         try:
90             it = get_db_integration(integration_name, None)
91             if it is None:
92                 add_db_integration(integration_name, config['integrations'][integration_name], None)            # Setup for user `None`, since we don't need this for cloud
93             if config['integrations'][integration_name].get('publish', False) and not is_cloud:
94                 dbw.setup_integration(integration_name)
95                 dbw.register_predictors(model_data_arr, integration_name=integration_name)
96         except Exception as e:
97             log.error(f'\n\nError: {e} adding database integration {integration_name}\n\n')
98 
99     del model_interface
100     del dbw
101     # @TODO Backwards compatibiltiy for tests, remove later
102 
103     if args.api is None:
104         api_arr = ['http', 'mysql']
105     else:
106         api_arr = args.api.split(',')
107 
108     apis = {
109         api: {
110             'port': config['api'][api]['port'],
111             'process': None,
112             'started': False
113         } for api in api_arr
114     }
115 
116     start_functions = {
117         'http': start_http,
118         'mysql': start_mysql,
119         'mongodb': start_mongo
120     }
121 
122     for api_name, api_data in apis.items():
123         if api_data['started']:
124             continue
125         print(f'{api_name} API: starting...')
126         try:
127             if api_name == 'http':
128                 p = ctx.Process(target=start_functions[api_name], args=(args.verbose, args.no_studio))
129             else:
130                 p = ctx.Process(target=start_functions[api_name], args=(args.verbose,))
131             p.start()
132             api_data['process'] = p
133         except Exception as e:
134             log.error(f'Failed to start {api_name} API with exception {e}\n{traceback.format_exc()}')
135             close_api_gracefully(apis)
136             raise e
137 
138     atexit.register(close_api_gracefully, apis=apis)
139 
140     async def wait_api_start(api_name, pid, port):
141         timeout = 60
142         start_time = time.time()
143         started = is_pid_listen_port(pid, port)
144         while (time.time() - start_time) < timeout and started is False:
145             await asyncio.sleep(0.5)
146             started = is_pid_listen_port(pid, port)
147         return api_name, port, started
148 
149     async def wait_apis_start():
150         futures = [
151             wait_api_start(api_name, api_data['process'].pid, api_data['port'])
152             for api_name, api_data in apis.items() if 'port' in api_data
153         ]
154         for i, future in enumerate(asyncio.as_completed(futures)):
155             api_name, port, started = await future
156             if started:
157                 print(f"{api_name} API: started on {port}")
158             else:
159                 log.error(f"ERROR: {api_name} API cant start on {port}")
160 
161     ioloop = asyncio.get_event_loop()
162     ioloop.run_until_complete(wait_apis_start())
163     ioloop.close()
164 
165     try:
166         for api_data in apis.values():
167             api_data['process'].join()
168     except KeyboardInterrupt:
169         print('Stopping stream integrations...')
170         STOP_THREADS_EVENT.set()
171         print('Closing app...')
172
```
--- 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/mindsdb/__main__.py b/mindsdb/__main__.py
--- a/mindsdb/__main__.py
+++ b/mindsdb/__main__.py
@@ -82,17 +82,20 @@
     if not is_cloud:
         for integration_name in get_db_integrations(COMPANY_ID, sensitive_info=True):
             print(f"Setting up integration: {integration_name}")
-            dbw.setup_integration(integration_name)
+            if get_db_integration(integration_name, COMPANY_ID)['publish']:
+                # do setup and register only if it is 'publish' integration
+                dbw.setup_integration(integration_name)
+                dbw.register_predictors(model_data_arr, integration_name=integration_name)
 
     for integration_name in config.get('integrations', {}):
         print(f'Adding: {integration_name}')
         try:
             it = get_db_integration(integration_name, None)
-            if it is None:
+            if it is None:      # register and setup it only if it doesn't conflict with records in db
                 add_db_integration(integration_name, config['integrations'][integration_name], None)            # Setup for user `None`, since we don't need this for cloud
-            if config['integrations'][integration_name].get('publish', False) and not is_cloud:
-                dbw.setup_integration(integration_name)
-                dbw.register_predictors(model_data_arr, integration_name=integration_name)
+                if config['integrations'][integration_name].get('publish', False) and not is_cloud:
+                    dbw.setup_integration(integration_name)
+                    dbw.register_predictors(model_data_arr, integration_name=integration_name)
         except Exception as e:
             log.error(f'\n\nError: {e} adding database integration {integration_name}\n\n')

{"golden_diff": "diff --git a/mindsdb/__main__.py b/mindsdb/__main__.py\n--- a/mindsdb/__main__.py\n+++ b/mindsdb/__main__.py\n@@ -82,17 +82,20 @@\n     if not is_cloud:\n         for integration_name in get_db_integrations(COMPANY_ID, sensitive_info=True):\n             print(f\"Setting up integration: {integration_name}\")\n-            dbw.setup_integration(integration_name)\n+            if get_db_integration(integration_name, COMPANY_ID)['publish']:\n+                # do setup and register only if it is 'publish' integration\n+                dbw.setup_integration(integration_name)\n+                dbw.register_predictors(model_data_arr, integration_name=integration_name)\n \n     for integration_name in config.get('integrations', {}):\n         print(f'Adding: {integration_name}')\n         try:\n             it = get_db_integration(integration_name, None)\n-            if it is None:\n+            if it is None:      # register and setup it only if it doesn't conflict with records in db\n                 add_db_integration(integration_name, config['integrations'][integration_name], None)            # Setup for user `None`, since we don't need this for cloud\n-            if config['integrations'][integration_name].get('publish', False) and not is_cloud:\n-                dbw.setup_integration(integration_name)\n-                dbw.register_predictors(model_data_arr, integration_name=integration_name)\n+                if config['integrations'][integration_name].get('publish', False) and not is_cloud:\n+                    dbw.setup_integration(integration_name)\n+                    dbw.register_predictors(model_data_arr, integration_name=integration_name)\n         except Exception as e:\n             log.error(f'\\n\\nError: {e} adding database integration {integration_name}\\n\\n')\n", "issue": "Mess in integrations setup\nCurrently we have two issues with integrations setup:\r\n1. 'setup' is call for all integrations, regardless 'publish' flag.\r\n2. if integration exists in db and in config file with same name, then only integration from db will be setup. That bad, because any integration from config file will be copied to db right after mindsdb start, and any changes in config file after that will have no effect.\n", "before_files": [{"content": "import atexit\nimport traceback\nimport sys\nimport os\nimport time\nimport asyncio\nimport signal\n\nimport torch.multiprocessing as mp\n\nfrom mindsdb.utilities.config import Config, STOP_THREADS_EVENT\nfrom mindsdb.interfaces.model.model_interface import ray_based, ModelInterface\nfrom mindsdb.api.http.start import start as start_http\nfrom mindsdb.api.mysql.start import start as start_mysql\nfrom mindsdb.api.mongo.start import start as start_mongo\nfrom mindsdb.utilities.ps import is_pid_listen_port, get_child_pids\nfrom mindsdb.utilities.functions import args_parse\nfrom mindsdb.interfaces.database.database import DatabaseWrapper\nfrom mindsdb.utilities.log import log\n\nfrom mindsdb.interfaces.database.integrations import get_db_integrations\n\nCOMPANY_ID = os.environ.get('MINDSDB_COMPANY_ID', None)\n\n\ndef close_api_gracefully(apis):\n    try:\n        for api in apis.values():\n            process = api['process']\n            childs = get_child_pids(process.pid)\n            for p in childs:\n                try:\n                    os.kill(p, signal.SIGTERM)\n                except Exception:\n                    p.kill()\n            sys.stdout.flush()\n            process.terminate()\n            process.join()\n            sys.stdout.flush()\n        if ray_based:\n            os.system('ray stop --force')\n    except KeyboardInterrupt:\n        sys.exit(0)\n\n\nif __name__ == '__main__':\n    mp.freeze_support()\n    args = args_parse()\n    config = Config()\n\n    if args.verbose is True:\n        # Figure this one out later\n        pass\n\n    os.environ['DEFAULT_LOG_LEVEL'] = config['log']['level']['console']\n    os.environ['LIGHTWOOD_LOG_LEVEL'] = config['log']['level']['console']\n\n    # Switch to this once the native interface has it's own thread :/\n    ctx = mp.get_context('spawn')\n\n    from mindsdb.__about__ import __version__ as mindsdb_version\n    print(f'Version {mindsdb_version}')\n\n    print(f'Configuration file:\\n   {config.config_path}')\n    print(f\"Storage path:\\n   {config['paths']['root']}\")\n\n    # @TODO Backwards compatibiltiy for tests, remove later\n    from mindsdb.interfaces.database.integrations import add_db_integration, get_db_integration\n    dbw = DatabaseWrapper(COMPANY_ID)\n    model_interface = ModelInterface()\n    raw_model_data_arr = model_interface.get_models()\n    model_data_arr = []\n    for model in raw_model_data_arr:\n        if model['status'] == 'complete':\n            x = model_interface.get_model_data(model['name'])\n            try:\n                model_data_arr.append(model_interface.get_model_data(model['name']))\n            except Exception:\n                pass\n\n    is_cloud = config.get('cloud', False)\n    if not is_cloud:\n        for integration_name in get_db_integrations(COMPANY_ID, sensitive_info=True):\n            print(f\"Setting up integration: {integration_name}\")\n            dbw.setup_integration(integration_name)\n\n    for integration_name in config.get('integrations', {}):\n        print(f'Adding: {integration_name}')\n        try:\n            it = get_db_integration(integration_name, None)\n            if it is None:\n                add_db_integration(integration_name, config['integrations'][integration_name], None)            # Setup for user `None`, since we don't need this for cloud\n            if config['integrations'][integration_name].get('publish', False) and not is_cloud:\n                dbw.setup_integration(integration_name)\n                dbw.register_predictors(model_data_arr, integration_name=integration_name)\n        except Exception as e:\n            log.error(f'\\n\\nError: {e} adding database integration {integration_name}\\n\\n')\n\n    del model_interface\n    del dbw\n    # @TODO Backwards compatibiltiy for tests, remove later\n\n    if args.api is None:\n        api_arr = ['http', 'mysql']\n    else:\n        api_arr = args.api.split(',')\n\n    apis = {\n        api: {\n            'port': config['api'][api]['port'],\n            'process': None,\n            'started': False\n        } for api in api_arr\n    }\n\n    start_functions = {\n        'http': start_http,\n        'mysql': start_mysql,\n        'mongodb': start_mongo\n    }\n\n    for api_name, api_data in apis.items():\n        if api_data['started']:\n            continue\n        print(f'{api_name} API: starting...')\n        try:\n            if api_name == 'http':\n                p = ctx.Process(target=start_functions[api_name], args=(args.verbose, args.no_studio))\n            else:\n                p = ctx.Process(target=start_functions[api_name], args=(args.verbose,))\n            p.start()\n            api_data['process'] = p\n        except Exception as e:\n            log.error(f'Failed to start {api_name} API with exception {e}\\n{traceback.format_exc()}')\n            close_api_gracefully(apis)\n            raise e\n\n    atexit.register(close_api_gracefully, apis=apis)\n\n    async def wait_api_start(api_name, pid, port):\n        timeout = 60\n        start_time = time.time()\n        started = is_pid_listen_port(pid, port)\n        while (time.time() - start_time) < timeout and started is False:\n            await asyncio.sleep(0.5)\n            started = is_pid_listen_port(pid, port)\n        return api_name, port, started\n\n    async def wait_apis_start():\n        futures = [\n            wait_api_start(api_name, api_data['process'].pid, api_data['port'])\n            for api_name, api_data in apis.items() if 'port' in api_data\n        ]\n        for i, future in enumerate(asyncio.as_completed(futures)):\n            api_name, port, started = await future\n            if started:\n                print(f\"{api_name} API: started on {port}\")\n            else:\n                log.error(f\"ERROR: {api_name} API cant start on {port}\")\n\n    ioloop = asyncio.get_event_loop()\n    ioloop.run_until_complete(wait_apis_start())\n    ioloop.close()\n\n    try:\n        for api_data in apis.values():\n            api_data['process'].join()\n    except KeyboardInterrupt:\n        print('Stopping stream integrations...')\n        STOP_THREADS_EVENT.set()\n        print('Closing app...')\n", "path": "mindsdb/__main__.py"}], "after_files": [{"content": "import atexit\nimport traceback\nimport sys\nimport os\nimport time\nimport asyncio\nimport signal\n\nimport torch.multiprocessing as mp\n\nfrom mindsdb.utilities.config import Config, STOP_THREADS_EVENT\nfrom mindsdb.interfaces.model.model_interface import ray_based, ModelInterface\nfrom mindsdb.api.http.start import start as start_http\nfrom mindsdb.api.mysql.start import start as start_mysql\nfrom mindsdb.api.mongo.start import start as start_mongo\nfrom mindsdb.utilities.ps import is_pid_listen_port, get_child_pids\nfrom mindsdb.utilities.functions import args_parse\nfrom mindsdb.interfaces.database.database import DatabaseWrapper\nfrom mindsdb.utilities.log import log\n\nfrom mindsdb.interfaces.database.integrations import get_db_integrations\n\nCOMPANY_ID = os.environ.get('MINDSDB_COMPANY_ID', None)\n\n\ndef close_api_gracefully(apis):\n    try:\n        for api in apis.values():\n            process = api['process']\n            childs = get_child_pids(process.pid)\n            for p in childs:\n                try:\n                    os.kill(p, signal.SIGTERM)\n                except Exception:\n                    p.kill()\n            sys.stdout.flush()\n            process.terminate()\n            process.join()\n            sys.stdout.flush()\n        if ray_based:\n            os.system('ray stop --force')\n    except KeyboardInterrupt:\n        sys.exit(0)\n\n\nif __name__ == '__main__':\n    mp.freeze_support()\n    args = args_parse()\n    config = Config()\n\n    if args.verbose is True:\n        # Figure this one out later\n        pass\n\n    os.environ['DEFAULT_LOG_LEVEL'] = config['log']['level']['console']\n    os.environ['LIGHTWOOD_LOG_LEVEL'] = config['log']['level']['console']\n\n    # Switch to this once the native interface has it's own thread :/\n    ctx = mp.get_context('spawn')\n\n    from mindsdb.__about__ import __version__ as mindsdb_version\n    print(f'Version {mindsdb_version}')\n\n    print(f'Configuration file:\\n   {config.config_path}')\n    print(f\"Storage path:\\n   {config['paths']['root']}\")\n\n    # @TODO Backwards compatibiltiy for tests, remove later\n    from mindsdb.interfaces.database.integrations import add_db_integration, get_db_integration\n    dbw = DatabaseWrapper(COMPANY_ID)\n    model_interface = ModelInterface()\n    raw_model_data_arr = model_interface.get_models()\n    model_data_arr = []\n    for model in raw_model_data_arr:\n        if model['status'] == 'complete':\n            x = model_interface.get_model_data(model['name'])\n            try:\n                model_data_arr.append(model_interface.get_model_data(model['name']))\n            except Exception:\n                pass\n\n    is_cloud = config.get('cloud', False)\n    if not is_cloud:\n        for integration_name in get_db_integrations(COMPANY_ID, sensitive_info=True):\n            print(f\"Setting up integration: {integration_name}\")\n            if get_db_integration(integration_name, COMPANY_ID)['publish']:\n                # do setup and register only if it is 'publish' integration\n                dbw.setup_integration(integration_name)\n                dbw.register_predictors(model_data_arr, integration_name=integration_name)\n\n    for integration_name in config.get('integrations', {}):\n        print(f'Adding: {integration_name}')\n        try:\n            it = get_db_integration(integration_name, None)\n            if it is None:      # register and setup it only if it doesn't conflict with records in db\n                add_db_integration(integration_name, config['integrations'][integration_name], None)            # Setup for user `None`, since we don't need this for cloud\n                if config['integrations'][integration_name].get('publish', False) and not is_cloud:\n                    dbw.setup_integration(integration_name)\n                    dbw.register_predictors(model_data_arr, integration_name=integration_name)\n        except Exception as e:\n            log.error(f'\\n\\nError: {e} adding database integration {integration_name}\\n\\n')\n\n    del model_interface\n    del dbw\n    # @TODO Backwards compatibiltiy for tests, remove later\n\n    if args.api is None:\n        api_arr = ['http', 'mysql']\n    else:\n        api_arr = args.api.split(',')\n\n    apis = {\n        api: {\n            'port': config['api'][api]['port'],\n            'process': None,\n            'started': False\n        } for api in api_arr\n    }\n\n    start_functions = {\n        'http': start_http,\n        'mysql': start_mysql,\n        'mongodb': start_mongo\n    }\n\n    for api_name, api_data in apis.items():\n        if api_data['started']:\n            continue\n        print(f'{api_name} API: starting...')\n        try:\n            if api_name == 'http':\n                p = ctx.Process(target=start_functions[api_name], args=(args.verbose, args.no_studio))\n            else:\n                p = ctx.Process(target=start_functions[api_name], args=(args.verbose,))\n            p.start()\n            api_data['process'] = p\n        except Exception as e:\n            log.error(f'Failed to start {api_name} API with exception {e}\\n{traceback.format_exc()}')\n            close_api_gracefully(apis)\n            raise e\n\n    atexit.register(close_api_gracefully, apis=apis)\n\n    async def wait_api_start(api_name, pid, port):\n        timeout = 60\n        start_time = time.time()\n        started = is_pid_listen_port(pid, port)\n        while (time.time() - start_time) < timeout and started is False:\n            await asyncio.sleep(0.5)\n            started = is_pid_listen_port(pid, port)\n        return api_name, port, started\n\n    async def wait_apis_start():\n        futures = [\n            wait_api_start(api_name, api_data['process'].pid, api_data['port'])\n            for api_name, api_data in apis.items() if 'port' in api_data\n        ]\n        for i, future in enumerate(asyncio.as_completed(futures)):\n            api_name, port, started = await future\n            if started:\n                print(f\"{api_name} API: started on {port}\")\n            else:\n                log.error(f\"ERROR: {api_name} API cant start on {port}\")\n\n    ioloop = asyncio.get_event_loop()\n    ioloop.run_until_complete(wait_apis_start())\n    ioloop.close()\n\n    try:\n        for api_data in apis.values():\n            api_data['process'].join()\n    except KeyboardInterrupt:\n        print('Stopping stream integrations...')\n        STOP_THREADS_EVENT.set()\n        print('Closing app...')\n", "path": "mindsdb/__main__.py"}]}