]> git.ipfire.org Git - pbs.git/commitdiff
packages: Stream files to any clients now
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 21 Mar 2023 08:29:56 +0000 (08:29 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 21 Mar 2023 08:35:26 +0000 (08:35 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/buildservice/packages.py

index 9a4b84071ead402af0f81fc707e318602801c674..059f9d6ceccb5a06cfa4f07b61bdcb57197371b8 100644 (file)
@@ -647,28 +647,39 @@ class File(base.Object):
 
        # Send Payload
 
-       @property
-       async def payload(self):
+       async def open(self):
                # Open the package
                p = await self.package.open()
 
-               # Create a helper function to read the entire payload
+               # Create a helper function to return a file-like object
                func = lambda: p.read(self.path)
 
                # Read the payload in a separate thread
                return await asyncio.to_thread(func)
 
-       async def sendfile(self, f, chunk_size=102400):
+       async def sendfile(self, dst, chunk_size=8192):
                """
                        Sends the payload of the file into the given file descriptor
                """
-               # XXX This should ideally not load the entire payload into memory at once
+               src = await self.open()
+
+               return await asyncio.to_thread(self._sendfile, src, dst, chunk_size=chunk_size)
+
+       def _sendfile(self, src, dst, chunk_size=8192):
+               while True:
+                       chunk = src.read(chunk_size)
+                       if not chunk:
+                               break
 
-               # Fetch the payload
-               payload = await self.payload
+                       dst.write(chunk)
 
-               # Send the payload in chunks, so that we do not overwhelm Tornado
-               for i in range(0, self.size, chunk_size):
-                       block = payload[i:i+chunk_size]
+       @property
+       async def payload(self):
+               """
+                       Returns the entire payload at once
+               """
+               # Open the file
+               f = await self.open()
 
-                       f.write(block)
+               # Read everything in a separate thread
+               return await asyncio.to_thread(f.readall)