On Mon, May 8, 2017 at 11:03 AM, Keisuke Miyako via 4D_Tech <
4d_tech@lists.4d.com> wrote:

Another great post, thanks. I really like the way you've broken out the
various scenarios, how they should behave and how you've observed them
behaving. Just to make it really clear, all I'm talking about is raising
errors consistently and not killing/restarting workers as a side-effect. I
in no way have _any_ problem with _any_ of 4D's restrictions on preemptive
processing. None. I looked into it a bit, and it's no simple task to make a
language run on multiple cores. So, they've got my complete respect on
that. Likewise, some of the restrictions in the language are imposed by the
underlying OS. So, it's reality imposing a constraint, not some arbitrary
choice by 4D.

Likewise, I appreciate what the compiler does for detecting errors in
advance. I'm always all in on the compiler doing more and, in this case,
it's a good effort.

But I am concerned (as you figured) about what comes up as #3 in your
taxonomy:

"CALL WORKER is used to "run cooperative code in an existing preemptive
process"

Personally, I think that 4D should *not* run the code. It should throw an
error that we can catch. Every time. It's not 4D's bug, it's my bug. But 4D
needs to tell me about it. This is very realistically the sort of flaw that
could creep into a system of almost any level of complexity from simple on
up.

Bad call: My fault
Scolding me: 4D's job
> and you can invoke that method by passing an empty string.
> http://doc.4d.com/4Dv16R2/4D/16-R2.1620/CALL-WORKER.301-3111543.en.html
> if we followed that rule and always passed an empty string, we would
never have this problem. just saying...

I guess I haven't said clearly, but I'm not primarily thinking of myself.
There is zero chance I'll start tossing unregulated code around for
execution. That's just stupid/insane/unsafe. It's a weak design, although I
can see why 4D did it. I've got a quite involved system of message passing
I'm working on that goes like this:

CallMyMagicThingy($object;{$result_callback_object})

Any method that is going to get a callback has one parameter:

C_OBJECT($1;$message)

That's it. There are formalisms and validators for the contents of the
message. (A header with routing details and action flags, a message
payload, and so on.) This, in fact, is was arguing for comprehensive JSON
scanning features a few months back. Without that, you can't write any sort
of generic validation code. Instead, you need a lot of code that embeds the
rules in the code. Ugh. I'd rather build my own meta-data/schema to
generate, validate, document, and test the formats. Can't. So, I scaled
back the system to code with only much simpler formats and had to write
individual validators. Wasteful and disappointing, but the native command
set doesn't support anything more. Anyway.

> now your feature request, if I understand correctly, talks about
detecting, on the receiving end,
> if a request to execute cooperative code has been received in a
preemptive process.
> I think it is not a problem, since there is nothing to receive since CALL
WORKER does make such requests.

I'm not parsing out what you're saying here, so I'm probably missing your
point. What I'm asking for is that the *recipient* throws an error. The
worker throws an error that I can catch. From there, I've got a lot of
options as how to proceed. There's no call-response with CALL WORKER so
there is not automatic way to report back the flaw to the code that caused
the flaw. But that's another matter:

C_BOOLEN($okay)
$okay:=Call worker("PreemptiveWorker";"BadCode")

If($okay=false)
   ALERT("Aiuto! Something went wrong!")
End if

I could go on about alternatives here all day, but that's not the point. At
the bare minimum, the preemptive worker should not terminate and should
report an error.

> * I don't get an error.
> this must be CALL WORKER asked to do something impossible. (issue #3
above)

Could be. Hard to know. Impossible to count on. The docs don't say. It has
been drilled into us for decades that when something is not in the docs *it
is not a reliable behavior.* There is absolutely no way to distinguish
between "Oh, yeah, we just didn't put that in the docs, good idea" from
"that's an undocumented behavior, don't count on it." They look the same
from the outside since there's nothing to look at!

> * The worker may be restarted in cooperative mode. Which may end up
clearing existing variables and so on (?)

> the worker must have been killed or aborted.

Yes, exactly - but not by my code - by 4D. This is a bug or design flaw.
It's not something I think is easy to defend as a good idea. "Oh, we will
keep this process running until you KILL it or quit. And that's a
guarantee! (+)"

(+) Not an actual guarantee, see the back of your ticket.

> * Other people report getting an error.
> some "eval" code must have been executed in the worker (issue #2 above)

Yeah, I'll buy that.

> * Sometimes I get an error.
> * Sometimes an error handler catches, sometimes it doesn't.

> a mix of all the other problems, just presenting themselves in random
order?

I cant' say for sure as I haven't studied it systemically enough. It was
enough of a dog's breakfast that it struck me as a waste of my time to try
to dig in. (I've poured hundreds of hours into CALL WORKER and CALL FORM
already, but I draw the line at features that just don't look like they
should have come out of the oven yet.) There's no promised behavior from 4D
about errors in case #3, it's easy to get weird results, and the
side-effects are potentially catastrophic. So, yeah, I'm not seeing putting
a bunch more time into it as smart move for me.

I really appreciate you offering a solid, well thought-out technical
answer. You've given me some food for thought and I think given everyone a
broader perspective on the system.

I want to emphasize again that I like CALL WORKER a lot. It's easy to use
and has a classic good 4D economy. Big power, small package. But, it needs
to be used correctly. Personally, I'd much prefer a true messaging system
rather than remote and unregulated code execution scheme. That's a great
approach (and time tested), and would make all of the following better:

* None of the nonesense I've been complaining about.
* Saving the queue for later processing.
* Load-balancing in real-time.
* Message distribution and routing. Easily.
* Message security policies.
* Message/service actions that can be extended to any JSON-capable system
out there. Very easy.
* Publish/subscribe: Easy.
* Networked: Easy

MQs (Message Queues) come out of the middleware world. It's always been all
about interchange amongst heterogeneous systems. That's one reason messages
are normally passed as, well, messages. Passing code locks your system into
a specific interpreter.

Personally, I don't care about preemptive much. I've noticed it seems to be
the new "For loops are faster" and that people get pretty excited. I
figured that I should check it out. I expect it to be suitable for only a
small range of problems. (There's a reason all of the demos show a bunch of
random calculations in a loop...it's because it's hard to find real-world
examples of discrete, time-consuming, CPU-bound, low-dependency tasks.)
When I have a suitable problem, I'll do a very, very, very specific and
tight implementation. Using the feature casually in this context could end
in tears too easily.
**********************************************************************
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:4d_tech-unsubscr...@lists.4d.com
**********************************************************************

Reply via email to