chiark / gitweb /
bundles: Split Uploaded out
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 9 May 2021 23:54:46 +0000 (00:54 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 9 May 2021 23:55:00 +0000 (00:55 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
daemon/cmdlistener.rs
src/bundles.rs

index 231bf66d7487977dc0d265b00dabe69ed10cc36b..e207be3d859ab23bd63b138ec0b70835a66106b1 100644 (file)
@@ -220,7 +220,7 @@ fn execute_and_respond<R,W>(cs: &mut CommandStreamData, cmd: MgmtCommand,
     }
 
     MC::UploadBundle { game, hash, kind } => {
-      let (mut upload, auth) = {
+      let (upload, auth) = {
         let ag = AccountsGuard::lock();
         let gref = Instance::lookup_by_name_unauth(&game)?;
         let bundles = gref.lock_bundles();
@@ -231,12 +231,12 @@ fn execute_and_respond<R,W>(cs: &mut CommandStreamData, cmd: MgmtCommand,
         let upload = bundles.start_upload(ig, kind)?;
         (upload, auth)
       };
-      upload.bulk(&mut bulk_upload)?;
+      let uploaded = upload.bulk(&mut bulk_upload, &hash)?;
       {
         let gref = Instance::lookup_by_name(&game, auth)?;
         let mut bundles = gref.lock_bundles();
         let mut ig = gref.lock()?;
-        bundles.finish_upload(&mut ig, upload, &hash)?;
+        bundles.finish_upload(&mut ig, uploaded)?;
       };
       Fine
     }
index 800bad0431ad468697dadf51a1a2f63d6f36c182..dc40f20f9e3e97729eb682ccdec1a0feafd59d06 100644 (file)
@@ -48,11 +48,17 @@ pub struct Loaded {
 
 /// returned by start_upload
 pub struct Uploading {
-  instance: Arc<InstanceName>,
   id: Id,
+  instance: Arc<InstanceName>,
   file: DigestWrite<BufWriter<fs::File>>,
 }
 
+/// returned by start_upload
+pub struct Uploaded {
+  id: Id,
+  file: fs::File,
+}
+
 #[derive(Debug,Copy,Clone,Error)]
 #[error("{0}")]
 #[repr(transparent)]
@@ -526,26 +532,32 @@ impl InstanceBundles {
 
 impl Uploading {
   #[throws(MgmtError)]
-  pub fn bulk<R>(&mut self, data: &mut R)
+  pub fn bulk<R>(self, data: &mut R, expected: &Hash) -> Uploaded
   where R: Read
   {
-    io::copy(data, &mut self.file)
-      .with_context(|| self.id.path_tmp(&*self.instance))
-      .context("copy").map_err(IE::from)?
+    let Uploading { id, mut file, instance } = self;
+    let tmp = id.path_tmp(&instance);
+
+    io::copy(data, &mut file)
+      .with_context(|| tmp.clone())
+      .context("copy").map_err(IE::from)?;
+
+    let (hash, file) = file.finish();
+
+    let file = file.into_inner().map_err(|e| e.into_error())
+      .with_context(|| tmp.clone()).context("flush").map_err(IE::from)?;
+    if hash.as_slice() != &expected.0[..] { throw!(ME::UploadCorrupted) }
+
+    Uploaded { id, file }
   }
 }
 
 impl InstanceBundles {
   #[throws(MgmtError)]
   pub fn finish_upload(&mut self, ig: &mut Instance,
-                       Uploading { instance:_, id, file }: Uploading,
-                       expected: &Hash) {
-    let (hash, file) = file.finish();
+                       Uploaded { id, mut file }: Uploaded) {
     let tmp = id.path_tmp(&ig.name);
     let install = id.path_(&ig.name);
-    let mut file = file.into_inner().map_err(|e| e.into_error())
-      .with_context(|| tmp.clone()).context("flush").map_err(IE::from)?;
-    if hash.as_slice() != &expected.0[..] { throw!(ME::UploadCorrupted) }
 
     file.rewind().context("rewind"). map_err(IE::from)?;
     let mut file = BufReader::new(file);