1 // Copyright (C) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 use std::ops::Deref; 15 use std::sync::atomic::AtomicBool; 16 use std::sync::Arc; 17 18 use crate::manage::events::{TaskEvent, TaskManagerEvent}; 19 use crate::manage::notifier::Notifier; 20 use crate::manage::scheduler::queue::keeper::SAKeeper; 21 use crate::manage::task_manager::TaskManagerTx; 22 use crate::task::config::Action; 23 use crate::task::download::download; 24 use crate::task::reason::Reason; 25 use crate::task::request_task::RequestTask; 26 use crate::task::upload::upload; 27 28 pub(crate) struct RunningTask { 29 task: Arc<RequestTask>, 30 tx: TaskManagerTx, 31 // `_keeper` is never used when executing the task. 32 _keeper: SAKeeper, 33 } 34 35 impl RunningTask { new(task: Arc<RequestTask>, tx: TaskManagerTx, keeper: SAKeeper) -> Self36 pub(crate) fn new(task: Arc<RequestTask>, tx: TaskManagerTx, keeper: SAKeeper) -> Self { 37 Self { 38 task, 39 tx, 40 _keeper: keeper, 41 } 42 } 43 run(self, abort_flag: Arc<AtomicBool>)44 pub(crate) async fn run(self, abort_flag: Arc<AtomicBool>) { 45 match self.conf.common_data.action { 46 Action::Download => { 47 download(self.task.clone(), abort_flag).await; 48 } 49 Action::Upload => { 50 upload(self.task.clone(), abort_flag).await; 51 } 52 _ => {} 53 } 54 } 55 } 56 57 impl Deref for RunningTask { 58 type Target = Arc<RequestTask>; 59 deref(&self) -> &Self::Target60 fn deref(&self) -> &Self::Target { 61 &self.task 62 } 63 } 64 65 impl Drop for RunningTask { drop(&mut self)66 fn drop(&mut self) { 67 self.task.update_progress_in_database(); 68 self.task.background_notify(); 69 Notifier::progress(&self.client_manager, self.build_notify_data()); 70 match *self.task.running_result.lock().unwrap() { 71 Some(res) => match res { 72 Ok(()) => { 73 self.tx 74 .send_event(TaskManagerEvent::Task(TaskEvent::Completed( 75 self.task_id(), 76 self.uid(), 77 self.mode(), 78 ))); 79 } 80 Err(e) if e == Reason::NetworkOffline => { 81 self.tx 82 .send_event(TaskManagerEvent::Task(TaskEvent::Offline( 83 self.task_id(), 84 self.uid(), 85 self.mode(), 86 ))); 87 } 88 Err(e) => { 89 self.tx.send_event(TaskManagerEvent::Task(TaskEvent::Failed( 90 self.task_id(), 91 self.uid(), 92 e, 93 self.mode(), 94 ))); 95 } 96 }, 97 None => { 98 self.tx 99 .send_event(TaskManagerEvent::Task(TaskEvent::Running( 100 self.task_id(), 101 self.uid(), 102 self.mode(), 103 ))); 104 } 105 } 106 } 107 } 108