B4J Question B4J Server SingleThreadHandler API Issue

prajinpraveen

Active Member
Licensed User
Longtime User
The code works in B4J debug mode and in Release mode only when SingleThreadHandler is set to True

b4j2:
srvr.AddHandler("/" & ABMShared.AppName & "/api", "Services", True) ' OPTIONAL


b4j:
    Log("GetBearerToken")
    Dim Job As HttpJob
    Job.Initialize("token", Me)
    Job.PostString(tokenurl, "")
    Job.GetRequest.SetContentType("application/json;charset=UTF-8")
    Job.GetRequest.SetHeader("Authorization", GetBasicAuthHeader(tokenclient,tokenclientsecret))
    Job.GetRequest.SetHeader("x-api-key", tokenapikey)
   
    Wait For (Job) JobDone(Job As HttpJob)
 
    If Job.Success Then
        Log("Done")
'        Log(Job.GetString)
        Try
            Dim tokenmap As Map = ABMShared.Json2Map(Job.GetString)
            Log(tokenmap)
        Catch
            Log(LastException)
        End Try
       
    End If
    Job.Release

b4j2:
Sub GetBasicAuthHeader(clientId As String, clientSecret As String) As String
    Dim su As StringUtils
    Dim auth As String = clientId & ":" & clientSecret
    Dim b() As Byte = auth.GetBytes("UTF8")
    Dim encoded As String = su.EncodeBase64(b)
    Return "Basic " & encoded
End Sub

is it possible to make it work with Mulithread or is it safe to use SingleThreadHandler = True
 

Alessandro71

Well-Known Member
Licensed User
Longtime User
you haven't clearly stated what is not working in release mode.
try commenting out one statement a time, and see which one is causing the failure.
is that all the code inside the handler?
maybe the culprit is somewhere else
 
Upvote 0

prajinpraveen

Active Member
Licensed User
Longtime User
Thank you

In debug mode or in singlethread, the http post works. In release or multithread it fails.

I have commented every other code to figure where the problem is.
 
Upvote 0

Alessandro71

Well-Known Member
Licensed User
Longtime User
have you seen this thread?
 
Upvote 0

prajinpraveen

Active Member
Licensed User
Longtime User
some feedback.

1. Add the SERVER conditional symbol to the build configuration (Ctrl + B).
2. Add a reference to jBuilderUtils. Library: https://www.b4x.com/android/forum/attachments/jbuilderutils-zip.41578/
3. The library code calls Main.srvr.CreateThreadSafeMap. If you named your server object differently then you need to add such public global variable and assign it the server object.

Result - Pass. Debug Mode, B4J BackgroundWorker has a timer. Calls a API in a Standard Class.
Result - Fail. Release Mode, B4J BackgroundWorker has a timer. Calls a API in a Standard Class.
Result - Pass. Release Mode, B4J BackgroundWorker has a timer. Calls a API on Main Module, using CallDelayedSub2.
Result - Pass. Release Mode, Main Module has a timer. Calls a API in a Standard Class..

Fail is when i get a 401 unathorized response from the API

Am i doing anything wrong?
Is it safe to run a timer in the Main Class and perform certain operations every xx minutes
 
Upvote 0

Alessandro71

Well-Known Member
Licensed User
Longtime User
since "B4J BackgroundWorker" and "Calls a API in a Standard Class" are unknown in this thread, the only possible advice is "be aware that using globals/singleinstance objects in a multithreaded environment must be serialized with locks or something similar".
the Pass/Fail list seem to pinpoint a concurrency issue as above.
 
Upvote 0

prajinpraveen

Active Member
Licensed User
Longtime User
B4J:
' Background Worker

Sub Class_Globals
    Dim backgroundtimer1 As Timer
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
    Log("Background Timer Class initialized")
    backgroundtimer1.Initialize("backgroundtimer1",3600000)
    backgroundtimer1.Enabled = True   
    StartMessageLoop
End Sub

Sub backgroundtimer1_Tick
    Dim PG As PayloadGenerator
    PG.Initialize
    PG.PostOrderEvents("{orderid:10}")
End Sub


B4J1:
' PayloadGenerator Class

Sub PostOrderEvents(responsebody As String) As ResumableSub
    Log("PostOrderEvents")
    
    Dim Job As HttpJob
    Job.Initialize("orderevent", Me)
    Job.PostString(codebn4l.OrderEventURL, responsebody)
    Job.GetRequest.SetContentType("application/json;charset=UTF-8")
    Job.GetRequest.SetHeader("Authorization", "Bearer " & codebn4l.token)

'    Log(codebn4l.token)
    
    If codebn4l.token = "" Or codebn4l.token = Null Then
        Log("Token is missing!")
        Return "Token Error"
    End If
    
    Wait For (Job) JobDone(Job As HttpJob)
    Log(Job.Success)
    
    If Job.Success Then
        Log("Done")
        Log(Job.GetString)
    End If
    Job.Release
    
    Return "X"
End Sub

codebn4l is a code module, that generates token every few minutes. I have tried hard coding the token in the payloadgenerator class, still fails with 401 error
 
Upvote 0
Top