-
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
execute calls to AsyncStorageModule serially #20386
Changes from 4 commits
0ae8e20
0227e95
0384323
e92a018
6463c07
b41c95a
92560ef
480e7f7
2c6b497
cde3ac5
9527119
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
/** | ||
/* | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
|
@@ -8,14 +8,16 @@ | |
package com.facebook.react.modules.storage; | ||
|
||
import java.util.HashSet; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
|
||
import android.database.Cursor; | ||
import android.database.sqlite.SQLiteStatement; | ||
|
||
import com.facebook.common.logging.FLog; | ||
import com.facebook.infer.annotation.Assertions; | ||
import com.facebook.react.bridge.Arguments; | ||
import com.facebook.react.bridge.Callback; | ||
import com.facebook.react.bridge.GuardedAsyncTask; | ||
import com.facebook.react.bridge.ReactApplicationContext; | ||
import com.facebook.react.bridge.ReactContextBaseJavaModule; | ||
import com.facebook.react.bridge.ReactMethod; | ||
|
@@ -42,10 +44,17 @@ public final class AsyncStorageModule | |
|
||
private ReactDatabaseSupplier mReactDatabaseSupplier; | ||
private boolean mShuttingDown = false; | ||
private ExecutorService mExecutor; | ||
|
||
public AsyncStorageModule(ReactApplicationContext reactContext) { | ||
super(reactContext); | ||
mReactDatabaseSupplier = ReactDatabaseSupplier.getInstance(reactContext); | ||
mExecutor = Executors.newSingleThreadExecutor(); | ||
} | ||
|
||
public AsyncStorageModule(ReactApplicationContext reactContext, ExecutorService executor) { | ||
this(reactContext); | ||
mExecutor = executor; | ||
} | ||
|
||
@Override | ||
|
@@ -61,6 +70,7 @@ public void initialize() { | |
|
||
@Override | ||
public void onCatalystInstanceDestroy() { | ||
mExecutor.shutdown(); | ||
mShuttingDown = true; | ||
} | ||
|
||
|
@@ -83,9 +93,9 @@ public void multiGet(final ReadableArray keys, final Callback callback) { | |
return; | ||
} | ||
|
||
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) { | ||
execute(new Runnable() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens if an exception is thrown when executing the Runnable? GuardedAsyncTask provided error management, see: https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/GuardedAsyncTask.java#L34 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @janicduplessis got it and ready to push the change, but waiting for CI to become green again. |
||
@Override | ||
protected void doInBackgroundGuarded(Void... params) { | ||
public void run() { | ||
if (!ensureDatabase()) { | ||
callback.invoke(AsyncStorageErrorUtil.getDBError(null), null); | ||
return; | ||
|
@@ -141,7 +151,7 @@ protected void doInBackgroundGuarded(Void... params) { | |
|
||
callback.invoke(null, data); | ||
} | ||
}.execute(); | ||
}); | ||
} | ||
|
||
/** | ||
|
@@ -156,9 +166,9 @@ public void multiSet(final ReadableArray keyValueArray, final Callback callback) | |
return; | ||
} | ||
|
||
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) { | ||
execute(new Runnable() { | ||
@Override | ||
protected void doInBackgroundGuarded(Void... params) { | ||
public void run() { | ||
if (!ensureDatabase()) { | ||
callback.invoke(AsyncStorageErrorUtil.getDBError(null)); | ||
return; | ||
|
@@ -208,7 +218,7 @@ protected void doInBackgroundGuarded(Void... params) { | |
callback.invoke(); | ||
} | ||
} | ||
}.execute(); | ||
}); | ||
} | ||
|
||
/** | ||
|
@@ -221,9 +231,9 @@ public void multiRemove(final ReadableArray keys, final Callback callback) { | |
return; | ||
} | ||
|
||
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) { | ||
execute(new Runnable() { | ||
@Override | ||
protected void doInBackgroundGuarded(Void... params) { | ||
public void run() { | ||
if (!ensureDatabase()) { | ||
callback.invoke(AsyncStorageErrorUtil.getDBError(null)); | ||
return; | ||
|
@@ -259,7 +269,7 @@ protected void doInBackgroundGuarded(Void... params) { | |
callback.invoke(); | ||
} | ||
} | ||
}.execute(); | ||
}); | ||
} | ||
|
||
/** | ||
|
@@ -268,9 +278,9 @@ protected void doInBackgroundGuarded(Void... params) { | |
*/ | ||
@ReactMethod | ||
public void multiMerge(final ReadableArray keyValueArray, final Callback callback) { | ||
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) { | ||
execute(new Runnable() { | ||
@Override | ||
protected void doInBackgroundGuarded(Void... params) { | ||
public void run() { | ||
if (!ensureDatabase()) { | ||
callback.invoke(AsyncStorageErrorUtil.getDBError(null)); | ||
return; | ||
|
@@ -322,17 +332,17 @@ protected void doInBackgroundGuarded(Void... params) { | |
callback.invoke(); | ||
} | ||
} | ||
}.execute(); | ||
}); | ||
} | ||
|
||
/** | ||
* Clears the database. | ||
*/ | ||
@ReactMethod | ||
public void clear(final Callback callback) { | ||
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) { | ||
execute(new Runnable() { | ||
@Override | ||
protected void doInBackgroundGuarded(Void... params) { | ||
public void run() { | ||
if (!mReactDatabaseSupplier.ensureDatabase()) { | ||
callback.invoke(AsyncStorageErrorUtil.getDBError(null)); | ||
return; | ||
|
@@ -345,17 +355,17 @@ protected void doInBackgroundGuarded(Void... params) { | |
callback.invoke(AsyncStorageErrorUtil.getError(null, e.getMessage())); | ||
} | ||
} | ||
}.execute(); | ||
}); | ||
} | ||
|
||
/** | ||
* Returns an array with all keys from the database. | ||
*/ | ||
@ReactMethod | ||
public void getAllKeys(final Callback callback) { | ||
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) { | ||
execute(new Runnable() { | ||
@Override | ||
protected void doInBackgroundGuarded(Void... params) { | ||
public void run() { | ||
if (!ensureDatabase()) { | ||
callback.invoke(AsyncStorageErrorUtil.getDBError(null), null); | ||
return; | ||
|
@@ -379,7 +389,7 @@ protected void doInBackgroundGuarded(Void... params) { | |
} | ||
callback.invoke(null, data); | ||
} | ||
}.execute(); | ||
}); | ||
} | ||
|
||
/** | ||
|
@@ -388,4 +398,13 @@ protected void doInBackgroundGuarded(Void... params) { | |
private boolean ensureDatabase() { | ||
return !mShuttingDown && mReactDatabaseSupplier.ensureDatabase(); | ||
} | ||
|
||
private void execute(Runnable r) { | ||
Assertions.assertNotNull(mExecutor); | ||
try { | ||
mExecutor.execute(r); | ||
} catch (RuntimeException e) { | ||
getReactApplicationContext().handleException(e); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why touch this line ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Android Studio was showing warning, so fixed it 😄