Bug? HttpJob - certainly a problem maybe a bug?

JackKirk

Well-Known Member
Licensed User
Longtime User
I am going to stick my neck out here and claim I have found a bug in HttpJob.

You might like to get some coffee before you start rummaging through the following.

I have been using HttpJob forever to run AWS services (S3, Recognition, Translate, SQS, SNS, ...) without problems - but always in the context of UI B4J apps.

I am currently deep into developing a web app on top of ABMaterial - a non-UI app that requires some adjustment to HttpJob as discussed here:

https://www.b4x.com/android/forum/threads/server-jokhttputils2-server-version.124350/#content
https://www.b4x.com/android/forum/t...-jokhttputils2-server-version-working.163667/

If I run the app in Debug mode it all works fine.

If I run it in Release mode the Translate calls fail randomly but heavily.

My web app (like its sister B4A and B4i apps) does on the fly translations when it detects a browser language other than English.

Its a bit more sophisticated than that - any translation is only done once then remembered for later reuse.

The HttpJob part of a typical Translate HttpJob looks something like:

B4X:
        AWS_translate_job.Initialize("name", Me)
        AWS_translate_job.PostString(wrk_AWS_Translate.URI, wrk_AWS_Translate.AWS_Translate_Request_JSON)        'Retrieve full header map

        add various headers

        'Finally add Authorization header to Http_Job
        AWS_translate_job.GetRequest.SetHeader("Authorization", wrk_AWS_Translate.Authorization)

        'Wait for TranslateText job to finish
        Wait For (AWS_translate_job) JobDone(Job As Http_Job)

When the AWS_translate_job.PostString call is made you are actually calling HttpJob:

B4X:
'Sends a POST request with the given data as the post data.
Public Sub PostString(Link As String, Text As String)
    PostBytes(Link, Text.GetBytes("UTF8"))
End Sub

'Sends a POST request with the given data as the post data
Public Sub PostBytes(Link As String, Data() As Byte)
    Try
        Link = AddScheme(Link)
        req.InitializePost2(Link, Data)
    Catch
        req.InitializePost2(InvalidURL, Data)
    End Try
    CallSubDelayed2(Http_Utils2_Service, "SubmitJob", Me)
End Sub

And you are supposed to be able to add your headers between when
........req.InitializePost2(Link, Data)
is executed, initializing the job and the
........CallSubDelayed2(Http_Utils2_Service, "SubmitJob", Me)
which submits the job.

The Translate calls I make are pretty short - typically only 40+ characters.

After a lot of mucking around I developed the theory that what is happening is the
........CallSubDelayed2(Http_Utils2_Service, "SubmitJob", Me)
is firing before the
........AWS_translate_job.GetRequest.SetHeader("Authorization", wrk_AWS_Translate.Authorization)
call is being made - resulting in various error messages that pretty obliquely indicate a lack of authorization.

I believe I have proved this theory with the fix I have developed:

1. In HttpJob I comment out all statements of the form:
........CallSubDelayed2(Http_Utils2_Service, "SubmitJob", Me)
2. To HttpJob I added another sub:

B4X:
'Submits job
Public Sub Submit ()
    CallSubDelayed2(Http_Utils2_Service, "SubmitJob", Me)
End Sub

3. Then in my code, after the:
........AWS_translate_job.GetRequest.SetHeader("Authorization", wrk_AWS_Translate.Authorization)
I add:
........AWS_translate_job.Submit

This has the effect of always only submitting the job after all headers have been added

This works flawlessly.

I guess I could be missing something...
 
Last edited:

JackKirk

Well-Known Member
Licensed User
Longtime User
The CallSubDelayed will never trigger before the Wait For line, unless your code calls Sleep or Wait For somewhere before.
Erel, yes I initially suspected that and went looking for such a culprit - couldn't find one anywhere.

Is there any way to track down something like that?

It does not negate the fix - surely HttpJob should be robust enough to cope with such a situation.

Another solution I looked at was to check the authorization had been made in HttpUtils2Service.SubmitJob but couldn't find a way to do it - this would be a minimal fix that wouldn't require any changes by the user.
 
Last edited:

JackKirk

Well-Known Member
Licensed User
Longtime User
The CallSubDelayed will never trigger before the Wait For line, unless your code calls Sleep or Wait For somewhere before.
As the app I am developing is sitting on top of ABMaterial I guess it is possible Sleeps or Wait Fors are occurring in there which I can't see - in which case my fix (or something like it) is essential.
 
Top