[mob][photos] MVP logs working in isolate
This commit is contained in:
59
mobile/lib/core/error-reporting/isolate_logging.dart
Normal file
59
mobile/lib/core/error-reporting/isolate_logging.dart
Normal file
@@ -0,0 +1,59 @@
|
||||
import "dart:collection" show Queue;
|
||||
import "dart:convert" show jsonEncode, jsonDecode;
|
||||
|
||||
import "package:logging/logging.dart";
|
||||
import "package:photos/core/error-reporting/super_logging.dart";
|
||||
|
||||
class IsolateLogString {
|
||||
final String logString;
|
||||
final Object? error;
|
||||
|
||||
IsolateLogString(this.logString, this.error);
|
||||
|
||||
String toJsonString() => jsonEncode({
|
||||
'logString': logString,
|
||||
'error': error,
|
||||
});
|
||||
|
||||
static IsolateLogString fromJsonString(String jsonString) {
|
||||
final json = jsonDecode(jsonString);
|
||||
return IsolateLogString(
|
||||
json['logString'] as String,
|
||||
json['error'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class IsolateLogger {
|
||||
final Queue<IsolateLogString> fileQueueEntries = Queue();
|
||||
|
||||
Future onLogRecordInIsolate(LogRecord rec) async {
|
||||
final str = "[ISOLATE]" + rec.toPrettyString();
|
||||
|
||||
// write to stdout
|
||||
SuperLogging.printLog(str);
|
||||
|
||||
// push to log queue
|
||||
fileQueueEntries.add(IsolateLogString(str, rec.error != null));
|
||||
}
|
||||
|
||||
/// WARNING: only call this from the isolate
|
||||
Queue<String> getLogStringsAndClear() {
|
||||
if (fileQueueEntries.isEmpty) return Queue<String>();
|
||||
final result = Queue<String>();
|
||||
while (fileQueueEntries.isNotEmpty) {
|
||||
final entry = fileQueueEntries.removeFirst();
|
||||
result.add(entry.toJsonString());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// WARNING: only call this from the main thread
|
||||
static void handLogStringsToMainLogger(Queue<String> logs) {
|
||||
while (logs.isNotEmpty) {
|
||||
final logString = logs.removeFirst();
|
||||
final log = IsolateLogString.fromJsonString(logString);
|
||||
SuperLogging.saveLogString(log.logString, log.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,6 +270,10 @@ class SuperLogging {
|
||||
// write to stdout
|
||||
printLog(str);
|
||||
|
||||
saveLogString(str, rec.error);
|
||||
}
|
||||
|
||||
static void saveLogString(String str, Object? error) {
|
||||
// push to log queue
|
||||
if (fileIsEnabled) {
|
||||
fileQueueEntries.add(str + '\n');
|
||||
@@ -279,8 +283,8 @@ class SuperLogging {
|
||||
}
|
||||
|
||||
// add error to sentry queue
|
||||
if (sentryIsEnabled && rec.error != null) {
|
||||
_sendErrorToSentry(rec.error!, null).ignore();
|
||||
if (sentryIsEnabled && error != null) {
|
||||
_sendErrorToSentry(error, null).ignore();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import "dart:isolate";
|
||||
import "dart:typed_data" show Uint8List;
|
||||
|
||||
import "package:computer/computer.dart";
|
||||
import "package:flutter/foundation.dart" show kDebugMode;
|
||||
import "package:flutter/foundation.dart" show debugPrint, kDebugMode;
|
||||
import "package:logging/logging.dart";
|
||||
import "package:ml_linalg/dtype.dart";
|
||||
import "package:ml_linalg/vector.dart";
|
||||
@@ -120,7 +120,10 @@ class FaceClusteringService {
|
||||
/// The main execution function of the isolate.
|
||||
static void _isolateMain(SendPort mainSendPort) async {
|
||||
Logger.root.level = kDebugMode ? Level.ALL : Level.INFO;
|
||||
Logger.root.onRecord.listen(SuperLogging.onLogRecord);
|
||||
// TODO:lau move to right isolate logging
|
||||
Logger.root.onRecord.listen((LogRecord rec) {
|
||||
debugPrint('[MLIsolate] ${rec.toPrettyString()}');
|
||||
});
|
||||
final receivePort = ReceivePort();
|
||||
mainSendPort.send(receivePort.sendPort);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import "dart:collection" show Queue;
|
||||
import "dart:io" show File;
|
||||
import 'dart:isolate';
|
||||
import 'dart:typed_data' show Uint8List;
|
||||
@@ -6,7 +7,7 @@ import 'dart:typed_data' show Uint8List;
|
||||
import "package:dart_ui_isolate/dart_ui_isolate.dart";
|
||||
import "package:flutter/foundation.dart" show kDebugMode;
|
||||
import "package:logging/logging.dart";
|
||||
import "package:photos/core/error-reporting/super_logging.dart";
|
||||
import "package:photos/core/error-reporting/isolate_logging.dart";
|
||||
import "package:photos/models/ml/face/box.dart";
|
||||
import "package:photos/services/machine_learning/ml_model.dart";
|
||||
import "package:photos/services/machine_learning/semantic_search/clip/clip_text_encoder.dart";
|
||||
@@ -20,6 +21,7 @@ enum MLComputerOperation {
|
||||
loadModel,
|
||||
initializeClipTokenizer,
|
||||
runClipText,
|
||||
testLogging,
|
||||
}
|
||||
|
||||
class MLComputer {
|
||||
@@ -62,7 +64,8 @@ class MLComputer {
|
||||
@pragma('vm:entry-point')
|
||||
static void _isolateMain(SendPort mainSendPort) async {
|
||||
Logger.root.level = kDebugMode ? Level.ALL : Level.INFO;
|
||||
Logger.root.onRecord.listen(SuperLogging.onLogRecord);
|
||||
final IsolateLogger isolateLogger = IsolateLogger();
|
||||
Logger.root.onRecord.listen(isolateLogger.onLogRecordInIsolate);
|
||||
final receivePort = ReceivePort();
|
||||
mainSendPort.send(receivePort.sendPort);
|
||||
|
||||
@@ -106,6 +109,14 @@ class MLComputer {
|
||||
final textEmbedding = await ClipTextEncoder.predict(args);
|
||||
sendPort.send(List<double>.from(textEmbedding, growable: false));
|
||||
break;
|
||||
case MLComputerOperation.testLogging:
|
||||
final logger = Logger('XXX MLComputerTestLogging');
|
||||
logger.info("XXX logging from isolate is working!!!");
|
||||
final Queue<String> logStrings =
|
||||
isolateLogger.getLogStringsAndClear();
|
||||
final test = [List<String>.from(logStrings)];
|
||||
sendPort.send(test);
|
||||
break;
|
||||
}
|
||||
} catch (e, stackTrace) {
|
||||
sendPort
|
||||
@@ -221,4 +232,20 @@ class MLComputer {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> testLogging() async {
|
||||
try {
|
||||
final test = await _runInIsolate(
|
||||
(
|
||||
MLComputerOperation.testLogging,
|
||||
{},
|
||||
),
|
||||
) as List<List<String>>;
|
||||
IsolateLogger.handLogStringsToMainLogger(Queue.from(test[0]));
|
||||
return;
|
||||
} catch (e, s) {
|
||||
_logger.severe("XXX Could not test logging in isolate", e, s);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,10 @@ class MLIndexingIsolate {
|
||||
@pragma('vm:entry-point')
|
||||
static void _isolateMain(SendPort mainSendPort) async {
|
||||
Logger.root.level = kDebugMode ? Level.ALL : Level.INFO;
|
||||
Logger.root.onRecord.listen(SuperLogging.onLogRecord);
|
||||
// TODO:lau move to right isolate logging
|
||||
Logger.root.onRecord.listen((LogRecord rec) {
|
||||
debugPrint('[MLIsolate] ${rec.toPrettyString()}');
|
||||
});
|
||||
final receivePort = ReceivePort();
|
||||
mainSendPort.send(receivePort.sendPort);
|
||||
receivePort.listen((message) async {
|
||||
|
||||
@@ -3,6 +3,7 @@ import "package:photos/core/event_bus.dart";
|
||||
import "package:photos/db/ml/clip_db.dart";
|
||||
import "package:photos/db/ml/db.dart";
|
||||
import "package:photos/events/people_changed_event.dart";
|
||||
import "package:photos/services/machine_learning/ml_computer.dart";
|
||||
import "package:photos/services/machine_learning/semantic_search/semantic_search_service.dart";
|
||||
import "package:photos/theme/ente_theme.dart";
|
||||
import "package:photos/ui/components/buttons/button_widget.dart";
|
||||
@@ -55,6 +56,16 @@ class MLUserDeveloperOptions extends StatelessWidget {
|
||||
await deleteAllLocalML(context);
|
||||
},
|
||||
),
|
||||
// TODO:lau remove below code
|
||||
const SizedBox(height: 24),
|
||||
ButtonWidget(
|
||||
buttonType: ButtonType.neutral,
|
||||
labelText: "Log something in isolate",
|
||||
onTap: () async {
|
||||
await MLComputer.instance.testLogging();
|
||||
showShortToast(context, "Done");
|
||||
},
|
||||
),
|
||||
const SafeArea(
|
||||
child: SizedBox(
|
||||
height: 12,
|
||||
|
||||
Reference in New Issue
Block a user