Should I Create a Thread When Handling Time-consuming Task in Message Handler?

What if current time-consuming task does not finish while another task come to message handler?

Message handlers work one-at-a-time, so if you need to perform long-running tasks, you will need to offload them. Running an asynchronous thread is a common solution, as long as your message pattern doesn't make more of them than your gateway can handle. If you need to queue tasks for multiple, but limited threads, you can use java to create a thread pool executor.

So what happens when the same message is caught by more than one handler ? Is there a way to know which one will execute first ?
Is that one handler at a time gateway-wide, or is the scope smaller ?

Phil's talking about gateway message handlers. I think you're talking about Perspective message handlers, which work differently.

1 Like

It would be good to document the constraints there, too. IIRC it's a queue per session?

Internally the event sending/receiving mechanism is different and likely lower latency, but the actual execution thread will be one from the 'worker' pool. You can configure the pools for blocking and non-blocking work separately:
Gateway Configuration File Reference - Ignition User Manual 8.1 - Ignition Documentation (until the docs are updated, use perspective-queue in the system props to adjust the blocking work thread pool)

Perspective message handlers are listening on a 'queue' thread, but automatically invoke their attached scripts on a 'worker' thread.

Got it, Turmel, thanks.

Since scripts in message handler is stateless (can't keep context), how to keep a thread pool among messages? Do your mean that unloading long-running tasks and send to a client project?

Top level variables in project script modules hold state until the projected is edited and saved. State can be held longer (with special care) using system.util.getGlobals(). I suggest using the latter to hold a single thread pool executor. (If you need to replace it, shut down the one before it.)

Search this forum for getGlobals for our accumulated wisdom. (:

2 Likes

I find that in [Gateway Event Scripts] Gateway Event Scripts - Ignition User Manual 8.1 - Ignition Documentation):

  • Threading - Determines the threading for the message handler. Contains the following options:
    • Shared - The default way of running a message handler. Will execute the handler on a shared pool of threads in the order that they are invoked. If too many message handlers are called all at once and they take long periods of time to execute, there may be delays before each message handler gets to execute.
    • Dedicated - The message handler will run on its own dedicated thread. This is useful when a message handler will take a long time to execute, so that it does not hinder the execution of other message handlers. Threads have a bit of overhead, so this option uses more of the Gateway's resources, but is desirable if you want the message handler to not be impeded by the execution of other message handlers.

So, message handler is excuted on a thread pool, and you don't have to create a thread to handle your scripts

This is true in the common case, but only when there's no other state that needs to carry over from one message to another, and you want the singulation of message handling.