grasping at straws

This commit is contained in:
Matthew Fosse 2024-07-26 14:34:11 -05:00
parent 083810be99
commit 5ee99b1a34
8 changed files with 108 additions and 57 deletions

View file

@ -789,6 +789,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
}
Future<StatusResponse> getStatusRequest() async {
await getStub();
final resp = await _stub.status(StatusRequest());
return resp;
}

View file

@ -11,6 +11,7 @@ public class CwMwebPlugin: NSObject, FlutterPlugin {
private static var server: MwebdServer?
private static var port: Int = 0
private static var dataDir: String?
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
@ -18,54 +19,53 @@ public class CwMwebPlugin: NSObject, FlutterPlugin {
result("iOS " + UIDevice.current.systemVersion)
case "start":
let args = call.arguments as? [String: String]
// print("args: \(args)")
let dataDir = args?["dataDir"]
var error: NSError?
if dataDir == "stop" && CwMwebPlugin.server != nil {
print("Stopping server")
CwMwebPlugin.server?.stop()
CwMwebPlugin.server = nil
result(0)
return
}
if CwMwebPlugin.server == nil {
CwMwebPlugin.server = MwebdNewServer("", dataDir, "", &error)
if let server = CwMwebPlugin.server {
do {
print("starting server \(CwMwebPlugin.port)")
try server.start(0, ret0_: &CwMwebPlugin.port)
result(CwMwebPlugin.port)
} catch let startError as NSError {
print("Server Start Error: \(startError.localizedDescription)")
result(FlutterError(code: "Server Start Error", message: startError.localizedDescription, details: nil))
}
} else if let error = error {
print("Server Creation Error: \(error.localizedDescription)")
result(FlutterError(code: "Server Creation Error", message: error.localizedDescription, details: nil))
} else {
print("Unknown Error: Failed to create server")
result(FlutterError(code: "Unknown Error", message: "Failed to create server", details: nil))
}
} else {
print("Server already running on port: \(CwMwebPlugin.port)")
// result(FlutterError(code: "Server Already Running", message: "The server is already running", details: nil))
result(CwMwebPlugin.port)
}
// result(0)
default:
result(FlutterMethodNotImplemented)
}
CwMwebPlugin.dataDir = dataDir
startServer(result: result)
case "stop":
stopServer()
result(nil)
default:
result(FlutterMethodNotImplemented)
}
}
deinit {
print("Stopping and cleaning up server")
// Perform cleanup tasks
CwMwebPlugin.server?.stop()
CwMwebPlugin.server = nil
}
}
private func startServer(result: @escaping FlutterResult) {
if CwMwebPlugin.server == nil {
var error: NSError?
CwMwebPlugin.server = MwebdNewServer("", CwMwebPlugin.dataDir, "", &error)
if let server = CwMwebPlugin.server {
do {
print("Starting server...")
try server.start(0, ret0_: &CwMwebPlugin.port)
print("Server started successfully on port: \(CwMwebPlugin.port)")
result(CwMwebPlugin.port)
} catch let startError as NSError {
print("Server Start Error: \(startError.localizedDescription)")
result(FlutterError(code: "Server Start Error", message: startError.localizedDescription, details: nil))
}
} else if let error = error {
print("Server Creation Error: \(error.localizedDescription)")
result(FlutterError(code: "Server Creation Error", message: error.localizedDescription, details: nil))
} else {
print("Unknown Error: Failed to create server")
result(FlutterError(code: "Unknown Error", message: "Failed to create server", details: nil))
}
} else {
print("Server already running on port: \(CwMwebPlugin.port)")
result(CwMwebPlugin.port)
}
}
private func stopServer() {
print("Stopping server")
CwMwebPlugin.server?.stop()
CwMwebPlugin.server = nil
CwMwebPlugin.port = 0
}
deinit {
stopServer()
}
}

View file

@ -6,22 +6,50 @@ import 'mwebd.pbgrpc.dart';
class CwMweb {
static RpcClient? _rpcClient;
static ClientChannel? _clientChannel;
static int? _port;
static Future<RpcClient> stub() async {
static Future<void> _initializeClient() async {
final appDir = await getApplicationSupportDirectory();
int port = await CwMwebPlatform.instance.start(appDir.path) ?? 0;
_port = await CwMwebPlatform.instance.start(appDir.path);
if (_port == null || _port == 0) {
throw Exception("Failed to start server");
}
print("Attempting to connect to server on port: $_port");
_clientChannel = ClientChannel('127.0.0.1',
port: port,
port: _port!,
options: const ChannelOptions(
credentials: ChannelCredentials.insecure(),
keepAlive: ClientKeepAliveOptions(permitWithoutCalls: true),
));
_rpcClient = RpcClient(_clientChannel!);
return _rpcClient!;
}
static Future<RpcClient> stub({int maxRetries = 3}) async {
for (int i = 0; i < maxRetries; i++) {
try {
if (_rpcClient == null || _clientChannel == null) {
await _initializeClient();
} else {
// Try to use the existing connection
var status = await _rpcClient!
.status(StatusRequest(), options: CallOptions(timeout: const Duration(seconds: 10)));
if (status != null) {
return _rpcClient!;
}
}
} catch (e) {
print("Attempt $i failed: $e");
if (i == maxRetries - 1) rethrow;
await stop();// call stop so we create a new instance before retrying
await Future.delayed(Duration(seconds: 2)); // Wait before retrying
}
}
throw Exception("Failed to connect after $maxRetries attempts");
}
static Future<void> stop() async {
await CwMwebPlatform.instance.start("stop");
await CwMwebPlatform.instance.stop();
await cleanup();
}
@ -29,5 +57,6 @@ class CwMweb {
await _clientChannel?.terminate();
_rpcClient = null;
_clientChannel = null;
_port = null;
}
}

View file

@ -14,4 +14,9 @@ class MethodChannelCwMweb extends CwMwebPlatform {
final result = await methodChannel.invokeMethod<int>('start', {'dataDir': dataDir});
return result;
}
@override
Future<void> stop() async {
await methodChannel.invokeMethod<void>('stop');
}
}

View file

@ -26,4 +26,8 @@ abstract class CwMwebPlatform extends PlatformInterface {
Future<int?> start(String dataDir) {
throw UnimplementedError('start() has not been implemented.');
}
Future<void> stop() {
throw UnimplementedError('stop() has not been implemented.');
}
}

View file

@ -144,4 +144,11 @@ import workmanager
}
}
@objc func applicationWillTerminate(_ notification: Notification) {
// Call the stop method on your plugin
if let plugin = self.registrar(forPlugin: "CwMwebPlugin")?.valuePublished(byPlugin: "CwMwebPlugin") as? CwMwebPlugin {
plugin.stop()
}
}
}

View file

@ -84,6 +84,7 @@ void callbackDispatcher() {
} else {
syncStatus = 1;
}
print("Sync status ${syncStatus}");
});
for (int i = 0;; i++) {
@ -91,8 +92,6 @@ void callbackDispatcher() {
if (syncStatus == 1) {
print("sync done!");
break;
} else {
print("Sync status ${syncStatus}");
}
if (i > 600) {
return Future.error("Synchronization Timed out");
@ -199,7 +198,7 @@ class BackgroundTasks {
await Workmanager().initialize(
callbackDispatcher,
isInDebugMode: kDebugMode,
isInDebugMode: true,
);
final inputData = <String, dynamic>{"sync_all": syncAll};
@ -262,5 +261,11 @@ class BackgroundTasks {
print(error);
print(stackTrace);
}
try {
Workmanager().cancelByUniqueName(mwebSyncTaskKey);
} catch (error, stackTrace) {
print(error);
print(stackTrace);
}
}
}

View file

@ -31,7 +31,7 @@ void startWalletSyncStatusChangeReaction(
await WakelockPlus.disable();
}
} catch (e) {
print(e.toString());
// print(e.toString());
}
});
}