caveat: i haven’t used max much in a long time, like since version 5 (when immediate was introduced, iirc), and mostly on version 4.5. but these were topics of interest then, when mxj and js were new (and, unfortunately many of the c74 articles on the topic seem to be dated from that era.) but i did have to do some max 7 work for a gig recently and had some contact with these issues (receiving lots of soft-realtime network data in max, with some js in the patch.)
so, fwiw…
maybe, maybe not. at least one form of priority inversion was possible in max 5 even when using immediate. the example from that article: if you have something coming off the high-priority thread (like a MIDI note) and you even just pass it through a message box before sending it into js, then your javascript function using it will be deferred to the queue even if it is declared immediate, because UI events have to happen on the queue. but if literally none of your inputs to js come from UI elements, then yeah you’re probably right.
iirc, the best way to ensure that javascript executes on the high-priority thread is to wrap it in a Task object. [nah, i take it back… callbacks still go on the queue. sorry.]
for general information on the threading model in Max, seems like the most up-to-date place to look is the max 7 SDK docs, particularly the chapters on threading, scheduler and low-priority queue.
if you haven’t checked it out, this article is also important (though dated, referring to the state of affairs in 4.5.)
it doesn’t really surprise me that immediate is deprecated, since a) it can be misleading as mentioned above, and b) i can imagine that it could easily lead to deadlocks for other things on the high-priority thread, if it’s not simply ignored (API was free to do this; it can even defer stuff from C externals), and c) who knows! keeping up to date with multithreading best-practices is hard enough without throwing a javascript engine in the mix.
anyway, long story short, worth considering just writing a C external if you are really concerned about having control over timing (i.e., want to be free to shoot yourself in the foot
), and your code is primarily concerned with processing realtime events. it’s not the worst API to work with.
another option is to just not worry about it until and unless you run into issues that are pretty definitely attributable to starvation of the low-priority thread. i guess it’s more likely if your patch is doing a lot of heavy lifting in other areas that are always low-priority; particularly manipulating jitter matrices.