contentmonster/classes/vesselthread.py

77 lines
2.3 KiB
Python
Raw Normal View History

2021-11-20 14:40:07 +00:00
from multiprocessing import Process
2021-11-25 18:03:58 +00:00
from typing import NoReturn, Optional
2021-11-20 14:40:07 +00:00
2021-11-25 15:31:49 +00:00
from classes.vessel import Vessel
2021-11-25 18:03:58 +00:00
from classes.remotefile import RemoteFile
from classes.retry import retry
from classes.database import Database
from const import STATUS_COMPLETE, STATUS_START
2021-11-25 15:31:49 +00:00
2021-11-22 10:14:38 +00:00
import time
2021-11-25 16:09:40 +00:00
2021-11-20 14:40:07 +00:00
class VesselThread(Process):
2021-11-25 15:31:49 +00:00
"""Thread processing uploads to a single vessel
"""
2021-11-25 16:09:40 +00:00
def __init__(self, vessel: Vessel, state: dict) -> None:
2021-11-25 15:31:49 +00:00
"""Initialize a new VesselThread
Args:
vessel (classes.vessel.Vessel): Vessel object to handle uploads for
state (dict): Dictionary containing the current application state
"""
2021-11-20 14:40:07 +00:00
super().__init__()
self.vessel = vessel
2021-11-25 15:31:49 +00:00
self._state = state
2021-11-20 14:40:07 +00:00
def run(self) -> NoReturn:
2021-11-25 15:31:49 +00:00
"""Run thread and process uploads to the vessel
"""
2021-11-22 10:14:38 +00:00
print("Launched Vessel Thread for " + self.vessel.name)
while True:
try:
2021-11-25 16:21:04 +00:00
self.upload()
2021-11-25 16:09:40 +00:00
except Exception as e:
print("An exception occurred in the Vessel Thread for " +
self.vessel.name)
print(repr(e))
2021-11-25 18:03:58 +00:00
@retry()
2021-11-25 16:21:04 +00:00
def upload(self) -> None:
"""Continue uploading process
"""
2021-11-25 18:03:58 +00:00
if not (current := self.vessel.currentUpload() or self.processQueue()):
2021-11-25 16:21:04 +00:00
return
2021-11-25 18:03:58 +00:00
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
2021-11-25 16:21:04 +00:00
"""
2021-11-25 16:09:40 +00:00
for f in self._state["files"]:
if not f.uuid in self.vessel._uploaded:
2021-11-25 18:03:58 +00:00
return f