Skip to content

Commit 2c733b7

Browse files
committed
fix: Add failure robustness
In some edge cases the RPC server would not be started even though it's the first app instance. This has no been fixed.
1 parent 7c30db2 commit 2c733b7

File tree

1 file changed

+50
-36
lines changed

1 file changed

+50
-36
lines changed

lib/flutter_single_instance.dart

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -100,76 +100,85 @@ abstract class FlutterSingleInstance {
100100
/// Returns true if this is the first instance of the app.
101101
/// Automatically writes a pid file to the temp directory if this is the first instance.
102102
Future<bool> isFirstInstance() async {
103-
if (debugMode) {
104-
logger.finest("Debug mode enabled, reporting as first instance");
105-
return true;
106-
}
107-
108103
var processName = await getProcessName(pid); // get name of current process
109104
processName!;
110105

111106
var pidFile = await getPidFile(processName);
112107
pidFile!;
113108

114-
if (!pidFile.existsSync()) {
115-
logger.finest("No pid file found, activating instance");
109+
Future<bool> check() async {
110+
if (debugMode) {
111+
logger.finest("Debug mode enabled, reporting as first instance");
112+
return true;
113+
}
116114

117-
// No pid file, so this is the first instance.
118-
await activateInstance(processName);
119-
return true;
120-
}
115+
if (!pidFile.existsSync()) {
116+
logger.finest("No pid file found, activating instance");
121117

122-
final data = await pidFile.readAsString();
118+
// No pid file, so this is the first instance.
119+
return true;
120+
}
123121

124-
final json;
122+
final data = await pidFile.readAsString();
125123

126-
try {
127-
json = jsonDecode(data);
128-
} catch (e, s) {
129-
logger.finest("Pid file is wrong format, assuming first instance", e, s);
130-
return true;
131-
}
124+
final json;
125+
126+
try {
127+
json = jsonDecode(data);
128+
} catch (e, s) {
129+
logger.finest(
130+
"Pid file is wrong format, assuming first instance", e, s);
131+
return true;
132+
}
133+
134+
_instance = Instance.fromJson(json);
135+
136+
logger.finest("Pid file found, verifying instance: $_instance");
132137

133-
_instance = Instance.fromJson(json);
138+
final pidName = await getProcessName(_instance!.pid);
134139

135-
logger.finest("Pid file found, verifying instance: $_instance");
140+
if (processName == pidName) {
141+
logger.finest(
142+
"Process name matches $processName, reporting as second instance",
143+
);
136144

137-
final pidName = await getProcessName(_instance!.pid);
145+
// Process exists, so this is not the first instance.
146+
return false;
147+
}
138148

139-
if (processName == pidName) {
140149
logger.finest(
141-
"Process name matches $processName, reporting as second instance",
150+
"Process name does not match $processName, activating instance",
142151
);
143-
144-
// Process exists, so this is not the first instance.
145-
return false;
152+
return true;
146153
}
147154

148-
logger.finest(
149-
"Process name does not match $processName, activating instance",
150-
);
155+
final isFirstInstance = await check();
151156

152-
// Process does not exist, so we can activate this instance.
153-
await activateInstance(processName);
157+
if (isFirstInstance) await activateInstance(processName);
154158

155-
return true;
159+
return isFirstInstance;
156160
}
157161

158162
/// Activates the first instance of the app and writes a pid file to the temp directory.
159163
@protected
160164
Future<void> activateInstance(String processName) async {
161165
var pidFile = await getPidFile(processName);
162166

163-
if (pidFile?.existsSync() == false) await pidFile?.create();
167+
if (pidFile == null) {
168+
logger.finest("Failed to retrieve process name, aborting");
169+
return;
170+
}
171+
172+
if (pidFile.existsSync() == false) await pidFile.create();
164173

165174
final instance = Instance(
166175
pid: pid,
167176
port: await startRpcServer(),
168177
);
169178

170-
await pidFile?.writeAsString(jsonEncode(instance.toJson()));
179+
await pidFile.writeAsString(jsonEncode(instance.toJson()));
171180

172-
logger.finest("Activated $instance at ${pidFile?.path}");
181+
logger.finest("Activated $instance at ${pidFile.path}");
173182
}
174183

175184
/// Returns the pid file.
@@ -183,6 +192,11 @@ abstract class FlutterSingleInstance {
183192
/// Starts an RPC server that listens for focus requests.
184193
@protected
185194
Future<int> startRpcServer() async {
195+
if (_server != null) {
196+
logger.finest("RPC server already started");
197+
return _server!.port!;
198+
}
199+
186200
logger.finest("Starting RPC server");
187201

188202
_server = Server.create(

0 commit comments

Comments
 (0)