Why is the thread locked having established connection? - tcp

Two programs connect to each other by loopback, program of client has established the connection successfully(59310->4001),but Then
the client soon is sleeping (some code reading inputstream is locked) ,see the picture underneath:
following are the sleeping code and locked code:
"Thread-2#6379" prio=5 tid=0x17 nid=NA runnable
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(SocketInputStream.java:-1)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.net.SocketInputStream.read(SocketInputStream.java:224)
at java.io.DataInputStream.readByte(DataInputStream.java:265)
at com.ib.client.EReader.readStr(EReader.java:892)
at com.ib.client.EReader.readInt(EReader.java:910)
at com.ib.client.EClientSocket.eConnect(EClientSocket.java:228)
- locked <0x18f4> (a com.service.ib.IBClient)
at com.ib.client.EClientSocket.eConnect(EClientSocket.java:185)
at com.service.ib.IBClient.connect(IBClient.java:88)
at com.service.ib.IBClient$1.run(IBClient.java:44)
why during the connection, the procedure of code is locked?
how to solve the problem?

Related

Jmeter testing Asp.net application get timeout

Problem:
I testing my asp.net webapi application in my server (use IIS) and Concurrency number is set to 2000,loop count is forever,and alter several second i get Connection timed out: connect error
what i have tried:
set http connect timeout and response timeout as 200000ms in jmeter gui.
set requestQueueLimit to 65535 and min process to 15 in IIS manager.
set minWorkerThread and minIoThread to 200 and timeout to 20 miniutes in web.config file and restart my application in IIS
None of the above worked,and i found the server's cpu usage has been low ,here is the screenshot when using jmeter to test:
cpu usage
jmeter screen shot
here is the error log:
org.apache.http.conn.HttpHostConnectException: Connect to XXX.XXX.com:80 [XXX.XXXX.com/XXXX] failed: Connection timed out: connect
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:156)
at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl$JMeterDefaultHttpClientConnectionOperator.connect(HTTPHC4Impl.java:408)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.executeRequest(HTTPHC4Impl.java:939)
at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(HTTPHC4Impl.java:650)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:66)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1301)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1290)
at org.apache.jmeter.threads.JMeterThread.doSampling(JMeterThread.java:651)
at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:570)
at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:501)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:268)
at java.lang.Thread.run(Unknown Source)
Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
Check Maximum Concurrent Connections and other limits in your web site configuration: Advanced Settings->Limits->Maximum Concurrent Connections
It may be not connected with IIS at all and the timeout can happen at your website level due to incorrect database configuration or inefficient algorithms used. Consider re-running your test with profiler tool telemetry like YourKit or dotTrace - it will give you full information regarding what's going on under the hood
Don't run load tests using JMeter GUI, it's only for tests development and debugging, when it comes to execution you should be running your JMeter tests in command-line non-GUI mode
Remove all the listeners, they don't add any value and just consume valuable resources

Qt: Detect a QTcpSocket disconnection in a console app when the user closes it

My question title should be enough. I already tried (without success):
Using a C-style destructor in a function: __attribute__((destructor)):
void sendToServerAtExit() __attribute__((destructor)) {
mySocket->write("$%BYE_CODE%$");
}
The application destructor is called, but the socket is already disconnected and I can't write to the server.
Using the standard C function atexit(), but the TCP connection is already lost so I can't send anything to the server.
atexit(sendToServerAtExit); // is the same function of point 1
The solution I found is check every second if all connected sockets are still connected, but I don't want to do so inefficient thing. It's only a temporary solution. Also, I want that others apps (even web ones) can join the chat room of my console app, and I don't want to request data every second.
What should I do?
Handle the below signal (QTcpSocket is inherited from QAbstractSocket)
void QAbstractSocket::stateChanged(QAbstractSocket::SocketState socketState)
Inside the slot called, check if socketState is QAbstractSocket::ClosingState.
QAbstractSocket::ClosingState indicates the socket is about to close.
http://doc.qt.io/qt-5/qabstractsocket.html#SocketState-enum
You can connect a slot to the disconnect signal.
connect(m_socket, &QTcpSocket::disconnected, this, &Class::clientDisconnected);
Check the documentation.
You can also know which user has been disconnected using a slot like this:
void Class::clientDisconnected
{
QTcpSocket* client = qobject_cast<QTcpSocket*>(sender());
if(client)
{
// Do something
client->deleteLater();
}
else
{
// Handle error
}
}
This method is usefull if you have a connections pool. You can use it as well if you have a single connection, but do not forget nullptr after client->deleteLater().
If I understand you question correctly, you want to send data over TCP to notify the remote computer that you are closing the socket.
Technically this can be done in Qt by listenning to the QIODevice::aboutToClose() or QAbstractSocket::stateChanged() signals.
However, if you graciously exit your program and close the QTcpSocket by sending a FIN packet to the remote computer. This means that on the remote computer,
the running program will be notified that the TCP connection finished. For instance, if the remote program is also using QTcpSocket, the QAbstractSocket::disconnected()
signal will be emitted.
The real issues arise when one of the program does not graciously exit (crash, hardware issue, cable unplugged, etc.). In this case, the TCP FIN packet will
not be sent and the remote computer will never get notified that the other side of the TCP connection is disconnected. The TCP connection will just time-out after a few minutes.
However, in this case you cannot send your final piece of data to the server either.
In the end the only solution is to send a "I am here" packet every now and then. Even though you claim it is ineficient, it is a widely used technique and it also has the advantage that it works.

Log4j2 in async mode still blocks on java.util.concurrent.lock under heavy load

I am trying to log in a low-latency environment.
2 high priority threads are calling log.error() in a tight loop (1Mmessages/s)
I want to use Async logging (with the disruptor) and to discard any excess messages. So the calling thread should NEVER block.
However, the jstack clearly shows it is blocking about 100 times/s.
Is it my configuration which is wrong ?
Or is the blocking inevitable if the buffer fill up ?
java -Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
-Dlog4j2.AsyncQueueFullPolicy=Discard
-Dlog4j2.DiscardThreshold=Trace
-DAsyncLogger.RingBufferSize=2000000 TestLog
"TT0" #14 prio=5 os_prio=0 tid=0x00007fe8cc690800 nid=0x2463 runnable [0x00007fe8ae70d000]
java.lang.Thread.State: RUNNABLE
at sun.misc.Unsafe.unpark(Native Method)
at java.util.concurrent.locks.LockSupport.unpark(LockSupport.java:141)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.unparkSuccessor(AbstractQueuedSynchronizer.java:662)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1264)
at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457)
at com.lmax.disruptor.BlockingWaitStrategy.signalAllWhenBlocking(BlockingWaitStrategy.java:72)
at com.lmax.disruptor.MultiProducerSequencer.publish(MultiProducerSequencer.java:218)
at com.lmax.disruptor.RingBuffer.translateAndPublish(RingBuffer.java:934)
at com.lmax.disruptor.RingBuffer.publishEvent(RingBuffer.java:444)
at com.lmax.disruptor.dsl.Disruptor.publishEvent(Disruptor.java:245)
at org.apache.logging.log4j.core.async.AsyncLogger.logMessage(AsyncLogger.java:285)
at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:727)
at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:716)
at org.apache.logging.log4j.spi.AbstractLogger.debug(AbstractLogger.java:232)
at TestLog$WriteToFile.run(TestLog.java:53)
at java.lang.Thread.run(Thread.java:745)
"AsyncLogger-1" #12 daemon prio=5 os_prio=0 tid=0x00007fe8cc96f800 nid=0x2460 waiting on condition [0x00007fe8b4187000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007104a0f28> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at com.lmax.disruptor.BlockingWaitStrategy.waitFor(BlockingWaitStrategy.java:45)
at com.lmax.disruptor.ProcessingSequenceBarrier.waitFor(ProcessingSequenceBarrier.java:55)
at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:123)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
The LMAX Disruptor allows you to choose what the background thread should do when it's waiting for work to arrive.
By default Log4j2 uses the BlockingWaitStrategy. This gives the behavior you are seeing, which is appropriate for most situations but perhaps not in ultra low latency use cases.
If you can dedicate a core to the background thread you can use the BusySpin wait strategy.
See https://github.com/apache/logging-log4j2/blob/master/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorUtil.java

In Jmeter's TCP Sampler: what's the difference between no "Re-use connection" vs "Re-use + Close connection"?

I'm new to using JMeter, and I found that in the TCP Sampler (Jmeter version 2.11) there are 2 checkboxes labeled "Re-use Connection" and "Close Connection". So the documentation says this:
Re-use connection: If selected, the connection is kept open. Otherwise it is closed when the data has been read.
Close connection: If selected, the connection will be closed after running the sampler.
So from what I understand, it is the same to not check Re-use Connection than to check both Re-use Connection and Close Connection, is it? Then what's the point of checking both?
Basically each thread group can have several threads running under it, so the re-use mean It get reused. Please read the following explanation.
If "Re-use connection" is selected, connections are shared between Samplers in the same thread, provided that the exact same host name string and port are used. Different hosts/port combinations will use different connections, as will different threads. If both of "Re-use connection" and "Close connection" are selected, the socket will be closed after running the sampler. On the next sampler, another socket will be created. You may want to close a socket at the end of each thread loop. If an error is detected - or "Re-use connection" is not selected - the socket is closed. Another socket will be reopened on the next sample.

QTimer, QThread, and TCP messaging

Qt 4.8, Windows XP:
I have a thread that manages my TCP messages and opens / maintains / closes the socket at the appropriate times.
This same thread starts a QTimer, 200 ms, defined in my thread's data, that pumps an event in my thread's class once (if) the socket is open. So the timer and its event belong to the thread, as best I understand the idea.
The QTimer timeout event sends a TCP message through the port belonging to the thread, it's a keep-alive message for this particular hardware item. Has to be sent regularly or the device "goes away" which won't do.
When the message is sent, I get this error:
"QSocketNotifier: socket notifiers cannot be enabled from another thread"
As far as I can tell, I am sending the message from the same thread and would expect any signals, etc., to be owned / handled etc. by it.
Can anyone tell me what I'm missing here?
PS: The message is sent, the device does stay alive... it's just that I'm getting this runtime error on the Qt error console and I'm very concerned that there are internal problems lurking because of it.
The message does NOT occur running under OS X 10.6. I don't know why.
Ok, here's the scoop. QTimer, for reason only known to the designers of QT, inherits the context of the parent of the thread. Not the context of the thread it's launched from. So when the timer goes off, and you send a message from the slot it called, you're not in the thread's context, you're in the parents context.
You also can't launch a thread that is child of THAT thread, so that you can fire a timer that will actually be in the thread you want. Qt won't let it run.
So, spend some memory, make a queue, load the message into the queue from elsewhere, watch the queue in the thread that owns the TCP port, and send em when ya got em. That works.

Resources