B4J Question [ Jserver ] I have questions about threadsafe in code modules and about my room search algorithm

Waldemar Lima

Well-Known Member
Licensed User
Longtime User
Hello guys, Does anyone have experience with jserver to help me improve this algorithm to the point of making it threadsafe and avoiding possible memory leaks?
*Are code modules threadsafe?
*Is there a possibility that the way I am integrating, there is concatenation of objects?

I'm making an algorithm for searching and creating rooms which I put in a CodeModule. :

RoomManager:
Sub FindOrCreateRoom(sm_matchfilters As Map,userConnID As Int) As String
    'Log("Init Function")
    Dim ReqFilters As Int = sm_matchfilters.Size
    'Log("Number of Rooms created : "&Matchs.Size)
    For Each Rooms As String In Matchs.Keys
        'Log("Entered in the room list ")
        Dim CurRoom As MatchRoom = Matchs.Get(Rooms)
        Dim CurFilters As Int = 0
     
        For Each FilterName As String In sm_matchfilters.Keys
            'Log("Entered filtering")
            Dim FilterOperator As String = sm_matchfilters.Get(FilterName)
         
            If (FilterName = "RoomSizeMax") Then
             
'                Log("FilterOperator = "&FilterOperator)
             
                If (CurRoom.MatchDetails.Get("RoomSize") < FilterOperator) Then
                    'Log("satisfied roomsize parameters")
                    Log("["&userConnID&"] Roomsize = "&CurRoom.MatchDetails.Get("RoomSize"))
                    CurFilters = CurFilters + 1
                Else
                    LogError("["&userConnID&"] *****Full Room*******")
                End If
             
            Else If (FilterName = "RoomType") Then
             
                If (CurRoom.MatchDetails.Get("RoomType") = FilterOperator) Then
                    'Log("satisfied roomtype parameters")
                    CurFilters = CurFilters + 1
                 
                End If
         
            Else
             
                If (CurRoom.MatchDetails.Get(FilterName) = FilterOperator) Then
                    'Log("parameters satisfied anyway")
                    CurFilters = CurFilters + 1
                    Continue
                End If
                 
            End If

            If (CurFilters = ReqFilters) Then
                'Log("satisfied parameters")
                Return CurRoom.MatchID
            End If

        Next

    Next


    LogError("["&userConnID&"] ####Creating new room###### ")
    Dim NewMatchRoom As MatchRoom
    NewMatchRoom.Initialize
    NewMatchRoom.MatchID = Utils.GenGUID
    NewMatchRoom.MatchDetails.Initialize '= sm_matchfilters
    NewMatchRoom.MatchDetails.Put("RoomType","1")
    NewMatchRoom.MatchDetails.Put("RoomSize","0")

    NewMatchRoom.UserList.Initialize

    Matchs.Put(NewMatchRoom.MatchID,NewMatchRoom)
    Return NewMatchRoom.MatchID

End Sub

Sub EnterRoom(idsala As String,idwscon As WebSocket,userConnID As Int) As Int
   
    If (Matchs.ContainsKey(idsala)) Then
        Dim EditMatchRoom As MatchRoom
        EditMatchRoom = Matchs.Get(idsala)
        Dim tmpnegosala As Int = EditMatchRoom.MatchDetails.Get("RoomSize")
        EditMatchRoom.MatchDetails.Put("RoomSize",""&(tmpnegosala+1))
        EditMatchRoom.UserList.Add(idwscon)
        Log("["&userConnID&"] Entrou na sala.")
        Return EditMatchRoom.MatchDetails.Get("RoomSize")
    Else
        Log("room dont exists :" &idsala)
        Return -1
    End If
   
End Sub

I'm calling this function above in a websockethandler class in jserver .
which I would like each connection to do the search and get the return of the room's uuid...

the websocket class code below:

UserConnection:
'WebSocket class
Sub Class_Globals
    Private ws As WebSocket
    Private Global_SalaAtual As String
    Private Global_CurrentConnectionId As Int
End Sub

Public Sub Initialize
 
End Sub

Private Sub WebSocket_Connected (WebSocket1 As WebSocket)
    ws = WebSocket1
    Main.connNum = Main.connNum + 1
    Log("------> CONECTOU [ "&Main.connNum&" ] <------")
    Global_CurrentConnectionId = Main.connNum
End Sub

Private Sub WebSocket_Disconnected
    Log("disconectado.")
End Sub

Sub Device_FindMatch(Params As Map)
    Dim sala As String = RoomManager.FindOrCreateRoom(Params,Global_CurrentConnectionId)
    Log("["&Global_CurrentConnectionId&"] Room Available : "&sala)
    Global_SalaAtual = sala
    RoomManager.EnterRoom(sala,ws,Global_CurrentConnectionId)
    Dim resp As List
    resp.Initialize
    resp.Add("waiting-players")
    ws.RunFunction("room_matchfound",resp)
    ws.Flush
End Sub

main code :

main.bas:
Sub Process_Globals
    Public srvr As Server
    Public connNum As Int = 0
End Sub

Sub AppStart (Args() As String)
 
    srvr.Initialize("srvr")
    srvr.Port = 51042
    srvr.StaticFilesFolder = File.Combine(File.DirApp, "www")
    srvr.AddWebSocket("/app", "UserConnection")
    srvr.Start
    StartMessageLoop
    'open browser and navigate to: http://127.0.0.1:51042/
End Sub

I created a clientwebsocket to test the load that the algorithm is supporting and I use this to create the websocketclient connections :
B4X:
    For i = 1 To 100

        Dim wsh As WebSocketHandler
        wsh.Initialize(Me,"wsh")
        wsh.Connect("ws://127.0.0.1:51042/app")
        Wait For wsh_Connected
        Log("connected "&i)
        Dim tmp As Map
        tmp.Initialize
        tmp.Put("RoomType", "1")
        tmp.Put("RoomSizeMax", "4")
        wsh.SendEventToServer("Device_FindMatch",tmp)
        Sleep(1)
    Next

According to your more experienced vision, how can I improve this algorithm? o_Oo_Oo_Oo_Oo_Oo_O

Can anyone help me with this ?
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0
Top