Example #1
0
 /// <summary>
 /// Tidy-up the state after an upload batch has been completed or an
 /// error occured.
 /// </summary>
 private void GoIdle()
 {
     Status = UploadManagerStatus.Idle;
     CommitIDSet.Clear();
     WantedCommitID = 0;
 }
Example #2
0
        /// <summary>
        /// Start a new file transfer batch.
        /// </summary>
        public void StartBatch()
        {
            Debug.Assert(OrderTree.Count > 0);
            Debug.Assert(Status == UploadManagerStatus.Idle);
            Debug.Assert(TransferThread == null);
            Debug.Assert(Ticket != null);

            try
            {
                ulong emailID = 0;

                // Build the payload and the tree.
                KfsPhase1Payload p = new KfsPhase1Payload();
                SortedDictionary<UInt64, KfsUploadBatchFile> tree = new SortedDictionary<UInt64, KfsUploadBatchFile>();

                int i = -1;
                foreach (KfsFileUpload f in OrderTree.Values)
                {
                    Debug.Assert(f.Status == FileTransferStatus.Queued);
                    f.Status = FileTransferStatus.Batched;

                    // Update emailID on first file.
                    // Note: this is not a safe: uploaded files could have bad email IDs
                    // but we didn't care when this was written.
                    if (++i == 0) { emailID = f.EmailID; }

                    // Request creation.
                    if (f.UpdateCommitID == 0)
                    {
                        // Use the tracked inode if it still exists, otherwise use the
                        // last full path.
                        KfsServerObject o = Share.ServerView.GetObjectByInode(f.TrackedInode);
                        if (o == null)
                        {
                            o = Share.ServerView.Root;
                            f.TrackedInode = o.Inode;
                            f.TrackedPath = f.LastFullPath;
                        }

                        Debug.Assert(o is KfsServerDirectory);
                        Debug.Assert(f.TrackedPath != "");
                        p.AddCreateOp(true, o.Inode, o.CommitID, f.TrackedPath);
                    }

                    // Request update.
                    else
                    {
                        Debug.Assert(f.TrackedPath == "");
                        p.AddUpdateOp(f.TrackedInode, f.UpdateCommitID);
                    }

                    tree[f.OrderID] = new KfsUploadBatchFile(f.OrderID, f.UploadPath);
                }

                // Start the transfer.
                TransferThread = new KfsUploadThread(Share, Ticket, emailID, tree, p);
                TransferThread.Start();

                Status = UploadManagerStatus.Batch;
                Ticket = null;
            }

            catch (Exception ex)
            {
                Share.FatalError(ex);
            }
        }
Example #3
0
        /// <summary>
        /// This method is called when a file upload batch has been completed.
        /// 'reason' is null if the thread has been cancelled (on failure).
        /// </summary>
        public void OnBatchCompleted(bool successFlag, Exception expReason, UInt64 commitID)
        {
            // Join with the upload batch thread.
            Debug.Assert(TransferThread != null);
            TransferThread = null;

            // The transfer batch failed.
            if (!successFlag)
            {
                // Cancel the upload of all files and do a full run to clear the
                // uploaded files.
                CancelOnError(expReason);
                Share.Pipeline.Run("file upload batch failed", true);
            }

            // The transfer batch succeeded.
            else
            {
                // We already got the server event. Call the handler function.
                if (CommitIDSet.Contains(commitID))
                    OnCommitIDReceived();

                // We're now waiting for the phase 2 event.
                else
                {
                    Status = UploadManagerStatus.Phase2;
                    WantedCommitID = commitID;
                }
            }

            // Delete the files in the upload directory if all the files have
            // been uploaded.
            if (OrderTree.Count == DoneTree.Count) DeleteUploadedFiles();
        }
Example #4
0
        /// <summary>
        /// This method is called when a upload ticket reply is received.
        /// </summary>
        public void OnTicket(AnpMsg m)
        {
            Debug.Assert(Status == UploadManagerStatus.Ticket);
            Debug.Assert(Ticket == null);

            // Store the ticket and run the pipeline.
            if (m.Type == KAnpType.KANP_RES_KFS_UPLOAD_REQ)
            {
                Status = UploadManagerStatus.Idle;
                Ticket = m.Elements[0].Bin;
                Share.Pipeline.Run("got upload ticket", false);
            }

            // On failure, cancel all uploads.
            else
            {
                CancelOnError(new Exception(m.Elements[0].String));
                Share.Pipeline.Run("could not obtain upload ticket", true);
            }
        }
Example #5
0
 /// <summary>
 /// Ask an upload ticket.
 /// </summary>
 public void AskTicket()
 {
     Debug.Assert(Status == UploadManagerStatus.Idle);
     Debug.Assert(Ticket == null);
     Share.AskUploadTicket();
     Status = UploadManagerStatus.Ticket;
 }