B4J Question Start a sub on a new thread / Run code on different threads

quique

Member
Licensed User
Longtime User
Hi there folks,

Not the easiest topic to search in b4j forum "start a new thread" or "new thread" :) Keep getting tons of "Place the question in a new thread" kind of answers :)

I have the following situation:

I am receiving MQTT packets. Each packet is used for doing some calculations and processing and finally I store it into MYSQL. This needs to happen at the best possible speed (which currently is working fine).

But then, if a particular MQTT message arrives, I need to also perform a second processing over it. But I do not need to pause or slow the main "task" of calculation and processing.

I need this second processing to happen concurrently on a new thread. This second processing may need to send one or more MQTT messages, and also will be stored in yet another table, on mysql. So it WILL take some time. This is why I need it to happen separately. There will be no GUI output, it's all "internal" working.

In short, how can I call a sub making it start on a separate thread ? Is this possible at all ?

Regards,

Enrique

p.d. I understand that multithreading is not a good thing on B4J (unless working with the web server library) so any suggestions or alternatives are welcome!
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Please edit the title and make it relevant to the question.

I understand that multithreading is not a good thing on B4J
Not exactly correct. Many things are multithreaded.

1. Sending MQTT messages is multithreaded. It will not affect the main thread.

2. Use the async SQL methods. They will also not affect the main thread.

3. Always make sure to test performance in release mode.
 
Upvote 0

quique

Member
Licensed User
Longtime User
Erel, thanks for answering, I just edited my question's title.

I understand that certain libraries are multithreaded.

As said, I need to keep receiving and storing incoming MQTT messages as fast as possible.

But some of the received MQTT messages need an extra analysis, taking some (variable) time since I might need to answer with another mqtt message, or even send an email.

So I wanted to know if it is possible to start a new thread inside my code, passing the needed data so I can accomplish this extra analysis task independently.

I am sure this has been already discussed in the forum, I just couldn't find it. :( Any pointers are welcome :)
 
Last edited:
Upvote 0

MarkusR

Well-Known Member
Licensed User
Longtime User
As I understand it
u can use "Wait For" that await ending other sub call.
this example simulate endless calculation and the timer event comes each 3 seconds.

B4J
B4X:
Sub Process_Globals
    Private Timer1 As Timer

B4X:
Sub AppStart (Form1 As Form, Args() As String)
    
    Timer1.Initialize("Timer1",3000)
    Timer1.Enabled=True

B4X:
Sub Timer1_Tick
    
    Log("Tick")
    
    Wait For(WaitDo) Complete (Result As Boolean)
    
End Sub

Sub WaitDo As ResumableSub

    Log("Do something")
    
    Do Until 1=0
        Sleep(0)
    Loop

    Return True
    
End Sub
 
Upvote 0

quique

Member
Licensed User
Longtime User
I need more information before I can answer. What are you doing with the messages? How are they processed? Which step is slow?

Let me see how can I illustrate it better


B4X:
'CALLBACK WHEN MQTT MESSAGE ARRIVES (We save the message into MySql)

Private Sub mqtt_MessageArrived (Topic As String, Payload() As Byte)

'do some stuff with the payload, segment it into different information bits

'CHECK FOR A PARTICULAR FLAG inside the Payload() and if PRESENT, launch another Sub, in another thread, so it doesn't block this at all, and the next instruction can be executed as fast and early as possible.

'Save all bits into Mysql

End Sub

The Sub I need to launch inside another thread, may end up taking several seconds for completing its tasks, because it needs to:

1) do a mysql query ...
2) maybe send email(s)
3) maybe send other mqtt messages
4) maybe interact with a hardware / arduino based board and send some SMS.
and end.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
as much as I understand (and if I get it wrong, hopefully I find out here), you can process information inside mqtt_MessageArrived without blocking the next mqtt_MessageArrived. So if you receive a packet and mqtt_MessageArrived receives the packet and you process the packet, the next incoming message will run another mqtt_MessageArrived, even though you’re not finished with the next one. Now if you need to process the messages in order, you may need to implement a queue system on the incoming mqtt messages.
 
Upvote 0

quique

Member
Licensed User
Longtime User
as much as I understand (and if I get it wrong, hopefully I find out here), you can process information inside mqtt_MessageArrived without blocking the next mqtt_MessageArrived. So if you receive a packet and mqtt_MessageArrived receives the packet and you process the packet, the next incoming message will run another mqtt_MessageArrived, even though you’re not finished with the next one. Now if you need to process the messages in order, you may need to implement a queue system on the incoming mqtt messages.

Nice ! If this is so, then I got no problem at all with my code. @Erel please can you confirm that whenever a new MQTT message arrives, the ...

B4X:
Private Sub mqtt_MessageArrived (Topic As String, Payload() As Byte)

Will be invoked and executed, even if an earlier mqtt message is still being processed in another instance of the same sub ?

This would be perfect for me, no need for manually launching threads or any other cumbersome idea.
 
Upvote 0

quique

Member
Licensed User
Longtime User
Put it simpler, when using MQTT library, whenever a packet arrives, the ...

B4X:
Private Sub mqtt_MessageArrived (Topic As String, Payload() As Byte)

Inside the Main module code, will be called and run, regardless than an earlier call to the same sub has been made earlier and is still working with that earlier mqtt packet ?
 
Upvote 0
Top