Socket Timeout Exception

I have 2 buckets, the first one consists of 1.5million records inside, the second one has only 100 records.

Clients (android devices) get socket timeout error (which I shared below) almost every once in a week while trying to pull replication from the first bucket, and nothing can fix the problem unless creating a new bucket after getting this exception. But however the second bucket works without problem.

There are 2 differences between them

  1. As I said early, first bucket has 1.5million records, the other bucket has only 100 records.
  2. Before using first bucket, I download a zipped db and unzip it on the clients (it would take a long time to sync 1.5 million records), however for the second one I dont use zipped db because its got only 100 records.

Does the record count may cause this difference which is one can replicate the other one can not? What I dont understand how it works for 5-10 days and suddenly starts to throw socket timeout exception. why It does not recreate socket for the connection, why I need to recreate another bucket to make the replication as is. What causes this problem in core library?

01-15 19:38:48.049 18906-18939/amonsis.android.MaviAndroid.development D/CouchbaseDatabaseHelper>>413: Incoming data public channel
01-15 19:39:08.356 18906-18937/amonsis.android.MaviAndroid.development W/ChangeTracker: ChangeTracker{http://xxxxx/yyyyyy/, OneShot, @14915773}: Exception in change tracker
java.net.SocketTimeoutException
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
at okio.Okio$2.read(Okio.java:139)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:237)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:345)
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:217)
at okhttp3.internal.http1.Http1Codec.readHeaderLine(Http1Codec.java:212)
at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:189)
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:88)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:125)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
at okhttp3.RealCall.execute(RealCall.java:77)
at com.couchbase.lite.replicator.ChangeTracker.runLoop(ChangeTracker.java:336)
at com.couchbase.lite.replicator.ChangeTracker.run(ChangeTracker.java:246)
at java.lang.Thread.run(Thread.java:818)

Hi @mustafaguven,

SocketTimeoutException is usually thrown in case that the client socket does not receive any data for the specified duration, CBL uses 40 sec. To avoid the timeout, SG sends CRLF, we call it “heartbeat”, to CBL every 30 sec, CBL for Android specify. If no network error, SocketTimeoutException should not occur. However, as SocketTimoutException is a transient error, so CBL should retry replication.

I wonder other error might occur in CBL or SG side. Can you find other error in CBL log or SG log? It might help to debug this issue.

Thanks!
Hideki

It should not related to timeout imho because when I replace the bucket it starts to sync again by the same record set and it keeps running for 6-7 days and suddenly something happens at somewhere and begins to throw socket timeout exception. All the devices are across the country can not get synced so it should not be caused by the network.

Your Java socket is timing out means that it takes too long to get respond from other device and your request expires before getting response. This exception is occurring on following condition.

  • Server is slow and default timeout is less, so just put timeout value according to you.
  • Server is working fine but timeout value is for less time. so change the timeout value.

Solution: A developer can pre-set the timeout option for both client and server operations.

From Client side:

Socket socket = new Socket();
SocketAddress socketAddress = new InetSocketAddress(host, port);
socket.connect(socketAddress, 12000); //12000 are milli seconds

From Server side:

ServerSocket serverSocket = new new ServerSocket(port);
serverSocket.setSoTimeout(12000);