contentmonster/classes/vesselthread.py

76 lines
2.3 KiB
Python

from multiprocessing import Process
from typing import NoReturn, Optional
from classes.vessel import Vessel
from classes.remotefile import RemoteFile
from classes.retry import retry
from classes.database import Database
from const import STATUS_COMPLETE, STATUS_START
import time
class VesselThread(Process):
"""Thread processing uploads to a single vessel
"""
def __init__(self, vessel: Vessel, state: dict) -> None:
"""Initialize a new VesselThread
Args:
vessel (classes.vessel.Vessel): Vessel object to handle uploads for
state (dict): Dictionary containing the current application state
"""
super().__init__()
self.vessel = vessel
self._state = state
def run(self) -> NoReturn:
"""Run thread and process uploads to the vessel
"""
print("Launched Vessel Thread for " + self.vessel.name)
while True:
try:
self.upload()
except Exception as e:
print("An exception occurred in the Vessel Thread for " +
self.vessel.name)
print(repr(e))
@retry()
def upload(self) -> None:
"""Continue uploading process
"""
if not (current := self.vessel.currentUpload() or self.processQueue()):
return
remotefile = RemoteFile(current, self.vessel,
self._state["config"].chunksize)
while True:
status = remotefile.getStatus()
if status == STATUS_COMPLETE:
remotefile.finalizeUpload()
db = Database()
db.logCompletion(current, self.vessel)
return
nextchunk = 0 if status == STATUS_START else status + 1
chunk = remotefile.getChunk(nextchunk)
# If the Chunk has no data, the selected range is beyond the end
# of the file, i.e. the complete file has already been uploaded
if chunk.data:
self.vessel.pushChunk(chunk)
else:
self.vessel.compileComplete(remotefile)
def processQueue(self) -> Optional[str]:
"""Return a file from the processing queue
"""
for f in self._state["files"]:
if not f.uuid in self.vessel._uploaded:
return f