Android Question Job.GetRequest.Timeout don´t work

Jose Cuevas

Member
Licensed User
Longtime User
Hi, my App consumes a REST API, but I don't want to wait more than 6 seconds for the response, I use the Job.GetRequest.Timeout = 6000, but there are many times that it waits up to 40 seconds, it doesn't respect the 6 seconds of the Job.GetRequest .Timeout. This is my code:

B4X:
    Dim XJob As HttpJob
    XJob.Initialize("FEL", Me)
    XJob.PostString("www.url.com", XML)
    XJob.GetRequest.SetContentType("application/xml")
    XJob.GetRequest.SetHeader("User", "12345")
    XJob.GetRequest.SetHeader("Password", "12345")
    XJob.GetRequest.Timeout = 6000     '6 seconds

    Wait For (XJob) JobDone(XJob As HttpJob)

    If XJob.Success Then
        sJSON = XJob.GetString
        ...............

I'm not sure if the position of the GetRequest.Timeout is correct.

I will appreciate any help you can give me.

Regards,
 

drgottjr

Expert
Licensed User
Longtime User
the timeout is for the connection. okclients have 3 timeouts available (connection, read, write).
they can all be set individually, but i do not believe the implementation that we use does this.
the connection timeout defintely works, so your statement to the contrary is not correct. it's doing
what it's supposed to do, just not what you want it to do.

i have a small okhttp client which i have used to test the various timeouts. it is possible to set a
read timeout independently of a connection timeout and cause timeout exceptions for each. for
your case use, you might have to write a java routine or possibly a javaobject wrap from b4a. you
might be able to incorporate it into okhttputils. i don't know how determined you are to make it
work like you want.
 
Upvote 0

Jose Cuevas

Member
Licensed User
Longtime User
the timeout is for the connection. okclients have 3 timeouts available (connection, read, write).
they can all be set individually, but i do not believe the implementation that we use does this.
the connection timeout defintely works, so your statement to the contrary is not correct. it's doing
what it's supposed to do, just not what you want it to do.

i have a small okhttp client which i have used to test the various timeouts. it is possible to set a
read timeout independently of a connection timeout and cause timeout exceptions for each. for
your case use, you might have to write a java routine or possibly a javaobject wrap from b4a. you
might be able to incorporate it into okhttputils. i don't know how determined you are to make it
work like you want.

Thanks drgottjr for your answer, that means, the connection was made in less than 6 seconds, what is taking more than 6 seconds is the response.

Could you share your small okhttp client code, maybe I find something that helps me.

Thanks in advance.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
yes, the connection is made in less than 6 seconds (it almost always would be). the response timeout is something different.

my okhttp client tests a lot of different things that have nothing to do with timeouts.
just start here: https://www.baeldung.com/okhttp-timeouts
to see how to control connection, read and write timeouts. you're going to have to handle everything yourself in java. if you're comfortable with that, fine. okhttp is easy enough to work with.
i'm still hoping (for you) that there is a way to control the read timeout from b4a (probably with a javaobject), but i don't have the time to test it. someone else may see the thread and respond.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
in looking at the okhttp.jar library that we use for okhttputils, it appears that the connection,
read and write timeouts for the okhttpclient are all set to default at 30 seconds.

the httpjob.getrequest.timeout refers to the okhttprequest, which is different from the okhttpclient
(although obviously related).

timeouts for the client are set when the okhttpclient is built. but it is possible to modify timeouts
on a per request basis. in theory, you are supposed to reuse the same client. there is an example of
this here:
https://github.com/square/okhttp/bl...ain/java/okhttp3/recipes/PerCallSettings.java

the example specifically changes the readtimeout. i don't know whether this means that is the only
setting you can modify or if that was the only one modified for the example.

without being able to test the url you are using, i can't say more.
 
Upvote 0

Jose Cuevas

Member
Licensed User
Longtime User
Thank you very much drgottjr I can't test too, because it fails in a specific rural area with bad cellular signal, but I will keep investigating how to fix this.

Regards,
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
something else you should be aware of: if the connection is lost, okhttp is designed to keep trying (silently). that could extend (reset) or even override the timeout. you should read about okhttp's behavior and why it's used nowadays.

you might have to set your own timer and cut the connection yourself. there is an example in the forum about closing the socket. it pertains to downloading a large file where the user wants to cancel the operation. i would imagine it could be used with a timer if things are taking too long. i'll search for the thread and post it if i find it.

EDIT: see if this is it. read carefully. there is a cancel sub. you understand okhttputils is written in b4x (not java), so you can modify it. okhttputils2.b4xlib is just a zip archive. if you change the extension to "zip", you can unzip it to see the b4x code modules. it was designed this way. keep this in mind as you read the
link.
https://www.b4x.com/android/forum/threads/download-huge-files-with-httputils2.30220/#content
 
Last edited:
Upvote 0

Jose Cuevas

Member
Licensed User
Longtime User
something else you should be aware of: if the connection is lost, okhttp is designed to keep trying (silently). that could extend (reset) or even override the timeout. you should read about okhttp's behavior and why it's used nowadays.

you might have to set your own timer and cut the connection yourself. there is an example in the forum about closing the socket. it pertains to downloading a large file where the user wants to cancel the operation. i would imagine it could be used with a timer if things are taking too long. i'll search for the thread and post it if i find it.
I already disabled the silent retry with this code:

B4X:
Sub RetryOff
    
    Dim jo As JavaObject = HttpUtils2Service.hc
    Dim builder As JavaObject = jo.RunMethod("sharedInit", Array("hc"))
    builder.RunMethod("retryOnConnectionFailure", Array(False))
    jo.SetField("client", builder.RunMethod("build", Null))
    
End Sub
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
if you're using your own httpclient (which would have been helpful to know before), you might as well add the readtimeout to your builder and see if it works. but since you can't duplicate the issue, you'll have to wait until somebody says something to you.
 
Upvote 0
Top