From 29ade9b7b09b6afe4a8635c521869721dc109f18 Mon Sep 17 00:00:00 2001 From: wcrisman Date: Wed, 10 Dec 2014 16:31:22 -0800 Subject: [PATCH] Simplified writeOutgoingMessages() and removed the call to internalProcessResponses(). Likely bugs in writeClientBoundMessage(). --- .../com/foundation/web/server/WebServer.java | 149 +++++++++++------- 1 file changed, 91 insertions(+), 58 deletions(-) diff --git a/Foundation Web Core/src/com/foundation/web/server/WebServer.java b/Foundation Web Core/src/com/foundation/web/server/WebServer.java index db76728..de3f66e 100644 --- a/Foundation Web Core/src/com/foundation/web/server/WebServer.java +++ b/Foundation Web Core/src/com/foundation/web/server/WebServer.java @@ -1651,24 +1651,100 @@ public class WebServer { * @see com.foundation.web.server.WebServer.AbstractSocketContext#processResponses() */ protected void writeOutgoingMessages() throws IOException { - if(getPassThroughSocketContext() != null) { - //Synchronized to avoid multiple threads accessing the pendingOutboundMessage chain at one time and updating the write flag out of order (could happen if we enabled request chaining over a single socket).// - synchronized(this) { - writeClientBoundMessage(); - }//synchronized// + Debug.log(id + "," + System.nanoTime() + "," + "Writing outgoing messages."); + if(key.channel().isOpen() && currentOutboundMessage != null) { + writeClientBoundMessage(); }//if// - else if(isWebsocket) { - //Right after upgrading the socket we have one last HTTP response to process.// - if(currentResponse != null) { - internalProcessResponses(); + else { + Debug.log(id + "," + System.nanoTime() + "," + "No outgoing messages to write!."); + }//else// +//OLD CODE +// if(getPassThroughSocketContext() != null) { +// //Synchronized to avoid multiple threads accessing the pendingOutboundMessage chain at one time and updating the write flag out of order (could happen if we enabled request chaining over a single socket).// +// synchronized(this) { +// writeClientBoundMessage(); +// }//synchronized// +// }//if// +// else if(isWebsocket) { +// //Right after upgrading the socket we have one last HTTP response to process.// +// if(currentResponse != null) { +// writeClientBoundMessage(); +// }//if// +// +// internalProcessWebsocketMessages(); +// }//else if// +// else { +// //Go directly to writing the client response if we are just passing everything through to another process.// +// internalProcessResponses(); +// }//else// +//NEW CODE +// boolean keepSending = true; +// +// //Synchronized to avoid multiple threads accessing the currentOutboundMessage chain at one time.// +// synchronized(this) { +// keepSending = currentOutboundMessage != null; +// }//synchronized// +// +// //Keep sending responses while the buffers are not full and there is another response to send.// +// while(key.channel().isOpen() && keepSending) { +// //Send the pending response object's prepared buffer of data.// +// writeClientBoundMessage(); +// +// //If we finished the message then load the next message, otherwise flag that we need to stop sending (buffers full - flag a write on the socket's key and wait).// +// if(currentOutboundMessage.isClosed()) { +// //Synchronized to avoid multiple threads accessing the currentOutboundMessage chain at one time.// +// synchronized(this) { +// currentOutboundMessage = currentOutboundMessage.getNext(); +// keepSending = currentOutboundMessage != null; +// }//synchronized// +// }//if// +// else { +// keepSending = false; +// }//else// +// }//while// + }//writeOutgoingMessages()// + /** + * @return + */ + private synchronized void internalProcessResponses() { + boolean finishedSending = true; + + //Keep sending responses while the buffers are not full and there is another response to send.// + while(finishedSending && currentResponse != null) { + //If the socket is open then send the next buffer of data.// + if(key.channel().isOpen()) { + //Send the pending response object's prepared buffer of data.// + finishedSending = writeClientBoundMessage(); }//if// - internalProcessWebsocketMessages(); - }//else if// - else { - //Go directly to writing the client response if we are just passing everything through to another process.// - internalProcessResponses(); - }//else// + //Close the response if successfully sent, or if the socket is closed.// + if(finishedSending || !key.channel().isOpen()) { + try {currentResponse.close();} catch(Throwable e) {} + }//if// + + //If we finished sending the current response then load the next one.// + if(finishedSending) { + currentResponse = currentResponse.getNextResponse(); + + if(currentResponse == null) { + lastResponse = null; + }//if// + else if(key.channel().isOpen()) { + //Prep the next response object for sending.// + prepareResponse(); + }//else// + else { + //Clean up after all the left over responses.// + while(currentResponse != null) { + currentResponse.close(); + currentResponse = currentResponse.getNextResponse(); + }//while// + + currentResponse = null; + lastResponse = null; + }//else// + }//if// + }//while// }//processCurrentResponse()// /** * Loads the next outbound websocket message and attempts to write it to the socket until all outbound messages have been sent, or the socket's buffers are full and a wait is required. @@ -1794,49 +1870,6 @@ public class WebServer { websocketStreamingMessage = null; }//else// }//loadNextWebsocketMessage()// - /** - * @return - */ - private synchronized void internalProcessResponses() { - boolean finishedSending = true; - - //Keep sending responses while the buffers are not full and there is another response to send.// - while(finishedSending && currentResponse != null) { - //If the socket is open then send the next buffer of data.// - if(key.channel().isOpen()) { - //Send the pending response object's prepared buffer of data.// - finishedSending = writeClientBoundMessage(); - }//if// - - //Close the response if successfully sent, or if the socket is closed.// - if(finishedSending || !key.channel().isOpen()) { - try {currentResponse.close();} catch(Throwable e) {} - }//if// - - //If we finished sending the current response then load the next one.// - if(finishedSending) { - currentResponse = currentResponse.getNextResponse(); - - if(currentResponse == null) { - lastResponse = null; - }//if// - else if(key.channel().isOpen()) { - //Prep the next response object for sending.// - prepareResponse(); - }//else// - else { - //Clean up after all the left over responses.// - while(currentResponse != null) { - currentResponse.close(); - currentResponse = currentResponse.getNextResponse(); - }//while// - - currentResponse = null; - lastResponse = null; - }//else// - }//if// - }//while// - }//processCurrentResponse()// /** * Sends a response to the client. * @return Whether the response could be fully sent. This will be false if there is still more data to be written when the call returns.