Permalink
Browse files

Client reader stability - runaway thread fix

-keepalive timerTask is now closed with swarm session
-socket read timeout shortened to 2 seconds
-readerThread better non-blocking (catch SocketTimeoutException)
-opted to remove raw message debug by default
-cleaned up printlns a little
  • Loading branch information...
1 parent 5904936 commit a840f4f723497beb0270ef11e471bad3a43c8eb8 @theterg theterg committed Jul 2, 2012
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: BUGswarm ReST Client
Bundle-SymbolicName: com.buglabs.bug.swarm.client
-Bundle-Version: 1.0.0.qualifier
+Bundle-Version: 1.0.1
Bundle-Vendor: Bug Labs, Inc.
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package:
@@ -5,6 +5,7 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
+import java.net.SocketTimeoutException;
import java.util.List;
import java.util.Map;
@@ -64,7 +65,16 @@ public void run() {
readinput:
try {
- while ((line = reader.readLine()) != null) {
+ while (!shuttingDown) {
+ try {
+ line = reader.readLine();
+ } catch (SocketTimeoutException e) {
+ continue;
+ }
+ if (line == null){
+ System.out.println("["+this.getClass().getSimpleName()+"]: "+"read a null line, quitting");
+ break;
+ }
line = line.trim();
//Filter empty lines and line length lines.
if (line.length() == 0 || isNumeric(line))
@@ -145,8 +155,10 @@ public void run() {
} catch (IOException e) {
disconnectMessage = e.getMessage();
} catch (InterruptedException e) {
+ System.out.println("["+this.getClass().getSimpleName()+"]: "+"Interrupted: Quitting");
return;
} finally {
+ System.out.println("["+this.getClass().getSimpleName()+"]: "+"Quitting");
//Relying on first element of listeners being the SwarmSessionImpl. See line 56.
if (!shuttingDown)
listeners.get(0).exceptionOccurred(ExceptionType.SERVER_UNEXPECTED_DISCONNECT, disconnectMessage);
@@ -233,13 +245,10 @@ private boolean isNumeric(String in) {
}
private void debugOut(String message, boolean out) {
- System.out.print(apiKey.substring(0, 4));
if (out)
- System.out.print(" --> ");
+ System.out.println("["+this.getClass().getSimpleName()+"]: "+apiKey.substring(0, 4)+" --> "+message);
else
- System.out.print(" <-- ");
-
- System.out.println(message);
+ System.out.println("["+this.getClass().getSimpleName()+"]: "+apiKey.substring(0, 4)+" <-- "+message);
}
/**
@@ -44,6 +44,7 @@
private boolean keepalive;
private boolean autoreconnect;
private long timestamp;
+ private final Timer keepaliveTimer;
/**
* @param hostname host of server
@@ -69,6 +70,7 @@ public SwarmSessionImp(String hostname, ISwarmSession.SessionType type, int port
this.listeners = new CopyOnWriteArrayList<ISwarmMessageListener>();
this.listeners.add(this);
this.socket = createSocket(hostname, port);
+ this.keepaliveTimer = new Timer();
sendHeader();
if (keepalive)
@@ -79,14 +81,13 @@ public SwarmSessionImp(String hostname, ISwarmSession.SessionType type, int port
//the local timestamp to the global. if they're the same
//no message has been sent, send a \n, otherwise just keep truckin
private void createKeepAliveThread() {
- final Timer timer = new Timer();
- timer.schedule(new TimerTask() {
+ keepaliveTimer.schedule(new TimerTask() {
private long localtimestamp = timestamp;
public void run() {
if (localtimestamp==timestamp){
try {
- writeOut("\n");
+ writeOut("\r\n");
} catch (IOException e) {
e.printStackTrace();
}
@@ -101,7 +102,7 @@ public void run() {
private Socket createSocket(String hostname, int port) throws UnknownHostException, IOException {
Socket socket = new Socket(hostname, port);
- socket.setSoTimeout(60000);
+ socket.setSoTimeout(2000);
this.soutput = socket.getOutputStream();
if (readerThread != null)
@@ -264,13 +265,10 @@ public void join(String swarmId, String resourceId) throws IOException {
* @param out
*/
private void debugOut(String message, boolean out) {
- System.out.print(apiKey.substring(0, 4));
if (out)
- System.out.print(" --> ");
+ System.out.println("["+this.getClass().getSimpleName()+"]: "+"["+this.getClass().getSimpleName()+"]: "+apiKey.substring(0, 4)+" --> "+message);
else
- System.out.print(" <-- ");
-
- System.out.println(message);
+ System.out.println("["+this.getClass().getSimpleName()+"]: "+apiKey.substring(0, 4)+" <-- "+message);
}
/**
@@ -322,6 +320,7 @@ private void debugOut(String message, boolean out) {
*/
private void writeOut(String message) throws IOException {
if (!isConnected() && autoreconnect) {
+ System.out.println("["+this.getClass().getSimpleName()+"]: "+"Connection closed when trying to write, reconnecting to swarm");
this.socket = createSocket(hostname, port);
sendHeader();
}
@@ -349,6 +348,7 @@ public void removeListener(ISwarmMessageListener listener) {
@Override
public void close() {
+ keepaliveTimer.cancel();
if (readerThread != null)
readerThread.shuttingDown();
@@ -377,6 +377,7 @@ public void close() {
readerThread.interrupt();
readerThread = null;
}
+ System.out.println("["+this.getClass().getSimpleName()+"]: "+"Swarm Session closed.");
}
@Override
@@ -392,6 +393,7 @@ public void presenceEvent(String fromSwarm, String fromResource, boolean isAvail
@Override
public void exceptionOccurred(ExceptionType type, String message) {
+ System.out.println("["+this.getClass().getSimpleName()+"]: "+"Swarm exception["+type+"]: "+message);
if (type == ExceptionType.SERVER_UNEXPECTED_DISCONNECT) {
try {
this.socket = createSocket(hostname, port);

0 comments on commit a840f4f

Please sign in to comment.