I'm not going to answer either of Tony's questions as I don't feel
qualified to say one way or another. I'll admit that I've paid almost no
attention to the preemptive/cooperative subject in upcoming versions of 4D.
Can those of you who have tried it all out and gotten some experience
provide a bit of background? Specifically: What problems does this help
with in your systems. I can easily see why 4D has put a lot of effort into
improving threading in their server code, what I'm not clear on is which
problem(s) or classes of problems this will help with meaningfully that
fall into our hands. I'm not suggesting there aren't problems like this, I
just don't know what they are.

And, after admitting my complete ignorance, I'll boldly go forward with a
couple of opinions from Tony's detailed suggestions. First off, the
IP-variables-that-are-process variables idea: I hate it. For the very
simple reason that it's fundamentally confusing, unless you understand it
already. There are or have been a few areas in 4D where you had to
carefully think through your execution context to understand how the could
would and should operate:

* Triggers
* Stored procedures
* Web of any kind
* Web contextual mode in particular
* Methods marked as 'execute on server'

4D normally does a masterful job of sheltering us from the difference
amongst various platforms and contexts. It's a wonderful thing to be able
to take for granted. Kudos. But when the context matters, *you can't see it
from the code.* You need prior knowledge and experience. That's expensive.
Also, if history is anything to go by, the documentation has always been
poor or absent on these subjects. The exceptional nature of triggers was
never well documented by 4D, and then it changed dramatically, the whole
dual-threads-for-client-connetions business has *never* been documented by
4D (outside of a conference) as far as I know, and so on. Even if there are
some docs on some of these subjects (and there are), they're pretty thin
for such important subjects. As a result, people tend to get pretty messed
up by these various parts of the language and consequently avoid using
them. Not a great outcome. If IP variables mean "IP, unless you're in this
one special kind of process, where they are process vars"...ummm. That's
confusing. Think about the scope of sets, another example of weak
documentation and misleading/confusing naming prefixes. Not helpful. And
while an experienced, dedicated 4D programmer might well learn all of the
kinks of these various exceptional parts of the language, a new or
occasional programmer would have no chance at all. Welcome to the new
person messing up your code! It's easy to forget, but younger programmers
tend to use a blend of languages for various tasks and may not learn or
retain the nuances of each one.

I also don't get the obsession with IP variables as I don't need a lot of
them. I don't know why they seem so important. I also never missed having
client variables in triggers. I strongly suspect that people have become
used to using IP variables for inter-process communications because 4D
didn't have any native alternative. <wish_I_could_turn_on_bold>IP variables
are not a messaging system and they're a terrible way to pass data
routinely between processes.</wish_I_could_turn_on_bold> Seriously, the
only thing worse is SET PROCESS VARIABLE which is just pathological. If you
need to pass messages, pass messages! NTK has given us a nice way to do
this for, oh, forever? And CALL WORKER also provides a very nice-looking
native method. You get a sequential message queue with no fuss. Sweet. No
semaphores, not IP locking, no nonesense. Easy, safe, lovely. It's only for
one-machine communications, but that's a huge start.

Okay, maybe I'm lying - maybe I do have a lot of IP vars. I just checked
and in a system with just shy of 6,000 methods I've got 152 IP arrays and
100 IP variables. A lot of those could be replaced very easily, a few I
would miss. Is that a lot? It doesn't feel like a lot, but "a lot" is a
relative term.

[Later] Thanks to Tony for linking to the relevant docs:
http://livedoc.4d.com/4D-Language-Reference-16/Processes/Preemptive-4D-processes.300-3036340.en.html

Hmm. No support on client machines. Hmmm. So, we're talking compiled,
server-side/single-user execution. That makes the restrictions make a whole
lot more sense to me. If this is so, and the tasks you need to get more
cores on are client-side in nature, there's a pretty strong argument for
using compiled-and-merged single-user apps that communicate with the server
using HTTP calls (etc.) At that point, you aren't going to use IP vars or
CALL WORKER from the server in any case. For what it's worth, that model
gets you more 'cores' because you're using a distributed architecture with
more machines.

Anyway, back to the docs. Right, no plug-ins makes sense, no IP vars makes
sense. You can use the network (HTTP Get) or file system (Create document,
TEXT TO DOCUMENT, etc.), so that's how you message the outside world. And
the outside world includes other processes. I guess CALL WORKER is a safe
way of calling that 4D has implemented for us in a single-machine context.
Nice.

At a first scan, these docs are great and it's inspiring to see 4D working
so hard to implement a challenging feature in a usable way. By the way,
here' s a link to the thread-safe command list:

http://livedoc.4d.com/Preemptive/4Dv16.999-2878208.en.html?revision=2923790

The new features make for a situation where a custom error handler is
pretty much a requirement. I use them about 100% of the time anyway, but
they're something it's easy to forget about. Triggers and other server-side
code need them and it looks like preemptive thread code does too.

There's a note about docrefs being shared in cooperative threads and not
shared in preemptive threads. I'm not at all clear what that means. I would
expect you would pass paths anyway...isn't that what everyone does now
anyway?

It looks like the table pointer restriction is not an execution
restriction, it's a compiler verification limitation. Same thing for error
method names. If the table pointer or error method name is set at runtime,
there's no way for the compiler to know what to scan for safety. How could
it? For triggers, it says it will check all possible triggers, for the
error method, it sounds like it doesn't try. Nice that it knows how to read
a method name parameter as a method name reference. I hope this shows up in
the rest of the compiler. I'd love to get warnings like "method name does
not exist" or "method name could not be verified." But perhaps I'm getting
this trigger thing wrong (?)

Anyway, that's all pretty deep in the weeds so I'll go back to my original
question: What problems are people having that server-side, preemptive
threads going to solve? I'll be very curious to hear about examples. And
I'll also immediately wonder if those problems can't be solved with a
different architecture using any version of 4D. Maybe not a better
solution, but good to have in the mix. (Multiple machine redundant
processing to good results has been around as long as 4D Server itself.) If
you are served better by a different architecture, it makes a big
difference in how you approach interprocess/inter-machine messaging, so
it's worth thinking through.
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[email protected]
**********************************************************************

Reply via email to