mirror of
https://github.com/square/okhttp.git
synced 2026-01-14 07:22:20 +03:00
TaskRunner, an abstraction over ExecutorService
I want to tighten up our executors for a few reasons - Fix daemon vs. non-daemon problems - Fix code unloading problems - Be able to wait for async work to complete in tearDown() - Fewer threads for pongs, acks, and window updates This shouldn't be too much to layer on top of ExecutorService, but it is not easy to do with those APIs alone. The underlying motivation is to make scheduling work easier in Http2Connection, which will help with differentiating between dead streams and dead connections. https://github.com/square/okhttp/issues/3146
This commit is contained in:
53
okhttp/src/main/java/okhttp3/internal/concurrent/Task.kt
Normal file
53
okhttp/src/main/java/okhttp3/internal/concurrent/Task.kt
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Square, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package okhttp3.internal.concurrent
|
||||
|
||||
/**
|
||||
* A unit of work that can be executed one or more times.
|
||||
*
|
||||
* Cancellation
|
||||
* ------------
|
||||
*
|
||||
* Tasks control their cancellation. If the hosting queue is canceled, the [Task.tryCancel] function
|
||||
* returns true if the task should skip the next-scheduled execution. Note that canceling a task is
|
||||
* not permanent; it is okay to schedule a task after it has been canceled.
|
||||
*
|
||||
* Recurrence
|
||||
* ----------
|
||||
*
|
||||
* Tasks control their recurrence schedule. The [runOnce] function returns -1L to signify that the
|
||||
* task should not be executed again. Otherwise it returns a delay until the next execution.
|
||||
*
|
||||
* A task has at most one next execution. If the same task instance is scheduled multiple times, the
|
||||
* earliest one wins. This applies to both executions scheduled with [TaskRunner.Queue.schedule] and
|
||||
* those implied by the returned execution delay.
|
||||
*
|
||||
* Task Queues
|
||||
* -----------
|
||||
*
|
||||
* Tasks are bound to the [TaskQueue] they are scheduled in. Each queue is sequential and the tasks
|
||||
* within it never execute concurrently. It is an error to use a task in multiple queues.
|
||||
*/
|
||||
abstract class Task(
|
||||
val name: String,
|
||||
val daemon: Boolean = true
|
||||
) {
|
||||
/** Returns the delay in nanoseconds until the next execution, or -1L to not reschedule. */
|
||||
abstract fun runOnce(): Long
|
||||
|
||||
/** Return true to skip the scheduled execution. */
|
||||
open fun tryCancel(): Boolean = false
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Square, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package okhttp3.internal.concurrent
|
||||
|
||||
/**
|
||||
* A set of tasks that are executed in sequential order.
|
||||
*
|
||||
* Work within queues is not concurrent. This is equivalent to each queue having a dedicated thread
|
||||
* for its work; in practice a set of queues may share a set of threads to save resources.
|
||||
*/
|
||||
interface TaskQueue {
|
||||
/**
|
||||
* An application-level object like a connection pool or HTTP call that this queue works on behalf
|
||||
* of. This is intended to be useful for testing and debugging only.
|
||||
*/
|
||||
val owner: Any
|
||||
|
||||
/** Returns a snapshot of tasks currently scheduled for execution. */
|
||||
val scheduledTasks: List<Task>
|
||||
|
||||
/**
|
||||
* Schedules [task] for execution in [delayNanos]. A task may only have one future execution
|
||||
* scheduled. If the task is already in the queue, the earliest execution time is used.
|
||||
*
|
||||
* The target execution time is implemented on a best-effort basis. If another task in this queue
|
||||
* is running when that time is reached, that task is allowed to complete before this task is
|
||||
* started. Similarly the task will be delayed if the host lacks compute resources.
|
||||
*/
|
||||
fun schedule(task: Task, delayNanos: Long = 0L)
|
||||
|
||||
/**
|
||||
* Schedules immediate execution of [Task.tryCancel] on all currently-enqueued tasks. These calls
|
||||
* will not be made until any currently-executing task has completed. Tasks that return true will
|
||||
* be removed from the execution schedule.
|
||||
*/
|
||||
fun cancelAll()
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Square, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package okhttp3.internal.concurrent
|
||||
|
||||
/**
|
||||
* A set of worker threads that are shared among a set of task queues.
|
||||
*
|
||||
* The task runner is responsible for managing non-daemon threads. It keeps the process alive while
|
||||
* user-visible (ie. non-daemon) tasks are scheduled, and allows the process to exit when only
|
||||
* housekeeping (ie. daemon) tasks are scheduled.
|
||||
*
|
||||
* The task runner is also responsible for releasing held threads when the library is unloaded.
|
||||
* This is for the benefit of container environments that implement code unloading.
|
||||
*
|
||||
* Most applications should share a process-wide [TaskRunner] and use queues for per-client work.
|
||||
*/
|
||||
interface TaskRunner {
|
||||
fun newQueue(owner: Any): TaskQueue
|
||||
|
||||
/**
|
||||
* Returns a snapshot of queues that currently have tasks scheduled. The task runner does not
|
||||
* necessarily track queues that have no tasks scheduled.
|
||||
*/
|
||||
fun activeQueues(): List<TaskQueue>
|
||||
}
|
||||
Reference in New Issue
Block a user