-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create new version of RuntimeScheduler #40944
Conversation
This pull request was exported from Phabricator. Differential Revision: D49316881 |
Base commit: c9d0a00 |
This pull request was exported from Phabricator. Differential Revision: D49316881 |
Summary: Pull Request resolved: facebook#40944 ## Summary This creates a new version of `RuntimeScheduler` that's intended to be backwards compatible but with a few notable changes: 1. `scheduleTask` is now thread-safe. 2. `scheduleWork` is now just an alias of `scheduleTask` with immediate priority (to preserve the yielding semantics it had over other tasks). 3. Yielding mechanism has changed, to make lower priority tasks to yield to higher priority tasks, instead of just yielding to `scheduleWork` and `executeNowOnTheSameThread`. We don't expect this to have any impact in performance or user perceivable behavior, so we consider it a short-lived refactor. When we validate this assumptions in a complex application we'll delete the old version and only keep the fork. ## Motivation The main motivation for this refactor is to reduce the amount of unnecessary interruptions of running tasks (via `shouldYield`) that are only used to schedule asynchronous tasks from native. The `scheduleWork` method is the only available mechanism exposed to native APIs to schedule work in the JS thread (as the existing version of `scheduleTask` is only meant to be called from JS). This mechanism **always** asks for any running tasks in the scheduler to yield, so these tasks are always considered to have the highest priority. This makes sense for discrete user events, but not for many other use cases coming from native (e.g.: notifying network responses could be UserBlocking, Normal or Low depending on the use case). We need a way to schedule tasks from native with other kinds of priorities, so we don't always have to interrupt what's currently executing if it has a higher priority than what we're scheduling. ## Changes **General APIs:** This centralizes scheduling in only 2 APIs in `RuntimeScheduler` (which already exist in the legacy version): * `scheduleTask`, which is non-blocking for the caller and can be used from any thread. This always uses the task queue in the scheduler and a new yielding mechanism. * `executeNowOnTheSameThread`, which is blocking for the caller and asks any task executing in the scheduler to yield. These tasks don't go through the task queue and instead queue through the existing synchronization mechanism in `RuntimeExecutor`. The yielding mechanism for these tasks is preserved. `scheduleWork` will be deprecated and it's just an alias for `scheduleTask` with an immediate priority (to preserve a similar behavior). **Yielding behavior:** Before, tasks would only yield to tasks scheduled via `scheduleWork` and `executeNowOnTheSameThread` (those tasks didn't go through the task queue). With this implementation, tasks would now yield to any task that has a higher position in the task queue. That means we reuse the existing mechanism to avoid lower priority tasks to never execute because higher priority tasks never stop coming. All tasks would yield to requests for synchronous access (via `executeNowOnTheSameThread`) as did the current implementation. Changelog: [internal] Differential Revision: D49316881 fbshipit-source-id: 5e8f1563b7d1c34641c83667ac2b381ae4d8938c
eb79820
to
f7b5a4d
Compare
This pull request was exported from Phabricator. Differential Revision: D49316881 |
Summary: Pull Request resolved: facebook#40944 ## Summary This creates a new version of `RuntimeScheduler` that's intended to be backwards compatible but with a few notable changes: 1. `scheduleTask` is now thread-safe. 2. `scheduleWork` is now just an alias of `scheduleTask` with immediate priority (to preserve the yielding semantics it had over other tasks). 3. Yielding mechanism has changed, to make lower priority tasks to yield to higher priority tasks, instead of just yielding to `scheduleWork` and `executeNowOnTheSameThread`. We don't expect this to have any impact in performance or user perceivable behavior, so we consider it a short-lived refactor. When we validate this assumptions in a complex application we'll delete the old version and only keep the fork. ## Motivation The main motivation for this refactor is to reduce the amount of unnecessary interruptions of running tasks (via `shouldYield`) that are only used to schedule asynchronous tasks from native. The `scheduleWork` method is the only available mechanism exposed to native APIs to schedule work in the JS thread (as the existing version of `scheduleTask` is only meant to be called from JS). This mechanism **always** asks for any running tasks in the scheduler to yield, so these tasks are always considered to have the highest priority. This makes sense for discrete user events, but not for many other use cases coming from native (e.g.: notifying network responses could be UserBlocking, Normal or Low depending on the use case). We need a way to schedule tasks from native with other kinds of priorities, so we don't always have to interrupt what's currently executing if it has a higher priority than what we're scheduling. ## Changes **General APIs:** This centralizes scheduling in only 2 APIs in `RuntimeScheduler` (which already exist in the legacy version): * `scheduleTask`, which is non-blocking for the caller and can be used from any thread. This always uses the task queue in the scheduler and a new yielding mechanism. * `executeNowOnTheSameThread`, which is blocking for the caller and asks any task executing in the scheduler to yield. These tasks don't go through the task queue and instead queue through the existing synchronization mechanism in `RuntimeExecutor`. The yielding mechanism for these tasks is preserved. `scheduleWork` will be deprecated and it's just an alias for `scheduleTask` with an immediate priority (to preserve a similar behavior). **Yielding behavior:** Before, tasks would only yield to tasks scheduled via `scheduleWork` and `executeNowOnTheSameThread` (those tasks didn't go through the task queue). With this implementation, tasks would now yield to any task that has a higher position in the task queue. That means we reuse the existing mechanism to avoid lower priority tasks to never execute because higher priority tasks never stop coming. All tasks would yield to requests for synchronous access (via `executeNowOnTheSameThread`) as did the current implementation. Changelog: [internal] Differential Revision: D49316881 fbshipit-source-id: bb101d733b831a408ac2e2486e631a65c0e5dfba
f7b5a4d
to
7185cc4
Compare
This pull request was exported from Phabricator. Differential Revision: D49316881 |
7185cc4
to
6f8fe29
Compare
Summary: Pull Request resolved: facebook#40944 ## Summary This creates a new version of `RuntimeScheduler` that's intended to be backwards compatible but with a few notable changes: 1. `scheduleTask` is now thread-safe. 2. `scheduleWork` is now just an alias of `scheduleTask` with immediate priority (to preserve the yielding semantics it had over other tasks). 3. Yielding mechanism has changed, to make lower priority tasks to yield to higher priority tasks, instead of just yielding to `scheduleWork` and `executeNowOnTheSameThread`. We don't expect this to have any impact in performance or user perceivable behavior, so we consider it a short-lived refactor. When we validate this assumptions in a complex application we'll delete the old version and only keep the fork. ## Motivation The main motivation for this refactor is to reduce the amount of unnecessary interruptions of running tasks (via `shouldYield`) that are only used to schedule asynchronous tasks from native. The `scheduleWork` method is the only available mechanism exposed to native APIs to schedule work in the JS thread (as the existing version of `scheduleTask` is only meant to be called from JS). This mechanism **always** asks for any running tasks in the scheduler to yield, so these tasks are always considered to have the highest priority. This makes sense for discrete user events, but not for many other use cases coming from native (e.g.: notifying network responses could be UserBlocking, Normal or Low depending on the use case). We need a way to schedule tasks from native with other kinds of priorities, so we don't always have to interrupt what's currently executing if it has a higher priority than what we're scheduling. ## Changes **General APIs:** This centralizes scheduling in only 2 APIs in `RuntimeScheduler` (which already exist in the legacy version): * `scheduleTask`, which is non-blocking for the caller and can be used from any thread. This always uses the task queue in the scheduler and a new yielding mechanism. * `executeNowOnTheSameThread`, which is blocking for the caller and asks any task executing in the scheduler to yield. These tasks don't go through the task queue and instead queue through the existing synchronization mechanism in `RuntimeExecutor`. The yielding mechanism for these tasks is preserved. `scheduleWork` will be deprecated and it's just an alias for `scheduleTask` with an immediate priority (to preserve a similar behavior). **Yielding behavior:** Before, tasks would only yield to tasks scheduled via `scheduleWork` and `executeNowOnTheSameThread` (those tasks didn't go through the task queue). With this implementation, tasks would now yield to any task that has a higher position in the task queue. That means we reuse the existing mechanism to avoid lower priority tasks to never execute because higher priority tasks never stop coming. All tasks would yield to requests for synchronous access (via `executeNowOnTheSameThread`) as did the current implementation. Changelog: [internal] Differential Revision: D49316881 fbshipit-source-id: e768393d4eece826966a1da3b1b5a3bfdabe8593
This pull request was exported from Phabricator. Differential Revision: D49316881 |
Summary: Pull Request resolved: facebook#40944 ## Summary This creates a new version of `RuntimeScheduler` that's intended to be backwards compatible but with a few notable changes: 1. `scheduleTask` is now thread-safe. 2. `scheduleWork` is now just an alias of `scheduleTask` with immediate priority (to preserve the yielding semantics it had over other tasks). 3. Yielding mechanism has changed, to make lower priority tasks to yield to higher priority tasks, instead of just yielding to `scheduleWork` and `executeNowOnTheSameThread`. We don't expect this to have any impact in performance or user perceivable behavior, so we consider it a short-lived refactor. When we validate this assumptions in a complex application we'll delete the old version and only keep the fork. ## Motivation The main motivation for this refactor is to reduce the amount of unnecessary interruptions of running tasks (via `shouldYield`) that are only used to schedule asynchronous tasks from native. The `scheduleWork` method is the only available mechanism exposed to native APIs to schedule work in the JS thread (as the existing version of `scheduleTask` is only meant to be called from JS). This mechanism **always** asks for any running tasks in the scheduler to yield, so these tasks are always considered to have the highest priority. This makes sense for discrete user events, but not for many other use cases coming from native (e.g.: notifying network responses could be UserBlocking, Normal or Low depending on the use case). We need a way to schedule tasks from native with other kinds of priorities, so we don't always have to interrupt what's currently executing if it has a higher priority than what we're scheduling. ## Changes **General APIs:** This centralizes scheduling in only 2 APIs in `RuntimeScheduler` (which already exist in the legacy version): * `scheduleTask`, which is non-blocking for the caller and can be used from any thread. This always uses the task queue in the scheduler and a new yielding mechanism. * `executeNowOnTheSameThread`, which is blocking for the caller and asks any task executing in the scheduler to yield. These tasks don't go through the task queue and instead queue through the existing synchronization mechanism in `RuntimeExecutor`. The yielding mechanism for these tasks is preserved. `scheduleWork` will be deprecated and it's just an alias for `scheduleTask` with an immediate priority (to preserve a similar behavior). **Yielding behavior:** Before, tasks would only yield to tasks scheduled via `scheduleWork` and `executeNowOnTheSameThread` (those tasks didn't go through the task queue). With this implementation, tasks would now yield to any task that has a higher position in the task queue. That means we reuse the existing mechanism to avoid lower priority tasks to never execute because higher priority tasks never stop coming. All tasks would yield to requests for synchronous access (via `executeNowOnTheSameThread`) as did the current implementation. Changelog: [internal] Reviewed By: sammy-SC Differential Revision: D49316881 fbshipit-source-id: 1285077a5b2119dd9e403ab1e637aeda8cf9e19f
6f8fe29
to
c4cdf75
Compare
This pull request was exported from Phabricator. Differential Revision: D49316881 |
Summary: Pull Request resolved: facebook#40944 ## Summary This creates a new version of `RuntimeScheduler` that's intended to be backwards compatible but with a few notable changes: 1. `scheduleTask` is now thread-safe. 2. `scheduleWork` is now just an alias of `scheduleTask` with immediate priority (to preserve the yielding semantics it had over other tasks). 3. Yielding mechanism has changed, to make lower priority tasks to yield to higher priority tasks, instead of just yielding to `scheduleWork` and `executeNowOnTheSameThread`. We don't expect this to have any impact in performance or user perceivable behavior, so we consider it a short-lived refactor. When we validate this assumptions in a complex application we'll delete the old version and only keep the fork. ## Motivation The main motivation for this refactor is to reduce the amount of unnecessary interruptions of running tasks (via `shouldYield`) that are only used to schedule asynchronous tasks from native. The `scheduleWork` method is the only available mechanism exposed to native APIs to schedule work in the JS thread (as the existing version of `scheduleTask` is only meant to be called from JS). This mechanism **always** asks for any running tasks in the scheduler to yield, so these tasks are always considered to have the highest priority. This makes sense for discrete user events, but not for many other use cases coming from native (e.g.: notifying network responses could be UserBlocking, Normal or Low depending on the use case). We need a way to schedule tasks from native with other kinds of priorities, so we don't always have to interrupt what's currently executing if it has a higher priority than what we're scheduling. ## Changes **General APIs:** This centralizes scheduling in only 2 APIs in `RuntimeScheduler` (which already exist in the legacy version): * `scheduleTask`, which is non-blocking for the caller and can be used from any thread. This always uses the task queue in the scheduler and a new yielding mechanism. * `executeNowOnTheSameThread`, which is blocking for the caller and asks any task executing in the scheduler to yield. These tasks don't go through the task queue and instead queue through the existing synchronization mechanism in `RuntimeExecutor`. The yielding mechanism for these tasks is preserved. `scheduleWork` will be deprecated and it's just an alias for `scheduleTask` with an immediate priority (to preserve a similar behavior). **Yielding behavior:** Before, tasks would only yield to tasks scheduled via `scheduleWork` and `executeNowOnTheSameThread` (those tasks didn't go through the task queue). With this implementation, tasks would now yield to any task that has a higher position in the task queue. That means we reuse the existing mechanism to avoid lower priority tasks to never execute because higher priority tasks never stop coming. All tasks would yield to requests for synchronous access (via `executeNowOnTheSameThread`) as did the current implementation. Changelog: [internal] Reviewed By: sammy-SC Differential Revision: D49316881 fbshipit-source-id: b8697951bef3deec5fad0a96225c05b22cebc5a8
c4cdf75
to
71f75c9
Compare
This pull request was exported from Phabricator. Differential Revision: D49316881 |
Summary: Pull Request resolved: facebook#40944 ## Summary This creates a new version of `RuntimeScheduler` that's intended to be backwards compatible but with a few notable changes: 1. `scheduleTask` is now thread-safe. 2. `scheduleWork` is now just an alias of `scheduleTask` with immediate priority (to preserve the yielding semantics it had over other tasks). 3. Yielding mechanism has changed, to make lower priority tasks to yield to higher priority tasks, instead of just yielding to `scheduleWork` and `executeNowOnTheSameThread`. We don't expect this to have any impact in performance or user perceivable behavior, so we consider it a short-lived refactor. When we validate this assumptions in a complex application we'll delete the old version and only keep the fork. ## Motivation The main motivation for this refactor is to reduce the amount of unnecessary interruptions of running tasks (via `shouldYield`) that are only used to schedule asynchronous tasks from native. The `scheduleWork` method is the only available mechanism exposed to native APIs to schedule work in the JS thread (as the existing version of `scheduleTask` is only meant to be called from JS). This mechanism **always** asks for any running tasks in the scheduler to yield, so these tasks are always considered to have the highest priority. This makes sense for discrete user events, but not for many other use cases coming from native (e.g.: notifying network responses could be UserBlocking, Normal or Low depending on the use case). We need a way to schedule tasks from native with other kinds of priorities, so we don't always have to interrupt what's currently executing if it has a higher priority than what we're scheduling. ## Changes **General APIs:** This centralizes scheduling in only 2 APIs in `RuntimeScheduler` (which already exist in the legacy version): * `scheduleTask`, which is non-blocking for the caller and can be used from any thread. This always uses the task queue in the scheduler and a new yielding mechanism. * `executeNowOnTheSameThread`, which is blocking for the caller and asks any task executing in the scheduler to yield. These tasks don't go through the task queue and instead queue through the existing synchronization mechanism in `RuntimeExecutor`. The yielding mechanism for these tasks is preserved. `scheduleWork` will be deprecated and it's just an alias for `scheduleTask` with an immediate priority (to preserve a similar behavior). **Yielding behavior:** Before, tasks would only yield to tasks scheduled via `scheduleWork` and `executeNowOnTheSameThread` (those tasks didn't go through the task queue). With this implementation, tasks would now yield to any task that has a higher position in the task queue. That means we reuse the existing mechanism to avoid lower priority tasks to never execute because higher priority tasks never stop coming. All tasks would yield to requests for synchronous access (via `executeNowOnTheSameThread`) as did the current implementation. Changelog: [internal] Reviewed By: javache, sammy-SC Differential Revision: D49316881 fbshipit-source-id: ae289d41bccf78ab44f2db8c0ecd6eabf00df653
71f75c9
to
0d5252e
Compare
This pull request was exported from Phabricator. Differential Revision: D49316881 |
Summary: Pull Request resolved: facebook#40944 ## Summary This creates a new version of `RuntimeScheduler` that's intended to be backwards compatible but with a few notable changes: 1. `scheduleTask` is now thread-safe. 2. `scheduleWork` is now just an alias of `scheduleTask` with immediate priority (to preserve the yielding semantics it had over other tasks). 3. Yielding mechanism has changed, to make lower priority tasks to yield to higher priority tasks, instead of just yielding to `scheduleWork` and `executeNowOnTheSameThread`. We don't expect this to have any impact in performance or user perceivable behavior, so we consider it a short-lived refactor. When we validate this assumptions in a complex application we'll delete the old version and only keep the fork. ## Motivation The main motivation for this refactor is to reduce the amount of unnecessary interruptions of running tasks (via `shouldYield`) that are only used to schedule asynchronous tasks from native. The `scheduleWork` method is the only available mechanism exposed to native APIs to schedule work in the JS thread (as the existing version of `scheduleTask` is only meant to be called from JS). This mechanism **always** asks for any running tasks in the scheduler to yield, so these tasks are always considered to have the highest priority. This makes sense for discrete user events, but not for many other use cases coming from native (e.g.: notifying network responses could be UserBlocking, Normal or Low depending on the use case). We need a way to schedule tasks from native with other kinds of priorities, so we don't always have to interrupt what's currently executing if it has a higher priority than what we're scheduling. ## Changes **General APIs:** This centralizes scheduling in only 2 APIs in `RuntimeScheduler` (which already exist in the legacy version): * `scheduleTask`, which is non-blocking for the caller and can be used from any thread. This always uses the task queue in the scheduler and a new yielding mechanism. * `executeNowOnTheSameThread`, which is blocking for the caller and asks any task executing in the scheduler to yield. These tasks don't go through the task queue and instead queue through the existing synchronization mechanism in `RuntimeExecutor`. The yielding mechanism for these tasks is preserved. `scheduleWork` will be deprecated and it's just an alias for `scheduleTask` with an immediate priority (to preserve a similar behavior). **Yielding behavior:** Before, tasks would only yield to tasks scheduled via `scheduleWork` and `executeNowOnTheSameThread` (those tasks didn't go through the task queue). With this implementation, tasks would now yield to any task that has a higher position in the task queue. That means we reuse the existing mechanism to avoid lower priority tasks to never execute because higher priority tasks never stop coming. All tasks would yield to requests for synchronous access (via `executeNowOnTheSameThread`) as did the current implementation. Changelog: [internal] Reviewed By: javache, sammy-SC Differential Revision: D49316881 fbshipit-source-id: 55a72cabbf3f9e110cbf7e878e52e066fd77d8cf
0d5252e
to
c457516
Compare
Summary: ## Summary This creates a new version of `RuntimeScheduler` that's intended to be backwards compatible but with a few notable changes: 1. `scheduleTask` is now thread-safe. 2. `scheduleWork` is now just an alias of `scheduleTask` with immediate priority (to preserve the yielding semantics it had over other tasks). 3. Yielding mechanism has changed, to make lower priority tasks to yield to higher priority tasks, instead of just yielding to `scheduleWork` and `executeNowOnTheSameThread`. We don't expect this to have any impact in performance or user perceivable behavior, so we consider it a short-lived refactor. When we validate this assumptions in a complex application we'll delete the old version and only keep the fork. ## Motivation The main motivation for this refactor is to reduce the amount of unnecessary interruptions of running tasks (via `shouldYield`) that are only used to schedule asynchronous tasks from native. The `scheduleWork` method is the only available mechanism exposed to native APIs to schedule work in the JS thread (as the existing version of `scheduleTask` is only meant to be called from JS). This mechanism **always** asks for any running tasks in the scheduler to yield, so these tasks are always considered to have the highest priority. This makes sense for discrete user events, but not for many other use cases coming from native (e.g.: notifying network responses could be UserBlocking, Normal or Low depending on the use case). We need a way to schedule tasks from native with other kinds of priorities, so we don't always have to interrupt what's currently executing if it has a higher priority than what we're scheduling. ## Changes **General APIs:** This centralizes scheduling in only 2 APIs in `RuntimeScheduler` (which already exist in the legacy version): * `scheduleTask`, which is non-blocking for the caller and can be used from any thread. This always uses the task queue in the scheduler and a new yielding mechanism. * `executeNowOnTheSameThread`, which is blocking for the caller and asks any task executing in the scheduler to yield. These tasks don't go through the task queue and instead queue through the existing synchronization mechanism in `RuntimeExecutor`. The yielding mechanism for these tasks is preserved. `scheduleWork` will be deprecated and it's just an alias for `scheduleTask` with an immediate priority (to preserve a similar behavior). **Yielding behavior:** Before, tasks would only yield to tasks scheduled via `scheduleWork` and `executeNowOnTheSameThread` (those tasks didn't go through the task queue). With this implementation, tasks would now yield to any task that has a higher position in the task queue. That means we reuse the existing mechanism to avoid lower priority tasks to never execute because higher priority tasks never stop coming. All tasks would yield to requests for synchronous access (via `executeNowOnTheSameThread`) as did the current implementation. Changelog: [internal] Reviewed By: javache, sammy-SC Differential Revision: D49316881
c457516
to
0c9625f
Compare
This pull request was exported from Phabricator. Differential Revision: D49316881 |
Summary: ## Summary This creates a new version of `RuntimeScheduler` that's intended to be backwards compatible but with a few notable changes: 1. `scheduleTask` is now thread-safe. 2. `scheduleWork` is now just an alias of `scheduleTask` with immediate priority (to preserve the yielding semantics it had over other tasks). 3. Yielding mechanism has changed, to make lower priority tasks to yield to higher priority tasks, instead of just yielding to `scheduleWork` and `executeNowOnTheSameThread`. We don't expect this to have any impact in performance or user perceivable behavior, so we consider it a short-lived refactor. When we validate this assumptions in a complex application we'll delete the old version and only keep the fork. ## Motivation The main motivation for this refactor is to reduce the amount of unnecessary interruptions of running tasks (via `shouldYield`) that are only used to schedule asynchronous tasks from native. The `scheduleWork` method is the only available mechanism exposed to native APIs to schedule work in the JS thread (as the existing version of `scheduleTask` is only meant to be called from JS). This mechanism **always** asks for any running tasks in the scheduler to yield, so these tasks are always considered to have the highest priority. This makes sense for discrete user events, but not for many other use cases coming from native (e.g.: notifying network responses could be UserBlocking, Normal or Low depending on the use case). We need a way to schedule tasks from native with other kinds of priorities, so we don't always have to interrupt what's currently executing if it has a higher priority than what we're scheduling. ## Changes **General APIs:** This centralizes scheduling in only 2 APIs in `RuntimeScheduler` (which already exist in the legacy version): * `scheduleTask`, which is non-blocking for the caller and can be used from any thread. This always uses the task queue in the scheduler and a new yielding mechanism. * `executeNowOnTheSameThread`, which is blocking for the caller and asks any task executing in the scheduler to yield. These tasks don't go through the task queue and instead queue through the existing synchronization mechanism in `RuntimeExecutor`. The yielding mechanism for these tasks is preserved. `scheduleWork` will be deprecated and it's just an alias for `scheduleTask` with an immediate priority (to preserve a similar behavior). **Yielding behavior:** Before, tasks would only yield to tasks scheduled via `scheduleWork` and `executeNowOnTheSameThread` (those tasks didn't go through the task queue). With this implementation, tasks would now yield to any task that has a higher position in the task queue. That means we reuse the existing mechanism to avoid lower priority tasks to never execute because higher priority tasks never stop coming. All tasks would yield to requests for synchronous access (via `executeNowOnTheSameThread`) as did the current implementation. Changelog: [internal] Reviewed By: javache, sammy-SC Differential Revision: D49316881
Summary: This removes an old experiment to implement microtasks in React Native (which is incorrect now that the runtime scheduler executes multiple tasks per runtime executor "task"). `drainMicrotasks` is a no-op at the moment in Hermes because the flag isn't set, so this code is essentially dead. We'll add the new iteration of microtasks in a following PR. Changelog: [internal] Reviewed By: christophpurrer Differential Revision: D49536251
…facebook#40875) Summary: This introduces a proxy for RuntimeScheduler so we can select between 2 different implementations at runtime (current implementation vs. new implementation, done in D49316881). Changelog: [internal] Reviewed By: javache, sammy-SC Differential Revision: D49316880
Summary: ## Summary This creates a new version of `RuntimeScheduler` that's intended to be backwards compatible but with a few notable changes: 1. `scheduleTask` is now thread-safe. 2. `scheduleWork` is now just an alias of `scheduleTask` with immediate priority (to preserve the yielding semantics it had over other tasks). 3. Yielding mechanism has changed, to make lower priority tasks to yield to higher priority tasks, instead of just yielding to `scheduleWork` and `executeNowOnTheSameThread`. We don't expect this to have any impact in performance or user perceivable behavior, so we consider it a short-lived refactor. When we validate this assumptions in a complex application we'll delete the old version and only keep the fork. ## Motivation The main motivation for this refactor is to reduce the amount of unnecessary interruptions of running tasks (via `shouldYield`) that are only used to schedule asynchronous tasks from native. The `scheduleWork` method is the only available mechanism exposed to native APIs to schedule work in the JS thread (as the existing version of `scheduleTask` is only meant to be called from JS). This mechanism **always** asks for any running tasks in the scheduler to yield, so these tasks are always considered to have the highest priority. This makes sense for discrete user events, but not for many other use cases coming from native (e.g.: notifying network responses could be UserBlocking, Normal or Low depending on the use case). We need a way to schedule tasks from native with other kinds of priorities, so we don't always have to interrupt what's currently executing if it has a higher priority than what we're scheduling. ## Changes **General APIs:** This centralizes scheduling in only 2 APIs in `RuntimeScheduler` (which already exist in the legacy version): * `scheduleTask`, which is non-blocking for the caller and can be used from any thread. This always uses the task queue in the scheduler and a new yielding mechanism. * `executeNowOnTheSameThread`, which is blocking for the caller and asks any task executing in the scheduler to yield. These tasks don't go through the task queue and instead queue through the existing synchronization mechanism in `RuntimeExecutor`. The yielding mechanism for these tasks is preserved. `scheduleWork` will be deprecated and it's just an alias for `scheduleTask` with an immediate priority (to preserve a similar behavior). **Yielding behavior:** Before, tasks would only yield to tasks scheduled via `scheduleWork` and `executeNowOnTheSameThread` (those tasks didn't go through the task queue). With this implementation, tasks would now yield to any task that has a higher position in the task queue. That means we reuse the existing mechanism to avoid lower priority tasks to never execute because higher priority tasks never stop coming. All tasks would yield to requests for synchronous access (via `executeNowOnTheSameThread`) as did the current implementation. Changelog: [internal] Reviewed By: javache, sammy-SC Differential Revision: D49316881
0c9625f
to
50d587e
Compare
This pull request was exported from Phabricator. Differential Revision: D49316881 |
This pull request has been merged in 220dcde. |
Summary: Pull Request resolved: facebook#40944 ## Summary This creates a new version of `RuntimeScheduler` that's intended to be backwards compatible but with a few notable changes: 1. `scheduleTask` is now thread-safe. 2. `scheduleWork` is now just an alias of `scheduleTask` with immediate priority (to preserve the yielding semantics it had over other tasks). 3. Yielding mechanism has changed, to make lower priority tasks to yield to higher priority tasks, instead of just yielding to `scheduleWork` and `executeNowOnTheSameThread`. We don't expect this to have any impact in performance or user perceivable behavior, so we consider it a short-lived refactor. When we validate this assumptions in a complex application we'll delete the old version and only keep the fork. ## Motivation The main motivation for this refactor is to reduce the amount of unnecessary interruptions of running tasks (via `shouldYield`) that are only used to schedule asynchronous tasks from native. The `scheduleWork` method is the only available mechanism exposed to native APIs to schedule work in the JS thread (as the existing version of `scheduleTask` is only meant to be called from JS). This mechanism **always** asks for any running tasks in the scheduler to yield, so these tasks are always considered to have the highest priority. This makes sense for discrete user events, but not for many other use cases coming from native (e.g.: notifying network responses could be UserBlocking, Normal or Low depending on the use case). We need a way to schedule tasks from native with other kinds of priorities, so we don't always have to interrupt what's currently executing if it has a higher priority than what we're scheduling. ## Changes **General APIs:** This centralizes scheduling in only 2 APIs in `RuntimeScheduler` (which already exist in the legacy version): * `scheduleTask`, which is non-blocking for the caller and can be used from any thread. This always uses the task queue in the scheduler and a new yielding mechanism. * `executeNowOnTheSameThread`, which is blocking for the caller and asks any task executing in the scheduler to yield. These tasks don't go through the task queue and instead queue through the existing synchronization mechanism in `RuntimeExecutor`. The yielding mechanism for these tasks is preserved. `scheduleWork` will be deprecated and it's just an alias for `scheduleTask` with an immediate priority (to preserve a similar behavior). **Yielding behavior:** Before, tasks would only yield to tasks scheduled via `scheduleWork` and `executeNowOnTheSameThread` (those tasks didn't go through the task queue). With this implementation, tasks would now yield to any task that has a higher position in the task queue. That means we reuse the existing mechanism to avoid lower priority tasks to never execute because higher priority tasks never stop coming. All tasks would yield to requests for synchronous access (via `executeNowOnTheSameThread`) as did the current implementation. Changelog: [internal] Reviewed By: javache, sammy-SC Differential Revision: D49316881 fbshipit-source-id: 046afc8b6f510a8608ef3da6e27b2663d861f1b8
Summary:
Summary
This creates a new version of
RuntimeScheduler
that's intended to be backwards compatible but with a few notable changes:scheduleTask
is now thread-safe.scheduleWork
is now just an alias ofscheduleTask
with immediate priority (to preserve the yielding semantics it had over other tasks).scheduleWork
andexecuteNowOnTheSameThread
.We don't expect this to have any impact in performance or user perceivable behavior, so we consider it a short-lived refactor. When we validate this assumptions in a complex application we'll delete the old version and only keep the fork.
Motivation
The main motivation for this refactor is to reduce the amount of unnecessary interruptions of running tasks (via
shouldYield
) that are only used to schedule asynchronous tasks from native.The
scheduleWork
method is the only available mechanism exposed to native APIs to schedule work in the JS thread (as the existing version ofscheduleTask
is only meant to be called from JS). This mechanism always asks for any running tasks in the scheduler to yield, so these tasks are always considered to have the highest priority. This makes sense for discrete user events, but not for many other use cases coming from native (e.g.: notifying network responses could be UserBlocking, Normal or Low depending on the use case).We need a way to schedule tasks from native with other kinds of priorities, so we don't always have to interrupt what's currently executing if it has a higher priority than what we're scheduling.
Changes
General APIs:
This centralizes scheduling in only 2 APIs in
RuntimeScheduler
(which already exist in the legacy version):scheduleTask
, which is non-blocking for the caller and can be used from any thread. This always uses the task queue in the scheduler and a new yielding mechanism.executeNowOnTheSameThread
, which is blocking for the caller and asks any task executing in the scheduler to yield. These tasks don't go through the task queue and instead queue through the existing synchronization mechanism inRuntimeExecutor
. The yielding mechanism for these tasks is preserved.scheduleWork
will be deprecated and it's just an alias forscheduleTask
with an immediate priority (to preserve a similar behavior).Yielding behavior:
Before, tasks would only yield to tasks scheduled via
scheduleWork
andexecuteNowOnTheSameThread
(those tasks didn't go through the task queue).With this implementation, tasks would now yield to any task that has a higher position in the task queue. That means we reuse the existing mechanism to avoid lower priority tasks to never execute because higher priority tasks never stop coming.
All tasks would yield to requests for synchronous access (via
executeNowOnTheSameThread
) as did the current implementation.Changelog: [internal]
Differential Revision: D49316881
See react-native-community/discussions-and-proposals#744