Skip to content

Commit 0de063d

Browse files
committed
refactor(livesync): handle cases when livesync thread dies or is interrupted
1 parent 9071988 commit 0de063d

File tree

1 file changed

+53
-25
lines changed

1 file changed

+53
-25
lines changed

test-app/app/src/debug/java/com/tns/NativeScriptSyncService.java

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ private class LocalServerSocketThread implements Runnable {
3434
private volatile boolean running;
3535
private final String name;
3636

37-
private ListenerWorker commThread;
38-
private LocalServerSocket serverSocket;
37+
private LiveSyncWorker livesyncWorker;
38+
private LocalServerSocket deviceSystemSocket;
3939

4040
public LocalServerSocketThread(String name) {
4141
this.name = name;
@@ -45,7 +45,7 @@ public LocalServerSocketThread(String name) {
4545
public void stop() {
4646
this.running = false;
4747
try {
48-
serverSocket.close();
48+
deviceSystemSocket.close();
4949
} catch (IOException e) {
5050
e.printStackTrace();
5151
}
@@ -54,20 +54,34 @@ public void stop() {
5454
public void run() {
5555
running = true;
5656
try {
57-
serverSocket = new LocalServerSocket(this.name);
57+
deviceSystemSocket = new LocalServerSocket(this.name);
5858
while (running) {
59-
LocalSocket socket = serverSocket.accept();
60-
commThread = new ListenerWorker(socket);
61-
new Thread(commThread).start();
59+
LocalSocket systemSocket = deviceSystemSocket.accept();
60+
livesyncWorker = new LiveSyncWorker(systemSocket);
61+
Thread livesyncThread = setUpLivesyncThread();
62+
livesyncThread.start();
6263
}
6364
} catch (IOException e) {
6465
e.printStackTrace();
6566
}
6667
}
6768

69+
@NonNull
70+
private Thread setUpLivesyncThread() {
71+
Thread livesyncThread = new Thread(livesyncWorker);
72+
livesyncThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
73+
@Override
74+
public void uncaughtException(Thread t, Throwable e) {
75+
logger.write(String.format("%s(%s): %s", t.getName(), t.getId(), e.toString()));
76+
}
77+
});
78+
livesyncThread.setName("Livesync Thread");
79+
return livesyncThread;
80+
}
81+
6882
@Override
6983
protected void finalize() throws Throwable {
70-
this.serverSocket.close();
84+
deviceSystemSocket.close();
7185
}
7286
}
7387

@@ -77,7 +91,7 @@ public void startServer() {
7791
localServerJavaThread.start();
7892
}
7993

80-
private class ListenerWorker implements Runnable {
94+
private class LiveSyncWorker implements Runnable {
8195
public static final int OPERATION_BYTE_SIZE = 1;
8296
public static final int FILE_NAME_LENGTH_BYTE_SIZE = 5;
8397
public static final int CONTENT_LENGTH_BYTE_SIZE = 10;
@@ -107,13 +121,13 @@ private class ListenerWorker implements Runnable {
107121
FILE_CONTENT_LENGTH, CONTENT_LENGTH_BYTE_SIZE,
108122
FILE_CONTENT);
109123
private final InputStream input;
110-
private Closeable socket;
124+
private Closeable livesyncSocket;
111125
private OutputStream output;
112126

113-
public ListenerWorker(LocalSocket socket) throws IOException {
114-
this.socket = socket;
115-
input = socket.getInputStream();
116-
output = socket.getOutputStream();
127+
public LiveSyncWorker(LocalSocket systemSocket) throws IOException {
128+
this.livesyncSocket = systemSocket;
129+
input = systemSocket.getInputStream();
130+
output = systemSocket.getOutputStream();
117131
}
118132

119133
public void run() {
@@ -155,13 +169,28 @@ public void run() {
155169
logger.write(String.format("Error while LiveSyncing: %s", e.toString()));
156170
e.printStackTrace();
157171
exceptionWhileLivesyncing = true;
172+
flushInputStream();
173+
} catch (Throwable e) {
174+
logger.write(String.format("%s(%s): Error while LiveSyncing.\nOriginal Exception: %s", Thread.currentThread().getName(), Thread.currentThread().getId(), e.toString()));
175+
try {
176+
this.livesyncSocket.close();
177+
} catch (IOException e1) {
178+
e1.printStackTrace();
179+
}
158180
}
159181

160182
if (!exceptionWhileLivesyncing) {
161183
runtime.runScript(new File(NativeScriptSyncService.this.context.getFilesDir(), "internal/livesync.js"));
162184
}
163185
}
164186

187+
private void flushInputStream() {
188+
try {
189+
this.input.skip(1000000);
190+
} catch (IOException e) {
191+
}
192+
}
193+
165194
/*
166195
* Tries to read operation input stream
167196
* If the stream is empty, method returns -1
@@ -177,9 +206,9 @@ private int getOperation() {
177206
operation = Integer.parseInt(new String(operationBuff));
178207

179208
} catch (NumberFormatException e) {
180-
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s. %s\noriginal exception: %s", OPERATION, LIVESYNC_ERROR_SUGGESTION, e.toString()));
209+
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s. %s\nOriginal Exception: %s", OPERATION, LIVESYNC_ERROR_SUGGESTION, e.toString()));
181210
} catch (Exception e) {
182-
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s. %s\noriginal exception: %s", OPERATION, LIVESYNC_ERROR_SUGGESTION, e.toString()));
211+
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s. %s\nOriginal Exception: %s", OPERATION, LIVESYNC_ERROR_SUGGESTION, e.toString()));
183212
}
184213
return operation;
185214
}
@@ -194,7 +223,7 @@ private String getFileName() {
194223
fileNameLengthBuffer = readNextBytes(FILE_NAME_LENGTH_BYTE_SIZE);
195224

196225
} catch (Exception e) {
197-
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s. %s\noriginal exception: %s", FILE_NAME_LENGTH, LIVESYNC_ERROR_SUGGESTION, e.toString()));
226+
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s. %s\nOriginal Exception: %s", FILE_NAME_LENGTH, LIVESYNC_ERROR_SUGGESTION, e.toString()));
198227
}
199228

200229
if (fileNameLengthBuffer == null) {
@@ -206,9 +235,9 @@ private String getFileName() {
206235
fileNameBuffer = readNextBytes(fileNameLenth);
207236

208237
} catch (NumberFormatException e) {
209-
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s. %s\noriginal exception: %s", FILE_NAME, LIVESYNC_ERROR_SUGGESTION, e.toString()));
238+
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s. %s\nOriginal Exception: %s", FILE_NAME, LIVESYNC_ERROR_SUGGESTION, e.toString()));
210239
} catch (Exception e) {
211-
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s. %s\noriginal exception: %s", FILE_NAME, LIVESYNC_ERROR_SUGGESTION, e.toString()));
240+
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s. %s\nOriginal Exception: %s", FILE_NAME, LIVESYNC_ERROR_SUGGESTION, e.toString()));
212241
}
213242

214243
if (fileNameBuffer == null) {
@@ -230,7 +259,7 @@ private byte[] getFileContent(String fileName) throws IllegalStateException {
230259
try {
231260
contentLength = readNextBytes(CONTENT_LENGTH_BYTE_SIZE);
232261
} catch (Exception e) {
233-
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s %s. %s\noriginal exception: %s", fileName, FILE_CONTENT_LENGTH, LIVESYNC_ERROR_SUGGESTION, e.toString()));
262+
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s %s. %s\nOriginal Exception: %s", fileName, FILE_CONTENT_LENGTH, LIVESYNC_ERROR_SUGGESTION, e.toString()));
234263
}
235264

236265
if (contentLength == null) {
@@ -242,9 +271,9 @@ private byte[] getFileContent(String fileName) throws IllegalStateException {
242271
contentBuff = readNextBytes(contentL);
243272

244273
} catch (NumberFormatException e) {
245-
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s %s. %s\noriginal exception: %s", fileName, FILE_CONTENT_LENGTH, LIVESYNC_ERROR_SUGGESTION, e.toString()));
274+
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s %s. %s\nOriginal Exception: %s", fileName, FILE_CONTENT_LENGTH, LIVESYNC_ERROR_SUGGESTION, e.toString()));
246275
} catch (Exception e) {
247-
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s %s. %s\noriginal exception: %s", fileName, FILE_CONTENT, LIVESYNC_ERROR_SUGGESTION, e.toString()));
276+
throw new IllegalStateException(String.format("\nLiveSync: failed to parse %s %s. %s\nOriginal Exception: %s", fileName, FILE_CONTENT, LIVESYNC_ERROR_SUGGESTION, e.toString()));
248277
}
249278

250279
if (contentBuff == null) {
@@ -264,7 +293,7 @@ private void createOrOverrideFile(String fileName, byte[] content) throws IOExce
264293
fos.close();
265294

266295
} catch (Exception e) {
267-
throw new IOException(String.format("\nLiveSync: failed to write file: %s\noriginal exception: %s", fileName, e.toString()));
296+
throw new IOException(String.format("\nLiveSync: failed to write file: %s\nOriginal Exception: %s", fileName, e.toString()));
268297
}
269298
}
270299

@@ -311,8 +340,7 @@ private byte[] readNextBytes(int size) throws IOException {
311340

312341
@Override
313342
protected void finalize() throws Throwable {
314-
this.socket.close();
343+
this.livesyncSocket.close();
315344
}
316-
317345
}
318346
}

0 commit comments

Comments
 (0)