Repository: Cog-Creators/Red-DiscordBot

Issue:
[Downloader] Downloader unloads on bot restart.
# Other bugs

<!-- 
Did you find a bug with something other than a command? Fill out the following:
-->

#### What were you trying to do?

I wanted to update my cogs by running ``[p]cog update``

#### What were you expecting to happen?

My cogs to update

#### What actually happened?

Nothing, because downloader was unloaded. I did some troubleshooting and noticed that this happens at every restart.

#### How can we reproduce this issue?

1. Load downloader
2. Install a 3rd party cog
3. Restart server/machine (Bot as systemd service active)
4. Try to update cog



Discussion:
I can't seem to reproduce this. If you could start your bot and look through the logs above where the logo is, there might be an error message there. When the bot encounters an error loading a cog on startup, it is automatically unloaded. That is what I suspect to be happening (for some reason).
Can't seem to reproduce this issue either.
Logs show nothing. Possibly after update? I actually can't reproduce it anymore myself.
It's like just the action of opening an issue on GitHub will solve all of my problems. (Stupid thing literally unloaded 3 times on two different bots before... oh well.)
I found the issue! It unloads on server/system reboot, not on bot restart. The restart on itself is fine but as soon as I reboot the entire machine the bot runs on, downloader gets unloaded.

I'll update the issue description with the new steps to reproduce
What OS, Arch, Version? Are you using the service file as written in the guide (with python or with redbot?)? Have you looked in the journalctl to see if anything is printed? It would be before the RedBot text box.
Ubuntu18.04.3 LTS
Service file with python, not the redbot entrypoint.
No logs (journalctl as expected just displays the redbot textbox)
Just tried it on a new droplet, didn't happen to me. Tried a reboot with `shutdown -r now` as well as flipping the On/Off switch in DO's panel (this one cause uvloop to error). Each time the bot started up with the same 3 cogs I had loaded before (downloader, rolemanagement, retrigger)
I really can't explain it. I have 3 bits on that machine all in seperate venvs and they all show the same behaviour.
@Dav-Git Can you please try to set your service file to start the bot with the `--debug` flag to  generate more detailed bugging log.

Please get full logs from first bootup to restart and running `[p]cogs` 

In adition to this whos your host?

(Note `--debug` should be on for all the time while you are reproducing this issue)
Also can you post `[p]debuginfo` for all the bots.
And a screenshot of `[p]cogs` please 


#### This is a mixture of the logs of all 3 instances I'll see if I can untangle them in a minute.
![grafik](https://user-images.githubusercontent.com/57032623/73064716-22f00200-3ea2-11ea-9d14-7dedd6bf2a7b.png)
![grafik](https://user-images.githubusercontent.com/57032623/73065802-be827200-3ea4-11ea-9d7f-0bce79ab2639.png)
![grafik](https://user-images.githubusercontent.com/57032623/73064753-369b6880-3ea2-11ea-8a25-5a6d80ee1f1f.png)
![grafik](https://user-images.githubusercontent.com/57032623/73064821-56cb2780-3ea2-11ea-9294-b9831e597ab4.png)

#### Output of ``[p]cogs`` per instance after reboot (I realized I should've probably done a [p] cogs before reboot too. But you can trust me downloader was loaded)

![grafik](https://user-images.githubusercontent.com/57032623/73064874-7c583100-3ea2-11ea-9489-2c431f35d499.png)
![grafik](https://user-images.githubusercontent.com/57032623/73064886-82e6a880-3ea2-11ea-9dae-8ef08d337aa0.png)
![grafik](https://user-images.githubusercontent.com/57032623/73064961-a90c4880-3ea2-11ea-8a58-70f932434391.png)

#### And here is ``[p]debuginfo``

![grafik](https://user-images.githubusercontent.com/57032623/73065076-f7214c00-3ea2-11ea-84e6-506c20320895.png)
![grafik](https://user-images.githubusercontent.com/57032623/73065099-01dbe100-3ea3-11ea-830a-b8e01d94a129.png)
![grafik](https://user-images.githubusercontent.com/57032623/73065128-0f916680-3ea3-11ea-863a-8ab7e60c2848.png)

There's a section of the logs missing between the first and second screenshot 
ah crap i thought the 545 and 546 were the same. Standby i'll edit the comment

Every line between the first line containing `===Basic Congig===` and `Invite URL`  as that will be the part that shows if something is happening
They are all there now
Awesome have a feeling narrowed down the issue happening here, i'll leave it to Jack to confirm though
Just the actual error for easy readability
![grafik](https://user-images.githubusercontent.com/57032623/73066699-fdb1c280-3ea6-11ea-9aca-f1817566b8f9.png)



Resolving patch:
diff --git a/redbot/cogs/downloader/__init__.py b/redbot/cogs/downloader/__init__.py
--- a/redbot/cogs/downloader/__init__.py
+++ b/redbot/cogs/downloader/__init__.py
@@ -3,5 +3,5 @@
 
 async def setup(bot):
     cog = Downloader(bot)
-    await cog.initialize()
     bot.add_cog(cog)
+    cog.create_init_task()
diff --git a/redbot/cogs/downloader/downloader.py b/redbot/cogs/downloader/downloader.py
--- a/redbot/cogs/downloader/downloader.py
+++ b/redbot/cogs/downloader/downloader.py
@@ -53,6 +53,8 @@ def __init__(self, bot: Red):
         self._create_lib_folder()
 
         self._repo_manager = RepoManager()
+        self._ready = asyncio.Event()
+        self._init_task = None
 
     def _create_lib_folder(self, *, remove_first: bool = False) -> None:
         if remove_first:
@@ -62,9 +64,21 @@ def _create_lib_folder(self, *, remove_first: bool = False) -> None:
             with self.SHAREDLIB_INIT.open(mode="w", encoding="utf-8") as _:
                 pass
 
+    async def cog_before_invoke(self, ctx: commands.Context) -> None:
+        async with ctx.typing():
+            await self._ready.wait()
+
+    def cog_unload(self):
+        if self._init_task is not None:
+            self._init_task.cancel()
+
+    def create_init_task(self):
+        self._init_task = asyncio.create_task(self.initialize())
+
     async def initialize(self) -> None:
         await self._repo_manager.initialize()
         await self._maybe_update_config()
+        self._ready.set()
 
     async def _maybe_update_config(self) -> None:
         schema_version = await self.conf.schema_version()


Test patch: