Subtask scheduling management

v4
laoyuyu 2 years ago
parent 344cbd2d99
commit 69f10d68d1
  1. 5
      Http/src/main/java/com/arialyy/aria/http/download/HttpDStopController.kt
  2. 5
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpDGOptionAdapter.kt
  3. 17
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpDGStartController.kt
  4. 2
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpDGSubTaskInterceptor.kt
  5. 28
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpDGTaskManager.kt
  6. 2
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpDGroupAdapter.kt
  7. 5
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpDGroupTask.java
  8. 75
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpSubBlockManager.kt
  9. 3
      PublicComponent/src/main/java/com/arialyy/aria/core/inf/ITaskAdapter.java
  10. 2
      PublicComponent/src/main/java/com/arialyy/aria/core/task/AbsTask.java
  11. 6
      PublicComponent/src/main/java/com/arialyy/aria/core/task/AbsTaskAdapter.kt

@ -15,14 +15,9 @@
*/ */
package com.arialyy.aria.http.download package com.arialyy.aria.http.download
import android.net.Uri
import com.arialyy.aria.core.DuaContext
import com.arialyy.aria.core.command.CancelCmd import com.arialyy.aria.core.command.CancelCmd
import com.arialyy.aria.core.command.StopCmd import com.arialyy.aria.core.command.StopCmd
import com.arialyy.aria.core.task.TaskCachePool import com.arialyy.aria.core.task.TaskCachePool
import com.arialyy.aria.util.FileUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import timber.log.Timber import timber.log.Timber
/** /**

@ -26,4 +26,9 @@ internal class HttpDGOptionAdapter : IHttpTaskOptionAdapter {
val subUrlList = mutableSetOf<String>() val subUrlList = mutableSetOf<String>()
val subNameList = mutableListOf<String>() val subNameList = mutableListOf<String>()
/**
* Number of subtasks executed simultaneously
*/
var subTaskNum = 2
} }

@ -51,6 +51,23 @@ class HttpDGStartController(target: Any, val savePath: Uri) : HttpBaseStartContr
return super.setHttpOption(httpOption) as HttpDGStartController return super.setHttpOption(httpOption) as HttpDGStartController
} }
/**
* Number of subtasks executed simultaneously
* @param num max 16
*/
fun setSubTaskNum(num: Int): HttpDGStartController {
if (num < 1) {
Timber.e("Quantity less than 1")
return this
}
if (num > 16) {
Timber.e("Quantity greater than 16")
return this
}
optionAdapter.subTaskNum = num
return this
}
/** /**
* add sub task download uri * add sub task download uri
*/ */

@ -72,7 +72,7 @@ internal class HttpDGSubTaskInterceptor : ITaskInterceptor {
tp.eventListener = HttpSubListener() tp.eventListener = HttpSubListener()
val subTask = SingleDownloadTask(tp) val subTask = SingleDownloadTask(tp)
val subAdapter = HttpDTaskAdapter(true) val subAdapter = HttpDTaskAdapter(true)
subAdapter.setBlockManager(HttpSubBlockManager(chain.blockManager.handler)) subAdapter.setBlockManager(HttpSubBlockManager(subTask, chain.blockManager.handler))
subTask.adapter = subAdapter subTask.adapter = subAdapter
if (it.isComplete && checkTaskIsComplete(it)) { if (it.isComplete && checkTaskIsComplete(it)) {
(chain.getTask() as HttpDGroupTask).addIncompleteTaskList(subTask) (chain.getTask() as HttpDGroupTask).addIncompleteTaskList(subTask)

@ -19,6 +19,14 @@ import android.os.Handler
import android.os.Looper import android.os.Looper
import com.arialyy.aria.core.inf.IBlockManager import com.arialyy.aria.core.inf.IBlockManager
import com.arialyy.aria.core.inf.ITaskManager import com.arialyy.aria.core.inf.ITaskManager
import com.arialyy.aria.http.download.HttpDTaskAdapter
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit.MILLISECONDS
/** /**
* @Author laoyuyu * @Author laoyuyu
@ -28,6 +36,14 @@ import com.arialyy.aria.core.inf.ITaskManager
internal class HttpDGTaskManager(val task: HttpDGroupTask) : ITaskManager, IBlockManager { internal class HttpDGTaskManager(val task: HttpDGroupTask) : ITaskManager, IBlockManager {
private lateinit var looper: Looper private lateinit var looper: Looper
private lateinit var handler: Handler private lateinit var handler: Handler
private val subTaskNum = task.dgOptionAdapter.subTaskNum
private val threadPool = ThreadPoolExecutor(
subTaskNum, subTaskNum,
0L, MILLISECONDS,
LinkedBlockingQueue(),
)
private val dispatcher = threadPool.asCoroutineDispatcher()
private val scope = MainScope()
private val callback = Handler.Callback { msg -> private val callback = Handler.Callback { msg ->
when (msg.what) { when (msg.what) {
@ -57,10 +73,20 @@ internal class HttpDGTaskManager(val task: HttpDGroupTask) : ITaskManager, IBloc
override fun start() { override fun start() {
task.incompleteTaskList.forEach { task.incompleteTaskList.forEach {
scope.launch(dispatcher) {
val adapter = HttpDTaskAdapter(true)
adapter.init(it)
adapter.start()
}
} }
} }
private fun quitLooper() {
looper.quit()
handler.removeCallbacksAndMessages(null)
scope.cancel()
}
override fun stop() { override fun stop() {
} }

@ -35,7 +35,7 @@ import timber.log.Timber
**/ **/
internal class HttpDGroupAdapter : AbsTaskAdapter() { internal class HttpDGroupAdapter : AbsTaskAdapter() {
private val taskManager by lazy { private val taskManager by lazy {
val manager = HttpDGTaskManager(getTask()) val manager = HttpDGTaskManager(getTask() as HttpDGroupTask)
ThreadTaskManager2.putTaskManager(getTask().taskId, manager) ThreadTaskManager2.putTaskManager(getTask().taskId, manager)
manager manager
} }

@ -19,6 +19,7 @@ import com.arialyy.aria.core.common.TaskOption;
import com.arialyy.aria.core.inf.ITaskOption; import com.arialyy.aria.core.inf.ITaskOption;
import com.arialyy.aria.core.task.AbsTask; import com.arialyy.aria.core.task.AbsTask;
import com.arialyy.aria.core.task.SingleDownloadTask; import com.arialyy.aria.core.task.SingleDownloadTask;
import com.arialyy.aria.http.HttpTaskOption;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -37,6 +38,10 @@ public class HttpDGroupTask extends AbsTask {
super(taskOption); super(taskOption);
} }
public HttpDGOptionAdapter getDGOptionAdapter() {
return getTaskOption(HttpTaskOption.class).getOptionAdapter(HttpDGOptionAdapter.class);
}
void setIncompleteTaskList(List<SingleDownloadTask> list) { void setIncompleteTaskList(List<SingleDownloadTask> list) {
incompleteTaskList.clear(); incompleteTaskList.clear();
incompleteTaskList.addAll(list); incompleteTaskList.addAll(list);

@ -16,37 +16,84 @@
package com.arialyy.dua.group package com.arialyy.dua.group
import android.os.Handler import android.os.Handler
import android.os.Looper
import com.arialyy.aria.core.inf.IBlockManager import com.arialyy.aria.core.inf.IBlockManager
import com.arialyy.aria.core.task.IThreadTask import com.arialyy.aria.core.inf.ITaskManager
import com.arialyy.aria.orm.entity.BlockRecord import com.arialyy.aria.core.task.ITask
import com.arialyy.aria.http.HttpTaskOption
import com.arialyy.aria.http.download.HttpDOptionAdapter
import timber.log.Timber
/** /**
* @Author laoyuyu * @Author laoyuyu
* @Description * @Description
* @Date 10:04 2023/3/12 * @Date 10:04 2023/3/12
**/ **/
class HttpSubBlockManager(val handler: Handler) : IBlockManager { internal class HttpSubBlockManager(private val task: ITask, private val groupHandler: Handler) :
private val unfinishedBlock = mutableListOf<BlockRecord>() IBlockManager {
private var blockNum: Int = 1 private lateinit var looper: Looper
private lateinit var handler: Handler
override fun putUnfinishedBlock(record: BlockRecord) { private var isStop = false
unfinishedBlock.add(record) private var isCancel = false
}
override fun getUnfinishedBlockList(): List<BlockRecord> { /**
return unfinishedBlock * Pass the message to the group task after the subtask is stopped
*/
private val callback = Handler.Callback { msg ->
when (msg.what) {
ITaskManager.STATE_STOP -> {
isStop = true
}
ITaskManager.STATE_CANCEL -> {
isCancel = true
}
ITaskManager.STATE_FAIL -> {
}
ITaskManager.STATE_COMPLETE -> {
}
ITaskManager.STATE_RUNNING -> {
}
ITaskManager.STATE_UPDATE_PROGRESS -> {
}
}
false
} }
override fun getHandler() = handler override fun getHandler() = handler
override fun start(threadTaskList: List<IThreadTask>) { /**
threadTaskList.forEach { tt -> * 1.Shared thread pool for subtasks [HttpDGTaskManager.dispatcher]
tt.run() * 2.Subtasks support only single block downloads
*/
override fun start() {
if (Looper.myLooper() == Looper.getMainLooper()) {
throw IllegalThreadStateException("io operations cannot be in the main thread")
} }
looper = Looper.myLooper()!!
handler = Handler(looper, callback)
// Synchronized sequential execution of all block
task.getTaskOption(HttpTaskOption::class.java)
.getOptionAdapter(HttpDOptionAdapter::class.java).threadList.forEach { tt ->
if (isStop) {
Timber.d("task stopped")
return
}
if (isCancel) {
Timber.d("task canceled")
return
}
tt.run()
}
}
private fun quitLooper() {
looper.quit()
handler.removeCallbacksAndMessages(null)
} }
override fun setBlockNum(blockNum: Int) { override fun setBlockNum(blockNum: Int) {
this.blockNum = blockNum Timber.i("Subtasks do not support chunked downloads")
} }
} }

@ -16,7 +16,6 @@
package com.arialyy.aria.core.inf; package com.arialyy.aria.core.inf;
import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.core.task.ITask; import com.arialyy.aria.core.task.ITask;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -26,7 +25,7 @@ import org.jetbrains.annotations.NotNull;
*/ */
public interface ITaskAdapter { public interface ITaskAdapter {
void init(@NotNull ITask task, @NotNull IEventListener listener); void init(@NotNull ITask task);
/** /**
* 任务是否正在执行 * 任务是否正在执行

@ -47,7 +47,7 @@ public abstract class AbsTask implements ITask {
public void setAdapter(ITaskAdapter adapter) { public void setAdapter(ITaskAdapter adapter) {
mAdapter = adapter; mAdapter = adapter;
mAdapter.init(this, mTaskOption.eventListener); mAdapter.init(this);
} }
@Override public ITaskAdapter getAdapter() { @Override public ITaskAdapter getAdapter() {

@ -17,8 +17,6 @@ package com.arialyy.aria.core.task
import com.arialyy.aria.core.inf.IBlockManager import com.arialyy.aria.core.inf.IBlockManager
import com.arialyy.aria.core.inf.ITaskAdapter import com.arialyy.aria.core.inf.ITaskAdapter
import com.arialyy.aria.core.inf.ITaskManager
import com.arialyy.aria.core.listener.IEventListener
import com.arialyy.aria.core.task.ITaskInterceptor.IChain import com.arialyy.aria.core.task.ITaskInterceptor.IChain
/** /**
@ -28,14 +26,12 @@ import com.arialyy.aria.core.task.ITaskInterceptor.IChain
**/ **/
abstract class AbsTaskAdapter : ITaskAdapter { abstract class AbsTaskAdapter : ITaskAdapter {
private lateinit var mTask: ITask private lateinit var mTask: ITask
private lateinit var mEventListener: IEventListener
private val mUserInterceptor = mutableListOf<ITaskInterceptor>() private val mUserInterceptor = mutableListOf<ITaskInterceptor>()
private val mCoreInterceptor = mutableListOf<ITaskInterceptor>() private val mCoreInterceptor = mutableListOf<ITaskInterceptor>()
override fun init(task: ITask, listener: IEventListener) { override fun init(task: ITask) {
mTask = task mTask = task
mEventListener = listener
} }
fun getTask() = mTask fun getTask() = mTask

Loading…
Cancel
Save