Merge branch 'braid/webworker-error-fallback' into 'main'

chore: expose option to retry computations

Closes famedly-web#536

See merge request famedly/company/frontend/famedlysdk!1096
This commit is contained in:
Nicolas Werner 2022-08-10 08:07:05 +00:00
commit 1047b8bdd3
2 changed files with 84 additions and 23 deletions

View File

@ -25,22 +25,37 @@ abstract class NativeImplementations {
/// the UI to likely freeze /// the UI to likely freeze
static const dummy = NativeImplementationsDummy(); static const dummy = NativeImplementationsDummy();
FutureOr<RoomKeys> generateUploadKeys(GenerateUploadKeysArgs args); FutureOr<RoomKeys> generateUploadKeys(
GenerateUploadKeysArgs args, {
bool retryInDummy = true,
});
FutureOr<Uint8List> keyFromPassphrase(KeyFromPassphraseArgs args); FutureOr<Uint8List> keyFromPassphrase(
KeyFromPassphraseArgs args, {
bool retryInDummy = true,
});
FutureOr<Uint8List?> decryptFile(EncryptedFile file); FutureOr<Uint8List?> decryptFile(
EncryptedFile file, {
bool retryInDummy = true,
});
FutureOr<MatrixImageFileResizedResponse?> shrinkImage( FutureOr<MatrixImageFileResizedResponse?> shrinkImage(
MatrixImageFileResizeArguments args); MatrixImageFileResizeArguments args, {
bool retryInDummy = false,
});
FutureOr<MatrixImageFileResizedResponse?> calcImageMetadata(Uint8List bytes); FutureOr<MatrixImageFileResizedResponse?> calcImageMetadata(
Uint8List bytes, {
bool retryInDummy = false,
});
@override @override
/// this implementation will catch any non-implemented method /// this implementation will catch any non-implemented method
dynamic noSuchMethod(Invocation invocation) { dynamic noSuchMethod(Invocation invocation) {
final dynamic argument = invocation.positionalArguments.single; final dynamic argument = invocation.positionalArguments.single;
final bool retryInDummy = invocation.namedArguments['retryInDummy'] as bool;
final memberName = invocation.memberName.toString().split('"')[1]; final memberName = invocation.memberName.toString().split('"')[1];
Logs().w( Logs().w(
@ -50,15 +65,15 @@ abstract class NativeImplementations {
); );
switch (memberName) { switch (memberName) {
case 'generateUploadKeys': case 'generateUploadKeys':
return dummy.generateUploadKeys(argument); return dummy.generateUploadKeys(argument, retryInDummy: retryInDummy);
case 'keyFromPassphrase': case 'keyFromPassphrase':
return dummy.keyFromPassphrase(argument); return dummy.keyFromPassphrase(argument, retryInDummy: retryInDummy);
case 'decryptFile': case 'decryptFile':
return dummy.decryptFile(argument); return dummy.decryptFile(argument, retryInDummy: retryInDummy);
case 'shrinkImage': case 'shrinkImage':
return dummy.shrinkImage(argument); return dummy.shrinkImage(argument, retryInDummy: retryInDummy);
case 'calcImageMetadata': case 'calcImageMetadata':
return dummy.calcImageMetadata(argument); return dummy.calcImageMetadata(argument, retryInDummy: retryInDummy);
default: default:
return super.noSuchMethod(invocation); return super.noSuchMethod(invocation);
} }
@ -69,28 +84,42 @@ class NativeImplementationsDummy extends NativeImplementations {
const NativeImplementationsDummy(); const NativeImplementationsDummy();
@override @override
Future<Uint8List?> decryptFile(EncryptedFile file) { Future<Uint8List?> decryptFile(
EncryptedFile file, {
bool retryInDummy = true,
}) {
return decryptFileImplementation(file); return decryptFileImplementation(file);
} }
@override @override
Future<RoomKeys> generateUploadKeys(GenerateUploadKeysArgs args) async { Future<RoomKeys> generateUploadKeys(
GenerateUploadKeysArgs args, {
bool retryInDummy = true,
}) async {
return generateUploadKeysImplementation(args); return generateUploadKeysImplementation(args);
} }
@override @override
Future<Uint8List> keyFromPassphrase(KeyFromPassphraseArgs args) { Future<Uint8List> keyFromPassphrase(
KeyFromPassphraseArgs args, {
bool retryInDummy = true,
}) {
return generateKeyFromPassphrase(args); return generateKeyFromPassphrase(args);
} }
@override @override
MatrixImageFileResizedResponse? shrinkImage( MatrixImageFileResizedResponse? shrinkImage(
MatrixImageFileResizeArguments args) { MatrixImageFileResizeArguments args, {
bool retryInDummy = false,
}) {
return MatrixImageFile.resizeImplementation(args); return MatrixImageFile.resizeImplementation(args);
} }
@override @override
MatrixImageFileResizedResponse? calcImageMetadata(Uint8List bytes) { MatrixImageFileResizedResponse? calcImageMetadata(
Uint8List bytes, {
bool retryInDummy = false,
}) {
return MatrixImageFile.calcMetadataImplementation(bytes); return MatrixImageFile.calcMetadataImplementation(bytes);
} }
} }
@ -122,7 +151,10 @@ class NativeImplementationsIsolate extends NativeImplementations {
} }
@override @override
Future<Uint8List?> decryptFile(EncryptedFile file) { Future<Uint8List?> decryptFile(
EncryptedFile file, {
bool retryInDummy = true,
}) {
return runInBackground<Uint8List?, EncryptedFile>( return runInBackground<Uint8List?, EncryptedFile>(
NativeImplementations.dummy.decryptFile, NativeImplementations.dummy.decryptFile,
file, file,
@ -130,7 +162,10 @@ class NativeImplementationsIsolate extends NativeImplementations {
} }
@override @override
Future<RoomKeys> generateUploadKeys(GenerateUploadKeysArgs args) async { Future<RoomKeys> generateUploadKeys(
GenerateUploadKeysArgs args, {
bool retryInDummy = true,
}) async {
return runInBackground<RoomKeys, GenerateUploadKeysArgs>( return runInBackground<RoomKeys, GenerateUploadKeysArgs>(
NativeImplementations.dummy.generateUploadKeys, NativeImplementations.dummy.generateUploadKeys,
args, args,
@ -138,7 +173,10 @@ class NativeImplementationsIsolate extends NativeImplementations {
} }
@override @override
Future<Uint8List> keyFromPassphrase(KeyFromPassphraseArgs args) { Future<Uint8List> keyFromPassphrase(
KeyFromPassphraseArgs args, {
bool retryInDummy = true,
}) {
return runInBackground<Uint8List, KeyFromPassphraseArgs>( return runInBackground<Uint8List, KeyFromPassphraseArgs>(
NativeImplementations.dummy.keyFromPassphrase, NativeImplementations.dummy.keyFromPassphrase,
args, args,
@ -147,7 +185,9 @@ class NativeImplementationsIsolate extends NativeImplementations {
@override @override
Future<MatrixImageFileResizedResponse?> shrinkImage( Future<MatrixImageFileResizedResponse?> shrinkImage(
MatrixImageFileResizeArguments args) { MatrixImageFileResizeArguments args, {
bool retryInDummy = false,
}) {
return runInBackground<MatrixImageFileResizedResponse?, return runInBackground<MatrixImageFileResizedResponse?,
MatrixImageFileResizeArguments>( MatrixImageFileResizeArguments>(
NativeImplementations.dummy.shrinkImage, NativeImplementations.dummy.shrinkImage,
@ -156,7 +196,10 @@ class NativeImplementationsIsolate extends NativeImplementations {
} }
@override @override
FutureOr<MatrixImageFileResizedResponse?> calcImageMetadata(Uint8List bytes) { FutureOr<MatrixImageFileResizedResponse?> calcImageMetadata(
Uint8List bytes, {
bool retryInDummy = false,
}) {
return runInBackground<MatrixImageFileResizedResponse?, Uint8List>( return runInBackground<MatrixImageFileResizedResponse?, Uint8List>(
NativeImplementations.dummy.calcImageMetadata, NativeImplementations.dummy.calcImageMetadata,
bytes, bytes,

View File

@ -62,7 +62,9 @@ class NativeImplementationsWebWorker extends NativeImplementations {
@override @override
Future<MatrixImageFileResizedResponse?> calcImageMetadata( Future<MatrixImageFileResizedResponse?> calcImageMetadata(
Uint8List bytes) async { Uint8List bytes, {
bool retryInDummy = false,
}) async {
try { try {
final result = await operation<Map<dynamic, dynamic>, Uint8List>( final result = await operation<Map<dynamic, dynamic>, Uint8List>(
WebWorkerOperations.calcImageMetadata, WebWorkerOperations.calcImageMetadata,
@ -70,6 +72,11 @@ class NativeImplementationsWebWorker extends NativeImplementations {
); );
return MatrixImageFileResizedResponse.fromJson(Map.from(result)); return MatrixImageFileResizedResponse.fromJson(Map.from(result));
} catch (e, s) { } catch (e, s) {
if (!retryInDummy) {
Logs().e(
'Web worker computation error. Ignoring and returning null', e, s);
return null;
}
Logs().e('Web worker computation error. Fallback to main thread', e, s); Logs().e('Web worker computation error. Fallback to main thread', e, s);
return NativeImplementations.dummy.calcImageMetadata(bytes); return NativeImplementations.dummy.calcImageMetadata(bytes);
} }
@ -77,7 +84,9 @@ class NativeImplementationsWebWorker extends NativeImplementations {
@override @override
Future<MatrixImageFileResizedResponse?> shrinkImage( Future<MatrixImageFileResizedResponse?> shrinkImage(
MatrixImageFileResizeArguments args) async { MatrixImageFileResizeArguments args, {
bool retryInDummy = false,
}) async {
try { try {
final result = final result =
await operation<Map<dynamic, dynamic>, Map<String, dynamic>>( await operation<Map<dynamic, dynamic>, Map<String, dynamic>>(
@ -86,13 +95,21 @@ class NativeImplementationsWebWorker extends NativeImplementations {
); );
return MatrixImageFileResizedResponse.fromJson(Map.from(result)); return MatrixImageFileResizedResponse.fromJson(Map.from(result));
} catch (e, s) { } catch (e, s) {
if (!retryInDummy) {
Logs().e(
'Web worker computation error. Ignoring and returning null', e, s);
return null;
}
Logs().e('Web worker computation error. Fallback to main thread', e, s); Logs().e('Web worker computation error. Fallback to main thread', e, s);
return NativeImplementations.dummy.shrinkImage(args); return NativeImplementations.dummy.shrinkImage(args);
} }
} }
@override @override
Future<RoomKeys> generateUploadKeys(GenerateUploadKeysArgs args) async { Future<RoomKeys> generateUploadKeys(
GenerateUploadKeysArgs args, {
bool retryInDummy = true,
}) async {
try { try {
final result = final result =
await operation<Map<dynamic, dynamic>, Map<String, dynamic>>( await operation<Map<dynamic, dynamic>, Map<String, dynamic>>(
@ -101,6 +118,7 @@ class NativeImplementationsWebWorker extends NativeImplementations {
); );
return RoomKeys.fromJson(Map.from(result)); return RoomKeys.fromJson(Map.from(result));
} catch (e, s) { } catch (e, s) {
if (!retryInDummy) rethrow;
Logs().e('Web worker computation error. Fallback to main thread', e, s); Logs().e('Web worker computation error. Fallback to main thread', e, s);
return NativeImplementations.dummy.generateUploadKeys(args); return NativeImplementations.dummy.generateUploadKeys(args);
} }