Skip to content

Commit c9ee902

Browse files
psivaramfacebook-github-bot
authored andcommitted
Adding support to cancel a headless task (#20416)
Summary: On UWP, when the app is executing a Background task, the OS can request it to cancel the task (for various reasons). If the app does not cancel its background task quickly, the OS might terminate the app. This change adds support to cancel the headless task which can be used by native code to forward the cancellation request from the OS to the JS code. Pull Request resolved: #20416 Differential Revision: D10052080 Pulled By: cpojer fbshipit-source-id: 2c0322ebb45f7835739f68bdf82a7100d968c516
1 parent d4adf50 commit c9ee902

File tree

1 file changed

+39
-6
lines changed

1 file changed

+39
-6
lines changed

Libraries/ReactNative/AppRegistry.js

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ const renderApplication = require('renderApplication');
2121

2222
type Task = (taskData: any) => Promise<void>;
2323
type TaskProvider = () => Task;
24+
type TaskCanceller = () => void;
25+
type TaskCancelProvider = () => TaskCanceller;
26+
2427
/* $FlowFixMe(>=0.90.0 site=react_native_fb) This comment suppresses an
2528
* error found when Flow v0.90 was deployed. To see the error, delete this
2629
* comment and run Flow. */
@@ -50,7 +53,8 @@ export type WrapperComponentProvider = any => React$ComponentType<*>;
5053
const runnables: Runnables = {};
5154
let runCount = 1;
5255
const sections: Runnables = {};
53-
const tasks: Map<string, TaskProvider> = new Map();
56+
const taskProviders: Map<string, TaskProvider> = new Map();
57+
const taskCancelProviders: Map<string, TaskCancelProvider> = new Map();
5458
let componentProviderInstrumentationHook: ComponentProviderInstrumentationHook = (
5559
component: ComponentProvider,
5660
) => component();
@@ -212,13 +216,29 @@ const AppRegistry = {
212216
*
213217
* See http://facebook.github.io/react-native/docs/appregistry.html#registerheadlesstask
214218
*/
215-
registerHeadlessTask(taskKey: string, task: TaskProvider): void {
216-
if (tasks.has(taskKey)) {
219+
registerHeadlessTask(taskKey: string, taskProvider: TaskProvider): void {
220+
this.registerCancellableHeadlessTask(taskKey, taskProvider, () => () => {
221+
/* Cancel is no-op */
222+
});
223+
},
224+
225+
/**
226+
* Register a cancellable headless task. A headless task is a bit of code that runs without a UI.
227+
*
228+
* See http://facebook.github.io/react-native/docs/appregistry.html#registercancellableheadlesstask
229+
*/
230+
registerCancellableHeadlessTask(
231+
taskKey: string,
232+
taskProvider: TaskProvider,
233+
taskCancelProvider: TaskCancelProvider,
234+
): void {
235+
if (taskProviders.has(taskKey)) {
217236
console.warn(
218-
`registerHeadlessTask called multiple times for same key '${taskKey}'`,
237+
`registerHeadlessTask or registerCancellableHeadlessTask called multiple times for same key '${taskKey}'`,
219238
);
220239
}
221-
tasks.set(taskKey, task);
240+
taskProviders.set(taskKey, taskProvider);
241+
taskCancelProviders.set(taskKey, taskCancelProvider);
222242
},
223243

224244
/**
@@ -227,7 +247,7 @@ const AppRegistry = {
227247
* See http://facebook.github.io/react-native/docs/appregistry.html#startheadlesstask
228248
*/
229249
startHeadlessTask(taskId: number, taskKey: string, data: any): void {
230-
const taskProvider = tasks.get(taskKey);
250+
const taskProvider = taskProviders.get(taskKey);
231251
if (!taskProvider) {
232252
throw new Error(`No task registered for key ${taskKey}`);
233253
}
@@ -240,6 +260,19 @@ const AppRegistry = {
240260
NativeModules.HeadlessJsTaskSupport.notifyTaskFinished(taskId);
241261
});
242262
},
263+
264+
/**
265+
* Only called from native code. Cancels a headless task.
266+
*
267+
* See http://facebook.github.io/react-native/docs/appregistry.html#cancelheadlesstask
268+
*/
269+
cancelHeadlessTask(taskId: number, taskKey: string): void {
270+
const taskCancelProvider = taskCancelProviders.get(taskKey);
271+
if (!taskCancelProvider) {
272+
throw new Error(`No task canceller registered for key '${taskKey}'`);
273+
}
274+
taskCancelProvider()();
275+
},
243276
};
244277

245278
BatchedBridge.registerCallableModule('AppRegistry', AppRegistry);

0 commit comments

Comments
 (0)