[mob][photos] MVP logs working in isolate

This commit is contained in:
laurenspriem
2024-09-01 22:53:24 +02:00
parent a9bc6502cb
commit d40dc06171
6 changed files with 114 additions and 7 deletions

View 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);
}
}
}

View File

@@ -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();
}
}

View File

@@ -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);

View File

@@ -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;
}
}
}

View File

@@ -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 {

View File

@@ -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,