synch event handling

Dear All,

the post about "messages" was going to became a debate about event handling, therefore I have created this separate post.
As I have stated in the wiki page [Contribute! Which weakness have you detected in RTT?], I have seen a serious issue in the current implementation of synchronous event handling.

We do all agree (I guess)that, from a theoretical point of view, something like an "immediate" reaction to an event must be present in RTT.
On the other hand, if the event handle is executed in the thread of the component which emitted the event (TaskA), it is easy to demonstrate that we are very sensible to catastrophic errors (and it is impossible to prevent such situation in the user's code!!!).
The only solution I can see is that the subscribers to the event (TaskB) creates an extra thread responsible for the execution of synchronous handles.
I know, I know!! it sounds non optimal, resource consuming and "dirty", but I insist that the current implementation is much unsafer.
I hope you can be help finding out a better solution.

Davide

synch event handling

Dear Davide,

On Mon, Apr 27, 2009 at 08:17:50AM -0000, faconti [..] ... wrote:

> the post about "messages" was going to became a debate about event
> handling, therefore I have created this separate post. As I have
> stated in the wiki page [Contribute! Which weakness have you
> detected in RTT?], I have seen a serious issue in the current
> implementation of synchronous event handling.
>

> We do all agree (I guess)that, from a theoretical point of view,
> something like an "immediate" reaction to an event must be present
> in RTT.

>From a theoretical POV yes, but in practice immediate is very relative
to a specific application.

> On the other hand, if the event handle is executed in the thread of
> the component which emitted the event (TaskA), it is easy to
> demonstrate that we are very sensible to catastrophic errors (and it
> is impossible to prevent such situation in the user's code!!!).
> The only solution I can see is that the subscribers to the event
> (TaskB) creates an extra thread responsible for the execution of
> synchronous handles.
> I know, I know!! it sounds non optimal, resource consuming and
> "dirty", but I insist that the current implementation is much
> unsafer.

I agree with you, but I think we should go a step further and question
if these synchronous communication mechanisms (methods and synchronous
events) don't create more problems than they solve.

1) they make it easy to create race conditions

2) it is *only* the component which receives an event which can
decide when it is safe and best to be handled.

3) it makes things really complicated!

> I hope you can be help finding out a better solution.

I know I'm repeating myself, but I belive all we need are asynchronous
messages. If all communication primitves are modeled with messages all
problems mentioned above go away.

This pictures shows it all:

http://people.mech.kuleuven.be/~orocos/pub/stable/documentation/rtt/curr...

A component should decide when to handle events, methods, commands
etc. For the case when it has a very long updateHook (or is what we
call non-periodic today) it should be able to explicitely invoke
event, method, command, etc. handling at certain points which make
sense for this specific component computation.

I think there is no reason to "pretend" we are one big non-distributed
application when we are really multiple partitoned and distributed
applications.

Markus

synch event handling

On Monday 27 April 2009 13:32:52 Markus Klotzbucher wrote:
>
> I agree with you, but I think we should go a step further and question
> if these synchronous communication mechanisms (methods and synchronous
> events) don't create more problems than they solve.

We can't label them all the same:
Synchronous events may be questionable from a conceptual point of view (ie
when you finish emiting the event, you know all handlers got executed. Why
would you care if you don't even know the handlers?)
vs
Methods are very much required in every functional programming language.

I was still arguing on this 'synchronous event might be bad and unnecessary'
case. Markus was trapped into bike-shedding and involved methods and a lower-
level implementation solution. Both issues are RTT 2.0 related, but as the
subject puts it. This one is about 'synch event handling'. Thank you.

>
> 1) they make it easy to create race conditions
>
> 2) it is *only* the component which receives an event which can
> decide when it is safe and best to be handled.
>
> 3) it makes things really complicated!
>
> > I hope you can be help finding out a better solution.
>
> I know I'm repeating myself, but I belive all we need are asynchronous
> messages. If all communication primitves are modeled with messages all
> problems mentioned above go away.

We both now you lost it here. Imagine a call-back scenario (A calls B which
calls A back) with methods constructed like this. Imagine the code to solve
the dead-locks, the thread allocation and data copying. Grade it on your
complexity scale. You're basically proposing to implement the same messaging
mechanism found in all CORBA implementations. I'm against adding complexity in
the RTT. We're off to far from 'keep it short and simple' already.

>
> This pictures shows it all:
>
> http://people.mech.kuleuven.be/~orocos/pub/stable/documentation/rtt/current
>/doc-xml/orocos-components-manual.html#fig-task-execution
>
> A component should decide when to handle events, methods, commands
> etc. For the case when it has a very long updateHook (or is what we
> call non-periodic today) it should be able to explicitely invoke
> event, method, command, etc. handling at certain points which make
> sense for this specific component computation.

Thats a flexibility I'm not against. Our current updateHook() is limiting.
You're not the first to request that user code may decide when incoming
messages must be processed.

>
> I think there is no reason to "pretend" we are one big non-distributed
> application when we are really multiple partitoned and distributed
> applications.

That choice is made at deployment of your component.

Peter

PS: I also predict that updateHook() will not survive when the discussions go
on like this. But I sticked to the topic...

synch event handling

(sorry Peter for the duplicate... didn't hit group reply again)

On Mon, Apr 27, 2009 at 10:51:54PM +0200, Peter Soetens wrote:
> On Monday 27 April 2009 13:32:52 Markus Klotzbucher wrote:
> >
> > I agree with you, but I think we should go a step further and question
> > if these synchronous communication mechanisms (methods and synchronous
> > events) don't create more problems than they solve.
>
> We can't label them all the same:
> Synchronous events may be questionable from a conceptual point of view (ie
> when you finish emiting the event, you know all handlers got executed. Why
> would you care if you don't even know the handlers?)
> vs
> Methods are very much required in every functional programming language.

I'm not sure I agree with your definition of "functional programming
language"... IMHO it refers to languages which are free of side
effects.

> I was still arguing on this 'synchronous event might be bad and unnecessary'
> case. Markus was trapped into bike-shedding and involved methods and a lower-
> level implementation solution. Both issues are RTT 2.0 related, but as the

Come on, we're discussing about rtt-2.0 and this is orocos-dev. I
think it is wrong to say that "synchronos events are bad", they can
only be used in inappropriate circumstances.

> subject puts it. This one is about 'synch event handling'. Thank you.

Several people pointed out the problem of events apply to methods
too.

> > 1) they make it easy to create race conditions
> >
> > 2) it is *only* the component which receives an event which can
> > decide when it is safe and best to be handled.
> >
> > 3) it makes things really complicated!
> >
> > > I hope you can be help finding out a better solution.
> >
> > I know I'm repeating myself, but I belive all we need are asynchronous
> > messages. If all communication primitves are modeled with messages all
> > problems mentioned above go away.
>
> We both now you lost it here. Imagine a call-back scenario (A calls B which
> calls A back) with methods constructed like this. Imagine the code to solve

But there are ways to create such problems in the current
implementation too. I think the core RTT should focus on allowing to
do powerful things opposed to trying to prevent all types of stupid
things a user might do.

> the dead-locks, the thread allocation and data copying. Grade it on your

Most of this is not different than asynchronous events and you
implemented lock-free queues. Why would thread allocation be needed?

> complexity scale. You're basically proposing to implement the same messaging
> mechanism found in all CORBA implementations. I'm against adding complexity in
> the RTT. We're off to far from 'keep it short and simple' already.

True, and it is my intention is to make things simpler! Look, it's
only a proposition and I would like you to comment and consider in a
rational and critical way.

Best regards
Markus

synch event handling

On Tue, 28 Apr 2009, Markus Klotzbcher wrote:

[...]
> I think the core RTT should focus on allowing to
> do powerful things opposed to trying to prevent all types of stupid
> things a user might do.

This was _the_ motivation to start Orocos a long time ago... :-)
But this statement used to be accompanied with another prime motivation:
"Orocos should provide documented examples of "best practice" use of all
its features, in the OCL sub-project." The project basically failed with respect to
this latter aspiration... :-(

Herman

synch event handling

> [...]
>> I think the core RTT should focus on allowing to
>> do powerful things opposed to trying to prevent all types of stupid
>> things a user might do.
>
> This was _the_ motivation to start Orocos a long time ago... :-)

I would like that the "user experience" could be scaled better.
What I mean is that RTT must allow less experienced programmers to
work smoothly without pitfalls waiting behind the corner and
experienced programmers to get things done their way if they need it.

Let's get back to the main discussion: do people like that a component
rise an event and it is suddenly blocked by another component that it
doesn't even know?
Is this robust and decoubled behaviour for you?
Because the post is about that!

(At least, when you call a method, you know what you are doing and
the associated risk).

synch event handling

On Wed, 29 Apr 2009, Davide Faconti wrote:

>> [...]
>>> I think the core RTT should focus on allowing to
>>> do powerful things opposed to trying to prevent all types of stupid
>>> things a user might do.
>>
>> This was _the_ motivation to start Orocos a long time ago... :-)
>
> I would like that the "user experience" could be scaled better.
> What I mean is that RTT must allow less experienced programmers to
> work smoothly without pitfalls waiting behind the corner and
> experienced programmers to get things done their way if they need it.

That was (and still _is_) the goal of the "OCL" subproject in Orocos: to
provide proven templates for some use cases, for less experienced
programmers. But keeping the RTT primitives separate from the OCL templates
is a _very_ motivated and crucial policy of the Orocos project...

So, maybe you should re-target your discussion efforts towards trying to
come to a concensus about which templates to provide (and document!) in
OCL...

> Let's get back to the main discussion: do people like that a component
> rise an event and it is suddenly blocked by another component that it
> doesn't even know?

Of course you don't _like_ it! But you will have to live with it, if your
_architecture_ is such that it does not prevent this situation.

> Is this robust and decoubled behaviour for you?

It is as decoupled as the _system architecture_ allows to.

> Because the post is about that!
>
> (At least, when you call a method, you know what you are doing and
> the associated risk).

The same goes for events and messages and other primitives...

Herman

synch event handling

> So, maybe you should re-target your discussion efforts towards trying to
> come to a concensus about which templates to provide (and document!) in
> OCL...
>

Maybe you are right. But then my best practive will be: never and ever
use synchronous handles.

>> Let's get back to the main discussion: do people like that a component
>> rise an event and it is suddenly blocked by another component that it
>> doesn't even know?
>
> Of course you don't _like_ it! But you will have to live with it, if your
> _architecture_ is such that it does not prevent this situation.
>

In RTT is IMPOSSIBLE to prevent it (this is my point). A component
emitting an event can NOT prevent that a peer connects to it,
subscribes a synch event and mess things out.

synch event handling

On Wed, 29 Apr 2009, Davide Faconti wrote:

>> So, maybe you should re-target your discussion efforts towards trying to
>> come to a concensus about which templates to provide (and document!) in
>> OCL...
>>
>
> Maybe you are right. But then my best practive will be: never and ever
> use synchronous handles.

A "best practice" is _always_ dependent on a particular _context_! Because
this context determines the trade-offs that a particular design has made.
(This is the essence of "software patterns" in software engineering, but it
holds for "best practices" in all other domains too...)

>>> Let's get back to the main discussion: do people like that a component
>>> rise an event and it is suddenly blocked by another component that it
>>> doesn't even know?
>>
>> Of course you don't _like_ it! But you will have to live with it, if your
>> _architecture_ is such that it does not prevent this situation.
>
> In RTT is IMPOSSIBLE to prevent it (this is my point). A component
> emitting an event can NOT prevent that a peer connects to it,
> subscribes a synch event and mess things out.

Of course! And I don't _want_ to prevent this! At least not in the
_toolkit_ which is RTT...

BTW I have no problem repeating myself, if you keep on repeating yourself
too... :-) That's "rule one" for every open source project "manager": every
worthy user of your project is worth spending time on, until you find an
understanding about how to make the project better for everyone :-)

Herman

synch event handling

> BTW I have no problem repeating myself, if you keep on repeating yourself
> too... :-) That's "rule one" for every open source project "manager": every
> worthy user of your project is worth spending time on, until you find an
> understanding about how to make the project better for everyone :-)
>

I think we have been repeating ourselves enough. I repeated myself
because, looking at some answers, I was afraid that I didn't explained
my opinion well.
And probably I did it at some point...
Let's not waste our time, we have both something more interesting and
more important to do.

My question from the beginning was (should have been): do exist a
DIFFERENT IMPLEMENTATION of the synch event handling which makes
possible to obtain the same user experience (almost), but avoid
unexpected malfunctioning?

synch event handling

On Wed, 29 Apr 2009, Davide Faconti wrote:

>> BTW I have no problem repeating myself, if you keep on repeating yourself
>> too... :-) That's "rule one" for every open source project "manager": every
>> worthy user of your project is worth spending time on, until you find an
>> understanding about how to make the project better for everyone :-)
>>
>
> I think we have been repeating ourselves enough. I repeated myself
> because, looking at some answers, I was afraid that I didn't explained
> my opinion well.
> And probably I did it at some point...
> Let's not waste our time, we have both something more interesting and
> more important to do.

I think we should refocus the discussion from "RTT 2.0" towards "OCL 2.0",
where your remarks and suggestions _are_ very to the point!

> My question from the beginning was (should have been): do exist a
> DIFFERENT IMPLEMENTATION of the synch event handling which makes
> possible to obtain the same user experience (almost), but avoid
> unexpected malfunctioning?

I don't think that exists...

Herman

synch event handling

> > I think the core RTT should focus on allowing to
> > do powerful things opposed to trying to prevent all types of stupid
> > things a user might do.
>
> This was _the_ motivation to start Orocos a long time ago... :-)
> But this statement used to be accompanied with another prime
motivation:
> "Orocos should provide documented examples of "best practice" use of
all
> its features, in the OCL sub-project." The project basically failed
with
> respect to
> this latter aspiration... :-(
>
Which leads to endless discussions ;-).

synch event handling

On Mon, 27 Apr 2009, Markus Klotzb???cher wrote:

> Dear Davide,
>
> On Mon, Apr 27, 2009 at 08:17:50AM -0000, faconti [..] ... wrote:
>
>> the post about "messages" was going to became a debate about event
>> handling, therefore I have created this separate post. As I have
>> stated in the wiki page [Contribute! Which weakness have you
>> detected in RTT?], I have seen a serious issue in the current
>> implementation of synchronous event handling.
>>

>> We do all agree (I guess)that, from a theoretical point of view,
>> something like an "immediate" reaction to an event must be present
>> in RTT.
>
>> From a theoretical POV yes, but in practice immediate is very relative
> to a specific application.
>
>> On the other hand, if the event handle is executed in the thread of
>> the component which emitted the event (TaskA), it is easy to
>> demonstrate that we are very sensible to catastrophic errors (and it
>> is impossible to prevent such situation in the user's code!!!).
>> The only solution I can see is that the subscribers to the event
>> (TaskB) creates an extra thread responsible for the execution of
>> synchronous handles.
>> I know, I know!! it sounds non optimal, resource consuming and
>> "dirty", but I insist that the current implementation is much
>> unsafer.
>
> I agree with you, but I think we should go a step further and question
> if these synchronous communication mechanisms (methods and synchronous
> events) don't create more problems than they solve.
> 1) they make it easy to create race conditions
> 2) it is *only* the component which receives an event which can
> decide when it is safe and best to be handled.
> 3) it makes things really complicated!

I don't really agree! At least not for the case of "single thread
serialization" (which is a use case I will keep on defending!). In that
case synchronous handling makes things much more deterministic (even
formally verifiable!). And (deterministic) _performance_ is another design
criterium that I don't want to loose out of sight!

>> I hope you can be help finding out a better solution.
>
> I know I'm repeating myself, but I belive all we need are asynchronous
> messages. If all communication primitves are modeled with messages all
> problems mentioned above go away.

But not the "problems" I mention! :-)

Asynchronous messages might be a good answer in the 'distributed' use case,
but not in general. And since a component should/can not know in what use
case it will be deployed, the component should _not_ impose any policy by
itself, but that policy will (have to) be chosen by the deployer, or the
system architect.

> This pictures shows it all:
>
> http://people.mech.kuleuven.be/~orocos/pub/stable/documentation/rtt/curr...
>
> A component should decide when to handle events, methods, commands
> etc. For the case when it has a very long updateHook (or is what we
> call non-periodic today) it should be able to explicitely invoke
> event, method, command, etc. handling at certain points which make
> sense for this specific component computation.

This picture _only_ shows _that_ a component should do all these things,
but it does _not_ show that asynchronous handling is the only policy to
support!

> I think there is no reason to "pretend" we are one big non-distributed
> application when we are really multiple partitoned and distributed
> applications.

I strongly disagree: many extremely useful machines _are_ non-distributed.

You make the mistake, in my humble opinion, to equate "component-based"
programming (CBP) with "distributed" programming. While CBP _is_ an almost
necessary condition for distributed programming, it does _not_ prevent
making very good and efficient non-distributed applications. On the
contrary: I expect better code when developers can separate the
functionality of their code from the IPC with other componens...

Herman

synch event handling

On Mon, Apr 27, 2009 at 02:22:08PM +0200, Herman Bruyninckx wrote:
> On Mon, 27 Apr 2009, Markus Klotzb???cher wrote:
...

> > I agree with you, but I think we should go a step further and question
> > if these synchronous communication mechanisms (methods and synchronous
> > events) don't create more problems than they solve.
> > 1) they make it easy to create race conditions
> > 2) it is *only* the component which receives an event which can
> > decide when it is safe and best to be handled.
> > 3) it makes things really complicated!
>
> I don't really agree! At least not for the case of "single thread
> serialization" (which is a use case I will keep on defending!). In that

Wait... I'm not saying that the "single thread serialisation" should
go... I'm saying that having component behaviors (executed by in their
own thread or serialized) running concurrently with "synchronous"
(actually very asynchronos from a callee POV!) code provided by the
same component is not a good idea.

That said, wouldn't you agree that "single thread serialization" is
purely a configuration issue, for tweaking performance vs. robustness?

> case synchronous handling makes things much more deterministic (even
> formally verifiable!). And (deterministic) _performance_ is another
> design criterium that I don't want to loose out of sight!

The term "synchronous" is very misleading, as it is only true for the
caller. For the callee it is asynchronous and I can't see how this
would make things more deterministic?

> >> I hope you can be help finding out a better solution.
> >
> > I know I'm repeating myself, but I belive all we need are asynchronous
> > messages. If all communication primitves are modeled with messages all
> > problems mentioned above go away.
>
> But not the "problems" I mention! :-)
>
> Asynchronous messages might be a good answer in the 'distributed' use case,
> but not in general. And since a component should/can not know in what use

When would it not be a good case?

I've learnt that the general fear of loosing performance because of
locally copying data is more often than not unfounded, copying data
between caches is fast. Quite to the contrary of threads running on
different cores and stealing cache lines all the time... So two
processes on two cores could be considered to be distributed already.

> case it will be deployed, the component should _not_ impose any policy by
> itself, but that policy will (have to) be chosen by the deployer, or the
> system architect.

Agreed, I don't want to impose any policies. Please note I am
suggesting to *construct* higher level communication primitives from
messages, not force everybody to use only messages!

> > This pictures shows it all:
> >
> > http://people.mech.kuleuven.be/~orocos/pub/stable/documentation/rtt/curr...
> >
> > A component should decide when to handle events, methods, commands
> > etc. For the case when it has a very long updateHook (or is what we
> > call non-periodic today) it should be able to explicitely invoke
> > event, method, command, etc. handling at certain points which make
> > sense for this specific component computation.
>
> This picture _only_ shows _that_ a component should do all these things,
> but it does _not_ show that asynchronous handling is the only policy to
> support!

And it shows that a component handles its events, methods, commands
and nothing else, meaning no external threads invokes component
internal code!

> > I think there is no reason to "pretend" we are one big non-distributed
> > application when we are really multiple partitoned and distributed
> > applications.
>
> I strongly disagree: many extremely useful machines _are_ non-distributed.

Yes! I don't question this! I'm saying that if we are distributed (C3)
then it's wrong to pretend we are not!

> You make the mistake, in my humble opinion, to equate "component-based"
> programming (CBP) with "distributed" programming. While CBP _is_ an almost

I don't think so :-)

> necessary condition for distributed programming, it does _not_ prevent
> making very good and efficient non-distributed applications. On the
> contrary: I expect better code when developers can separate the
> functionality of their code from the IPC with other componens...

Yes, but how is this opposed to messages? I didn't say messages
couldn't go through shared mem or even directly to the recipients
queue? And of course I agree that components should work independantly
from the ipc which interconnects them.

Markus

synch event handling

On Mon, 27 Apr 2009, Markus Klotzb???cher wrote:

> On Mon, Apr 27, 2009 at 02:22:08PM +0200, Herman Bruyninckx wrote:
>> On Mon, 27 Apr 2009, Markus Klotzb???cher wrote:
> ...
>
>>> I agree with you, but I think we should go a step further and question
>>> if these synchronous communication mechanisms (methods and synchronous
>>> events) don't create more problems than they solve.
>>> 1) they make it easy to create race conditions
>>> 2) it is *only* the component which receives an event which can
>>> decide when it is safe and best to be handled.
>>> 3) it makes things really complicated!
>>
>> I don't really agree! At least not for the case of "single thread
>> serialization" (which is a use case I will keep on defending!). In that
>
> Wait... I'm not saying that the "single thread serialisation" should
> go... I'm saying that having component behaviors (executed by in their
> own thread or serialized) running concurrently with "synchronous"
> (actually very asynchronos from a callee POV!) code provided by the
> same component is not a good idea.

I didn't quite understand this paragraph... What exactly is not a
good idea?

> That said, wouldn't you agree that "single thread serialization" is
> purely a configuration issue, for tweaking performance vs. robustness?

It _should_ be only a configuration issue :-) But we have no toolchain
support yet to make it so simple...

>> case synchronous handling makes things much more deterministic (even
>> formally verifiable!). And (deterministic) _performance_ is another
>> design criterium that I don't want to loose out of sight!
>
> The term "synchronous" is very misleading, as it is only true for the
> caller. For the callee it is asynchronous and I can't see how this
> would make things more deterministic?
There _should_ be no asynchronicity (even not for the callee) in the
single-thread case. In the sense that the application developer should
provide thread-safe implementations, that can guarantee atomic changes to
shared data. It's only under this condition that formal verifications could
have any sense anyway :-)

>>>> I hope you can be help finding out a better solution.
>>>
>>> I know I'm repeating myself, but I belive all we need are asynchronous
>>> messages. If all communication primitves are modeled with messages all
>>> problems mentioned above go away.
>>
>> But not the "problems" I mention! :-)
>>
>> Asynchronous messages might be a good answer in the 'distributed' use case,
>> but not in general. And since a component should/can not know in what use
>
> When would it not be a good case?
In many cases, such as, for example, all CSP-based designs. And there are
_a lot_ of them "out there"...

> I've learnt that the general fear of loosing performance because of
> locally copying data is more often than not unfounded, copying data
> between caches is fast.
The _real_ performance overhead will come from context switching, not from
data copying... Serialization can solve both (when done correctly!).

> Quite to the contrary of threads running on
> different cores and stealing cache lines all the time... So two
> processes on two cores could be considered to be distributed already.
"could" -> "should"!

>> case it will be deployed, the component should _not_ impose any policy by
>> itself, but that policy will (have to) be chosen by the deployer, or the
>> system architect.
>
> Agreed, I don't want to impose any policies. Please note I am
> suggesting to *construct* higher level communication primitives from
> messages, not force everybody to use only messages!
>
>>> This pictures shows it all:
>>>
>>> http://people.mech.kuleuven.be/~orocos/pub/stable/documentation/rtt/curr...
>>>
>>> A component should decide when to handle events, methods, commands
>>> etc. For the case when it has a very long updateHook (or is what we
>>> call non-periodic today) it should be able to explicitely invoke
>>> event, method, command, etc. handling at certain points which make
>>> sense for this specific component computation.
>>
>> This picture _only_ shows _that_ a component should do all these things,
>> but it does _not_ show that asynchronous handling is the only policy to
>> support!
>
> And it shows that a component handles its events, methods, commands
> and nothing else, meaning no external threads invokes component
> internal code!

What you mention is an _architectural_ implementation of the _concept_
illustrated in that figure... And, rightly so, the figure does not bring
architecture into the picture :-)

>>> I think there is no reason to "pretend" we are one big non-distributed
>>> application when we are really multiple partitoned and distributed
>>> applications.
>>
>> I strongly disagree: many extremely useful machines _are_ non-distributed.
>
> Yes! I don't question this! I'm saying that if we are distributed (C3)
> then it's wrong to pretend we are not!

By definition :-)

>> You make the mistake, in my humble opinion, to equate "component-based"
>> programming (CBP) with "distributed" programming. While CBP _is_ an almost
>
> I don't think so :-)

>> necessary condition for distributed programming, it does _not_ prevent
>> making very good and efficient non-distributed applications. On the
>> contrary: I expect better code when developers can separate the
>> functionality of their code from the IPC with other componens...
>
> Yes, but how is this opposed to messages? I didn't say messages
> couldn't go through shared mem or even directly to the recipients
> queue? And of course I agree that components should work independantly
> from the ipc which interconnects them.
>
> Markus

Herman

synch event handling

1) One question: is performance more important than fault tolerance?
Apparently they are, but I think it shouldn't.

Even "single thread serialization" has big problems in this sense, and
I can see a new post in the forum with a lot of debate coming soon :-)

2) We are using the word "synchronous" as synonym of "not-differed in
time". I agree that would be nice to have such a thing. I am just
complaining the current implementation, not the concept itself.

3) ...this doesn't mean that I am able (yet) to figure out a better
implementation.

4) being distributed or not will have an effect on the performance of
the system , but __should not__ affect its behaviour in general. We
should never make any hypothesis about the current deployment of the
system (single process of distributed).

May be I am repeating something obvious, but I have noticed some
sub-debates emerging in the forum thread...

synch event handling

On Mon, Apr 27, 2009 at 4:22 PM, Davide Faconti <faconti [..] ...>wrote:

> 1) One question: is performance more important than fault tolerance?
> Apparently they are, but I think it shouldn't.
>
> Even "single thread serialization" has big problems in this sense, and
> I can see a new post in the forum with a lot of debate coming soon :-)

I'm convinced that both are quite orthogonal, but I'll defer that argument
to the
later discussion.

>
>
> 2) We are using the word "synchronous" as synonym of "not-differed in
> time". I agree that would be nice to have such a thing. I am just
> complaining the current implementation, not the concept itself.

See also Markus' note about the two different variants of this word.

>
> 3) ...this doesn't mean that I am able (yet) to figure out a better
> implementation.
>
> 4) being distributed or not will have an effect on the performance of
> the system , but __should not__ affect its behaviour in general. We
> should never make any hypothesis about the current deployment of the
> system (single process of distributed).

This is major. I 100% agree on this.

Peter

synch event handling

On Monday 27 April 2009 16:22:40 Davide Faconti wrote:
> 1) One question: is performance more important than fault tolerance?
> Apparently they are, but I think it shouldn't.
>
> Even "single thread serialization" has big problems in this sense, and
> I can see a new post in the forum with a lot of debate coming soon :-)
>
> 2) We are using the word "synchronous" as synonym of "not-differed in
> time". I agree that would be nice to have such a thing. I am just
> complaining the current implementation, not the concept itself.

You could describe the calling of RTT::Methods as 'blocking' and RTT::Commands
as non-blocking. At the callee side, the method is executed asynchronously
(not in the thread of the receiver) and the command synchronously (in the same
thread of the receiver). Markus wants to extend this and even execute methods
synchronously in the receiver. I don't agree that quickly...

There's also no reason to think implementations already. Lets get the user
visible concepts clear and simple first. So a Method is blocking from the point
of the caller. We all agree on that (I hope). The question is if the behavior
(ie foo() ) associated with that Method object is executed in context of the
caller or in the context of the receiver. In the latter case, you don't need
to care about threading from a user pov, in the first case, you might consider
using mutexes to protect concurrent access. I'm not that confident yet
which one is superior, but I do know which one adds complexity to the RTT and
semantics as a whole.

>
> 3) ...this doesn't mean that I am able (yet) to figure out a better
> implementation.
>
> 4) being distributed or not will have an effect on the performance of
> the system , but __should not__ affect its behaviour in general. We
> should never make any hypothesis about the current deployment of the
> system (single process of distributed).

I agree here as well.

Peter

synch event handling

On Mon, 27 Apr 2009, Peter Soetens wrote:

> On Monday 27 April 2009 16:22:40 Davide Faconti wrote:
>> 1) One question: is performance more important than fault tolerance?
>> Apparently they are, but I think it shouldn't.
>>
>> Even "single thread serialization" has big problems in this sense, and
>> I can see a new post in the forum with a lot of debate coming soon :-)
>>
>> 2) We are using the word "synchronous" as synonym of "not-differed in
>> time". I agree that would be nice to have such a thing. I am just
>> complaining the current implementation, not the concept itself.
>
> You could describe the calling of RTT::Methods as 'blocking' and RTT::Commands
> as non-blocking. At the callee side, the method is executed asynchronously
> (not in the thread of the receiver) and the command synchronously (in the same
> thread of the receiver).

This is a strange way to put things: I thought that a method would just
execute some code that comes with the callee, but that the fact whether or
not the callee has a thread has anything to do with the semantics...

> Markus wants to extend this and even execute methods
> synchronously in the receiver. I don't agree that quickly...

That would be "just" one of the possible policies on top of the
(asynchronous) message passing, I guess?

> There's also no reason to think implementations already. Lets get the user
> visible concepts clear and simple first. So a Method is blocking from the point
> of the caller. We all agree on that (I hope).

I, at least, agree.

> The question is if the behavior
> (ie foo() ) associated with that Method object is executed in context of the
> caller or in the context of the receiver. In the latter case, you don't need
> to care about threading from a user pov,
Indeed, from the _user_ point of view, since the threading problems have by
then already been solved by RTT, which was able to deliver the
corresponding "message" to the receiver.

> in the first case, you might consider
> using mutexes to protect concurrent access. I'm not that confident yet
> which one is superior, but I do know which one adds complexity to the RTT and
> semantics as a whole.

Which one...? (Just to be absolutely clear about how _you_ think about
these issues.)

I definitely know about at least one single fundamental problem which makes
the first case (i.e., synchronous execution of the method call in the context of
the caller) inferior from a "distributed systems" point of view: using
mutexes or other thread-safety support primitives requires caller and
receiver to share these primitives! And this introduces coupling at the
level of having to know about each other's internals. Which I don't like.

On the other hand, I _do_ like the above-mentioned synchronous execution of
the method call in the context of the caller in the _specific_ use case of
single-thread execution: in that case, the _toolchain_ should take care of
the above-mentioned coupling issues, and it can do this without having to
introduce this coupling to the programmers of both components. Hence, in
this case, and only in this one, this approach is "superior".

>> 3) ...this doesn't mean that I am able (yet) to figure out a better
>> implementation.
>>
>> 4) being distributed or not will have an effect on the performance of
>> the system , but __should not__ affect its behaviour in general. We
>> should never make any hypothesis about the current deployment of the
>> system (single process of distributed).
>
> I agree here as well.

Then let me introduce another discussion point that was already mentioned
by Davide earlier on: the current implementation of the TaskContext
introduces, in my opinion, already too many "policies", more in particular
in the way how it "integrates" the (Non)PeriodicActivity property with the
calling of the various "hook()"s. While I liked the idea some years back, I
now think that I find this an ugly example of introducing "Coordination"
into the TaskContext's "Computation"...

Maybe this remark is too much hidden in this thread with another Subject
so I might have to post it in a new thread...

Herman

synch event handling

>
> > in the first case, you might consider
> > using mutexes to protect concurrent access. I'm not that confident
yet
> > which one is superior, but I do know which one adds complexity to
the
> RTT and
> > semantics as a whole.
>
> Which one...? (Just to be absolutely clear about how _you_ think about
> these issues.)
>
> I definitely know about at least one single fundamental problem which
> makes
> the first case (i.e., synchronous execution of the method call in the
> context of
> the caller) inferior from a "distributed systems" point of view: using
> mutexes or other thread-safety support primitives requires caller and
> receiver to share these primitives! And this introduces coupling at
the
> level of having to know about each other's internals. Which I don't
like.
>
This is why we never used Methods before. Distributing them changes
their behavior from the caller's POV...

Sander.

synch event handling

On Mon, 27 Apr 2009, Davide Faconti wrote:
> 1) One question: is performance more important than fault tolerance?
> Apparently they are, but I think it shouldn't.
>
> Even "single thread serialization" has big problems in this sense, and
> I can see a new post in the forum with a lot of debate coming soon :-)
>
> 2) We are using the word "synchronous" as synonym of "not-differed in
> time". I agree that would be nice to have such a thing. I am just
> complaining the current implementation, not the concept itself.

I don't! :-)

What I have been referring to as "synchronous" is what Markus described as case a]: An event handler is synchronous if the event emitter _blocks_ when firing the event. For a single process application this means that the event handler is executed in the Activity (thread) of the event emitter.

Now, it is up to the application builder to decide on the final behaviour of the _application_, e.g. if you have Component S(ender) connected to a low priority thread firing an event, and Component R(eceiver) is connected to a high priority activity, the handler will be executed "immediately" after the event has been fired. I still call(ed) this _asynchronous_ event handling.

>From what I understood from a discussion with Peter this morning, the above application architecture is also Sanders use case, i.e. conceptually asynchronous event handling in an "all goes well" situation.
Sander, correct me if I'm wrong, but I understood from the discussion this morning that the reason you need _synchronous_ Event handlers is to deal with the case that something is "wrong" with the receiver(s thread) and hence, it has no resources any more to execute some kind of emergency behaviour itself anymore.
But (purely hypothetically and probably not a good solution!) if you would have a TaskCore connected to two threads, and one thread would be reserved to such "emergency behaviour handling", you wouldn't need SynEvents, right?

AFAIK, this interpretation of syn/asyn events is also the semantics that is currently used in the orocos documentation (and hence IMHO should be the one we are using in this discussion about syn/asyn events).

Klaas

> 3) ...this doesn't mean that I am able (yet) to figure out a better
> implementation.
>
> 4) being distributed or not will have an effect on the performance of
> the system , but __should not__ affect its behaviour in general. We
> should never make any hypothesis about the current deployment of the
> system (single process of distributed).
>
> May be I am repeating something obvious, but I have noticed some
> sub-debates emerging in the forum thread...
>

synch event handling

On Mon, 27 Apr 2009, Davide Faconti wrote:

> 1) One question: is performance more important than fault tolerance?
> Apparently they are, but I think it shouldn't.
Again, this trade-off is _completely_ case dependent. RTT should not do it
for you, but it should support _configurability_ of the trade-off.

> Even "single thread serialization" has big problems in this sense, and
> I can see a new post in the forum with a lot of debate coming soon :-)
Of course, doing synchronous "thread safe" method calls is not easy either...
But giving more attention to only one of both difficult software
engineering problems is not good; both should be supported equally well.
(That is: perfectly.)

> 2) We are using the word "synchronous" as synonym of "not-differed in
> time".
I don't know whether I fully understand this. My understanding of
"synchronous" is: I know what is going to happen to my component by just
reading the code in my function; everything happens at exactly the lines of
code that I want it to happen. (I just don't know all the time how _fast_
it is going to happen.)

> I agree that would be nice to have such a thing. I am just
> complaining the current implementation, not the concept itself.

> 3) ...this doesn't mean that I am able (yet) to figure out a better
> implementation.
>
> 4) being distributed or not will have an effect on the performance of
> the system , but __should not__ affect its behaviour in general. We
> should never make any hypothesis about the current deployment of the
> system (single process of distributed).
>
> May be I am repeating something obvious, but I have noticed some
> sub-debates emerging in the forum thread...
>
Herman

synch event handling

>> 1) One question: is performance more important than fault tolerance?
>> Apparently they are, but I think it shouldn't.
> Again, this trade-off is _completely_ case dependent. RTT should not do it
> for you, but it should support _configurability_ of the trade-off.

Ok , we have got to the point! I think that this will need a different
post in the forum to discuss this sentence...
By the way... am I wrong or the single thread serialization is the
default option of RTT instead of being an option for experienced users
only?

synch event handling

On Monday 27 April 2009 16:45:52 Davide Faconti wrote:
> >> 1) One question: is performance more important than fault tolerance?
> >> Apparently they are, but I think it shouldn't.
> >
> > Again, this trade-off is _completely_ case dependent. RTT should not do
> > it for you, but it should support _configurability_ of the trade-off.
>
> Ok , we have got to the point! I think that this will need a different
> post in the forum to discuss this sentence...
> By the way... am I wrong or the single thread serialization is the
> default option of RTT instead of being an option for experienced users
> only?

You're correct. If you don't assign a thread, the commands and asynchronous
handlers are executed within the thread of the caller.

So this is the worst of the worst case you could imagine in this discussion:
even if you only allowed asynch events to be attached, the callbacks would
still be executed in your thread. This indeed violates the 'never trust the
client' scenario. But again only for events, not for commands or methods.

Peter

synch event handling

On Mon, Apr 27, 2009 at 03:48:43PM +0200, Herman Bruyninckx wrote:
> On Mon, 27 Apr 2009, Markus Klotzb???cher wrote:
>
> > On Mon, Apr 27, 2009 at 02:22:08PM +0200, Herman Bruyninckx wrote:
> >> On Mon, 27 Apr 2009, Markus Klotzb???cher wrote:
> > ...
> >
> >>> I agree with you, but I think we should go a step further and question
> >>> if these synchronous communication mechanisms (methods and synchronous
> >>> events) don't create more problems than they solve.
> >>> 1) they make it easy to create race conditions
> >>> 2) it is *only* the component which receives an event which can
> >>> decide when it is safe and best to be handled.
> >>> 3) it makes things really complicated!
> >>
> >> I don't really agree! At least not for the case of "single thread
> >> serialization" (which is a use case I will keep on defending!). In that
> >
> > Wait... I'm not saying that the "single thread serialisation" should
> > go... I'm saying that having component behaviors (executed by in their
> > own thread or serialized) running concurrently with "synchronous"
> > (actually very asynchronos from a callee POV!) code provided by the
> > same component is not a good idea.
>
> I didn't quite understand this paragraph... What exactly is not a
> good idea?

The fact that currently RTT::Methods are not thread safe, e.g. there
is a potential race condition between the computation which implements
the RTT::Method and updateHook. If Methods were processed on the
callee side like Events, Commands, etc this Problem would go away.

The same is true for synchronous events (if I'm not mistaken).

> > That said, wouldn't you agree that "single thread serialization" is
> > purely a configuration issue, for tweaking performance vs. robustness?
>
> It _should_ be only a configuration issue :-) But we have no toolchain
> support yet to make it so simple...
>
> >> case synchronous handling makes things much more deterministic (even
> >> formally verifiable!). And (deterministic) _performance_ is another
> >> design criterium that I don't want to loose out of sight!
> >
> > The term "synchronous" is very misleading, as it is only true for the
> > caller. For the callee it is asynchronous and I can't see how this
> > would make things more deterministic?
> There _should_ be no asynchronicity (even not for the callee) in the
> single-thread case. In the sense that the application developer should
> provide thread-safe implementations, that can guarantee atomic changes to
> shared data. It's only under this condition that formal verifications could
> have any sense anyway :-)

Good, we actually agree :-)

Markus

synch event handling

On Mon, Apr 27, 2009 at 4:16 PM, Markus Klotzbücher <
markus [dot] klotzbuecher [..] ...> wrote:

> On Mon, Apr 27, 2009 at 03:48:43PM +0200, Herman Bruyninckx wrote:
> > On Mon, 27 Apr 2009, Markus Klotzb???cher wrote:
> >
> > > On Mon, Apr 27, 2009 at 02:22:08PM +0200, Herman Bruyninckx wrote:
> > >> On Mon, 27 Apr 2009, Markus Klotzb???cher wrote:
> > > ...
> > >
> > >>> I agree with you, but I think we should go a step further and
> question
> > >>> if these synchronous communication mechanisms (methods and
> synchronous
> > >>> events) don't create more problems than they solve.
> > >>> 1) they make it easy to create race conditions
> > >>> 2) it is *only* the component which receives an event which can
> > >>> decide when it is safe and best to be handled.
> > >>> 3) it makes things really complicated!
> > >>
> > >> I don't really agree! At least not for the case of "single thread
> > >> serialization" (which is a use case I will keep on defending!). In
> that
> > >
> > > Wait... I'm not saying that the "single thread serialisation" should
> > > go... I'm saying that having component behaviors (executed by in their
> > > own thread or serialized) running concurrently with "synchronous"
> > > (actually very asynchronos from a callee POV!) code provided by the
> > > same component is not a good idea.
> >
> > I didn't quite understand this paragraph... What exactly is not a
> > good idea?
>
> The fact that currently RTT::Methods are not thread safe, e.g. there
> is a potential race condition between the computation which implements
> the RTT::Method and updateHook. If Methods were processed on the
> callee side like Events, Commands, etc this Problem would go away.
>

RTT::Methods are indeed not thread safe, and this was an explicit design
choice.
In lots of cases, all you need is a 'C function', with all its very well
known limitations
included. For goodness sake, RTT::Method is the only primitive I don't want
to
change ! This is also the only Orocos primitive that maps 1:1 to a UML
construct, in case you cared :-) The ONLY reason to implement a function
call as a send+receive message is for middleware purposes (ie inter-process
communication).
This does not belong in the bare RTT, we delegate that to CORBA or whatever.

> The same is true for synchronous events (if I'm not mistaken).

Yes. Fortunately, we made it the responsibility of the event subscriber to
decide if he would react synchronously or asynchronously to an event. Hence,
he can take the appropriate action in case of synchronous (ie
non-thread-safe) reactions.

Peter

synch event handling

On Monday, April 27, 2009, at 10:16AM, "Markus Klotzb?" <markus [dot] klotzbuecher [..] ...> wrote:
>On Mon, Apr 27, 2009 at 03:48:43PM +0200, Herman Bruyninckx wrote:
>> On Mon, 27 Apr 2009, Markus Klotzb???cher wrote:
>>
>> > On Mon, Apr 27, 2009 at 02:22:08PM +0200, Herman Bruyninckx wrote:
>> >> On Mon, 27 Apr 2009, Markus Klotzb???cher wrote:
>> > ...
>> >
>> >>> I agree with you, but I think we should go a step further and question
>> >>> if these synchronous communication mechanisms (methods and synchronous
>> >>> events) don't create more problems than they solve.
>> >>> 1) they make it easy to create race conditions
>> >>> 2) it is *only* the component which receives an event which can
>> >>> decide when it is safe and best to be handled.
>> >>> 3) it makes things really complicated!
>> >>
>> >> I don't really agree! At least not for the case of "single thread
>> >> serialization" (which is a use case I will keep on defending!). In that
>> >
>> > Wait... I'm not saying that the "single thread serialisation" should
>> > go... I'm saying that having component behaviors (executed by in their
>> > own thread or serialized) running concurrently with "synchronous"
>> > (actually very asynchronos from a callee POV!) code provided by the
>> > same component is not a good idea.
>>
>> I didn't quite understand this paragraph... What exactly is not a
>> good idea?
>
>The fact that currently RTT::Methods are not thread safe, e.g. there
>is a potential race condition between the computation which implements
>the RTT::Method and updateHook. If Methods were processed on the
>callee side like Events, Commands, etc this Problem would go away.

This is something we have had to work around explicitly, the interaction of updateHook() with incoming aperiodic method calls. An alternative that overcomes this would be nice ...
S

--
Orocos-Dev mailing list
Orocos-Dev [..] ...
http://lists.mech.kuleuven.be/mailman/listinfo/orocos-dev

synch event handling

On Mon, Apr 27, 2009 at 4:58 PM, S Roderick <kiwi [dot] net [..] ...> wrote:

>
> >The fact that currently RTT::Methods are not thread safe, e.g. there
> >is a potential race condition between the computation which implements
> >the RTT::Method and updateHook. If Methods were processed on the
> >callee side like Events, Commands, etc this Problem would go away.
>
> This is something we have had to work around explicitly, the interaction of
> updateHook() with incoming aperiodic method calls. An alternative that
> overcomes this would be nice ...
>

The proposed RTT::Message would be the solution (not Markus' version, but
mine).
It's an asynchronous method invocation, but without a return value. It is
executed
sequentially with updateHook.

Peter

synch event handling

> You make the mistake, in my humble opinion, to equate
"component-based"
> programming (CBP) with "distributed" programming. While CBP _is_ an
almost
> necessary condition for distributed programming, it does _not_ prevent
> making very good and efficient non-distributed applications. On the
> contrary: I expect better code when developers can separate the
> functionality of their code from the IPC with other componens...
>
Herman's last sentence is right on target. This is essentially the
reason we started with Orocos a couple of years ago. Let the developers
focus on the task at hands: writing quality application code. An
individual developer should never ever have to deal with IPC primitives
(mutex's, semaphore's, critical section etc.). Leave that to the
specialists.

Sander.

synch event handling

On Mon, 27 Apr 2009, Vandenbroucke Sander wrote:

>> You make the mistake, in my humble opinion, to equate
> "component-based"
>> programming (CBP) with "distributed" programming. While CBP _is_ an
> almost
>> necessary condition for distributed programming, it does _not_ prevent
>> making very good and efficient non-distributed applications. On the
>> contrary: I expect better code when developers can separate the
>> functionality of their code from the IPC with other componens...
>>
> Herman's last sentence is right on target. This is essentially the
> reason we started with Orocos a couple of years ago. Let the developers
> focus on the task at hands: writing quality application code. An
> individual developer should never ever have to deal with IPC primitives
> (mutex's, semaphore's, critical section etc.). Leave that to the
> specialists.
>
> Sander.
>
It might be time (for me) to give credit to where it belongs: _your_
"synchronous" use case, Sander, was very influential for the early designs
of Orocos, in the pre-1.0 times, and I am still an ardent defender of it
being supported in all future versions of Orocos :-)

Herman

synch event handling

> I know I'm repeating myself, but I belive all we need are asynchronous
> messages. If all communication primitves are modeled with messages all
> problems mentioned above go away.
>
>
> I think there is no reason to "pretend" we are one big non-distributed
> application when we are really multiple partitoned and distributed
> applications.

Markus, basically I agree with all you said

let's summarize

This is an answer to all the people that are contributing to the post (by the way, thanks for your time).
I think that the discussion about synch events is (at least for me) just a "firestarter" for a much deeper discussion.
Which is the philosophy of RTT 2.0?
Which is the responsability of RTT and which is not?

It is a tricky question, I know, but once we decide this, all the following decision are coherent.

What I am trying to tell you is that apparently someone think: "since only God can write a code without any bug, it is not responsability of RTT to take care about all possible failures of the system".

There is something I am convinced and I will fight to make people understand it, even if they don't agree with me (I can be wrong, I am human you know ).
With synch event (but it is just 1 example) we are leaving an "open door" to errors. I insist to close such doors... theaves will sneak in anyway, but they will have an harder time to get in.

I also hope that you understand that my example with the student was a simplification (even if there are robot like HRP-2 which have self-collision controllers to have the expensive robot used by students in a safe way).
Also the infinite loop example was a silly example of failure, but there are many more on the list...

let's summarize

On Mon, 27 Apr 2009, faconti [..] ... wrote:

> This is an answer to all the people that are contributing to the post (by
> the way, thanks for your time).
Thanks for yours, and for the summary! :-)

> I think that the discussion about synch events is (at least for me) just
> a "firestarter" for a much deeper discussion.
> Which is the philosophy of RTT 2.0?
> Which is the responsability of RTT and which is not?

It is a "toolkit", offering a set of programming primitives to support the
use cases, policies and architectures that our "customers" want to have
supported. It is _not_ about selecting one use case, policy or
architecture, and then optimizing for that choice.

> It is a tricky question, I know, but once we decide this, all the
> following decision are coherent.
>
> What I am trying to tell you is that apparently someone think: "since
> only God can write a code without any bug, it is not responsability of
> RTT to take care about all possible failures of the system".
Indeed. It should try to support failure recognition and recovery, but it
cannot "care" about it. And "failure recovery" does not need really
different toolkit primitives than "normal" functionality, in my opinion.

> There is something I am convinced and I will fight to make people
> understand it, even if they don't agree with me (I can be wrong, I am
> human you know ).
> With synch event (but it is just 1 example) we are leaving an "open door"
> to errors. I insist to close such doors... theaves will sneak in anyway,
> but they will have an harder time to get in.

You have to make your case _a lot_ more clear, since I am not at all
convinced. On the contrary, this (very interesting) discussion make me only
more deeply aware of the fact that RTT should _support_ (not impose, nor
make impossible) both synchronous and asynchronous interactions (be it via
method calls, events, or whatever IPC primitives we decide to include in
RTT). If you don't like or need synchronous programming primitives, there
is noboyd who is going to force you to use them; a similar courtecy should
exist the other way around.

This said, I do think there might still be some parts in RTT that are not
(yet) sync/async agnostic, or where the choice between both is not (yet)
configurable, so identifying those spots (now) is important.

> I also hope that you understand that my example with the student was a
> simplification (even if there are robot like HRP-2 which have
> self-collision controllers to have the expensive robot used by students
> in a safe way).
> Also the infinite loop example was a silly example of failure, but there
> are many more on the list...
It's not about the "sillyness" of the example, since that example was very
clear to me: don't expect a toolkit to "solve" errors at the system design
level, or at the level of logical component correctness...

Herman

let's summarize

On Mon, Apr 27, 2009 at 03:33:09PM +0200, Herman Bruyninckx wrote:
> On Mon, 27 Apr 2009, faconti [..] ... wrote:

> > There is something I am convinced and I will fight to make people
> > understand it, even if they don't agree with me (I can be wrong, I am
> > human you know ).
> > With synch event (but it is just 1 example) we are leaving an "open door"
> > to errors. I insist to close such doors... theaves will sneak in anyway,
> > but they will have an harder time to get in.
>
> You have to make your case _a lot_ more clear, since I am not at all
> convinced. On the contrary, this (very interesting) discussion make me only
> more deeply aware of the fact that RTT should _support_ (not impose, nor
> make impossible) both synchronous and asynchronous interactions (be it via
> method calls, events, or whatever IPC primitives we decide to include in
> RTT). If you don't like or need synchronous programming primitives, there
> is noboyd who is going to force you to use them; a similar courtecy should
> exist the other way around.

What do you actually mean by synchronous? (maybe we should have
discussed this earlier...)

a) A caller blocks until the request is completed
b) the request is handled synchronously and at the callee side and in
the thread of the callee.

I believe you mean a) while Davide and I are concerned with b). Both
are possible and are orthogonal.

Markus

let's summarize

On Mon, 27 Apr 2009, Markus Klotzb???cher wrote:

> On Mon, Apr 27, 2009 at 03:33:09PM +0200, Herman Bruyninckx wrote:
>> On Mon, 27 Apr 2009, faconti [..] ... wrote:
>
>>> There is something I am convinced and I will fight to make people
>>> understand it, even if they don't agree with me (I can be wrong, I am
>>> human you know ).
>>> With synch event (but it is just 1 example) we are leaving an "open door"
>>> to errors. I insist to close such doors... theaves will sneak in anyway,
>>> but they will have an harder time to get in.
>>
>> You have to make your case _a lot_ more clear, since I am not at all
>> convinced. On the contrary, this (very interesting) discussion make me only
>> more deeply aware of the fact that RTT should _support_ (not impose, nor
>> make impossible) both synchronous and asynchronous interactions (be it via
>> method calls, events, or whatever IPC primitives we decide to include in
>> RTT). If you don't like or need synchronous programming primitives, there
>> is noboyd who is going to force you to use them; a similar courtecy should
>> exist the other way around.
>
> What do you actually mean by synchronous? (maybe we should have
> discussed this earlier...)
>
> a) A caller blocks until the request is completed
> b) the request is handled synchronously and at the callee side and in
> the thread of the callee.
>
> I believe you mean a) while Davide and I are concerned with b). Both
> are possible and are orthogonal.

I am also always talking about b).

Herman

let's summarize

> I am also always talking about b).

>From a very practical point of view, this is possible only in single
process deployment...
If you are distributed in multi process, definition b) is just
impossible, since the implementation of the method's function is
inside the process of the callee.

let's summarize

On Mon, 27 Apr 2009, Davide Faconti wrote:

>> I am also always talking about b).
>
> From a very practical point of view, this is possible only in single
> process deployment...
> If you are distributed in multi process, definition b) is just
> impossible, since the implementation of the method's function is
> inside the process of the callee.
>
That's exactly why it is then indeed called _asynchronous_ :-)

Herman

synch event handling

> > On the other hand, if the event handle is executed in the thread of
> > the component which emitted the event (TaskA), it is easy to
> > demonstrate that we are very sensible to catastrophic errors (and it
> > is impossible to prevent such situation in the user's code!!!).
> > The only solution I can see is that the subscribers to the event
> > (TaskB) creates an extra thread responsible for the execution of
> > synchronous handles.
> > I know, I know!! it sounds non optimal, resource consuming and
> > "dirty", but I insist that the current implementation is much
> > unsafer.
>
> I agree with you, but I think we should go a step further and question
> if these synchronous communication mechanisms (methods and synchronous
> events) don't create more problems than they solve.
>
> 1) they make it easy to create race conditions
>
> 2) it is *only* the component which receives an event which can
> decide when it is safe and best to be handled.
>
> 3) it makes things really complicated!
>
> > I hope you can be help finding out a better solution.
>
> I know I'm repeating myself, but I belive all we need are asynchronous
> messages. If all communication primitves are modeled with messages all
> problems mentioned above go away.
>
Ok if:
- also no more Method interface. They have the same risk as synchronous
event handling.
- on failure of a message queue (queue full) there is a deterministic
exception handling that is capable of informing _all_ components, even
the broken ones.
- memory efficient queues.

Sander.

synch event handling

Dear Sander,

(Sorry for the duplicate, forgot to hit group reply the first time)

On Mon, Apr 27, 2009 at 02:01:51PM +0200, Vandenbroucke Sander wrote:
> > > On the other hand, if the event handle is executed in the thread of
> > > the component which emitted the event (TaskA), it is easy to
> > > demonstrate that we are very sensible to catastrophic errors (and it
> > > is impossible to prevent such situation in the user's code!!!).
> > > The only solution I can see is that the subscribers to the event
> > > (TaskB) creates an extra thread responsible for the execution of
> > > synchronous handles.
> > > I know, I know!! it sounds non optimal, resource consuming and
> > > "dirty", but I insist that the current implementation is much
> > > unsafer.
> >
> > I agree with you, but I think we should go a step further and
> > question
> > if these synchronous communication mechanisms (methods and
> > synchronous
> > events) don't create more problems than they solve.
> >
> > 1) they make it easy to create race conditions
> >
> > 2) it is *only* the component which receives an event which can
> > decide when it is safe and best to be handled.
> >
> > 3) it makes things really complicated!
> >
> > > I hope you can be help finding out a better solution.
> >
> > I know I'm repeating myself, but I belive all we need are
> > asynchronous
> > messages. If all communication primitves are modeled with messages
> > all
> > problems mentioned above go away.
> >
> Ok if:
> - also no more Method interface. They have the same risk as
> synchronous
> event handling.

Yes. Synchronous calls would be still possible (by constructing them
with two messages) but they would no longer be asynchronous on the
callee side.

> - on failure of a message queue (queue full) there is a
> - deterministic
> exception handling that is capable of informing _all_ components,
> - even
> the broken ones.

Ack. I would call it configurable policies for fault handling.

> - memory efficient queues.

Agreed!

Best regards
Markus

synch event handling

> > Ok if:
> > - also no more Method interface. They have the same risk as
> > synchronous
> > event handling.
>
> Yes. Synchronous calls would be still possible (by constructing them
> with two messages) but they would no longer be asynchronous on the
> callee side.
>
You lost me here.

> > - on failure of a message queue (queue full) there is a
> > - deterministic
> > exception handling that is capable of informing _all_ components,
> > - even
> > the broken ones.
>
> Ack. I would call it configurable policies for fault handling.
>
> > - memory efficient queues.
>
> Agreed!
>

Sander.

synch event handling

On Mon, Apr 27, 2009 at 02:47:15PM +0200, Vandenbroucke Sander wrote:
> > > Ok if:
> > > - also no more Method interface. They have the same risk as
> > > synchronous
> > > event handling.
> >
> > Yes. Synchronous calls would be still possible (by constructing them
> > with two messages) but they would no longer be asynchronous on the
> > callee side.
> >
> You lost me here.

I believe that synchronous method invocations like RTT::Methods are a
valid use case, but they should be thread safe. I suggest that
RTT::Methods should be implemented as follows (or there should at
least additionally be such a thread safe variant to choose from)

Caller Callee

send Message to callee
and block waiting for
response

when callee gets around
processing Messages, invoke
computation requested by
caller and send response back

gets response and
continues

The Method is synchronous on both sides and the race condition goes
away. From a user point of view there is no difference except that
there isn't any race condition anymore. The IPC by which the message
is transported can be configured to anything from sockets, shared mem,
to carrier pidgeons (but will typically not be required because the
deployer makes the best choice anyway.)

Have I found you again?

Markus

synch event handling

>Sander said: this makes Methods unusable in
>real-time systems by design. The reason: It blocks
>the Caller for a certain, unpredictable amount of time.

Well... yes!!! Isn't it already like that in RTT? It is. You are
blocked an umpredictable time when you call a method.

If we don't want to be blocked, we have to remove the method entity
and that's all.
Markus and Sander, what do you think of:

1) caller send a message and it decides to block waiting for the answer or not.
2) callee get the message and do some calculation. the result is sent
back to caller.
3) caller get this answer. may be it has been waiting or maybe it has
done something usefull in the midtime.

Markus, this is the way that I would do it, but we must be conscious
of its limitation.
First of all, you are always thread-safe on the caller side, but you
are thead-safe on the callee side only if you use a muter or a queue.

>From the implementation point of view, the only difference with
messages of RTT 2.0 is that we are executing the message queue with a
very high priority, undependent from the Task activity.
We are just implementing a way to execute the clculation "as soon as
possible" (and, of course, not "instantly" as method would).
Anyway, with mutexes, it will not be instataneous anyway.

synch event handling

On Mon, 27 Apr 2009, Davide Faconti wrote:

>> Sander said: this makes Methods unusable in
>> real-time systems by design. The reason: It blocks
>> the Caller for a certain, unpredictable amount of time.
>
> Well... yes!!! Isn't it already like that in RTT? It is. You are
> blocked an umpredictable time when you call a method.
>
> If we don't want to be blocked, we have to remove the method entity
> and that's all.

I don't agree: there _are_ use cases where this makes sense. And again, if
your use case does not need methods, just don't use them.

> Markus and Sander, what do you think of:
>
> 1) caller send a message and it decides to block waiting for the answer or not.
> 2) callee get the message and do some calculation. the result is sent
> back to caller.
> 3) caller get this answer. may be it has been waiting or maybe it has
> done something usefull in the midtime.

This is what others have been calling "message passing" :-)

> Markus, this is the way that I would do it, but we must be conscious
> of its limitation.
> First of all, you are always thread-safe on the caller side, but you
> are thead-safe on the callee side only if you use a muter or a queue.
Again, these are architectural issues, which RTT must support, but not
impose or prevent.

> From the implementation point of view, the only difference with
> messages of RTT 2.0 is that we are executing the message queue with a
> very high priority, undependent from the Task activity.

"very high priority" is a _configuration_ issue. And again RTT must support
this but not impose or prevent it.

> We are just implementing a way to execute the clculation "as soon as
> possible" (and, of course, not "instantly" as method would).
> Anyway, with mutexes, it will not be instataneous anyway.

Herman

synch event handling

> On Mon, Apr 27, 2009 at 02:47:15PM +0200, Vandenbroucke Sander wrote:
> > > > Ok if:
> > > > - also no more Method interface. They have the same risk as
> > > > synchronous
> > > > event handling.
> > >
> > > Yes. Synchronous calls would be still possible (by constructing
them
> > > with two messages) but they would no longer be asynchronous on the
> > > callee side.
> > >
> > You lost me here.
>
> I believe that synchronous method invocations like RTT::Methods are a
> valid use case, but they should be thread safe. I suggest that
> RTT::Methods should be implemented as follows (or there should at
> least additionally be such a thread safe variant to choose from)
>
> Caller Callee
>
> send Message to callee
> and block waiting for
> response
>
> when callee gets around
> processing Messages, invoke
> computation requested by
> caller and send response back
>
>
> gets response and
> continues
>
>
> The Method is synchronous on both sides and the race condition goes
> away. From a user point of view there is no difference except that
> there isn't any race condition anymore. The IPC by which the message
> is transported can be configured to anything from sockets, shared mem,
> to carrier pidgeons (but will typically not be required because the
> deployer makes the best choice anyway.)
>
> Have I found you again?
>
Yes you have. From my point of view, this makes Methods unusable in
real-time systems by design. The reason: It blocks the Caller for a
certain, unpredictable amount of time. This is not done in real-time
systems. I do appreciate your effort to make Methods thread-safe but
this isn't the way.

Sander.

synch event handling

On Mon, Apr 27, 2009 at 05:50:09PM +0200, Vandenbroucke Sander wrote:
> > On Mon, Apr 27, 2009 at 02:47:15PM +0200, Vandenbroucke Sander wrote:
> > > > > Ok if:
> > > > > - also no more Method interface. They have the same risk as
> > > > > synchronous
> > > > > event handling.
> > > >
> > > > Yes. Synchronous calls would be still possible (by constructing
> them
> > > > with two messages) but they would no longer be asynchronous on the
> > > > callee side.
> > > >
> > > You lost me here.
> >
> > I believe that synchronous method invocations like RTT::Methods are a
> > valid use case, but they should be thread safe. I suggest that
> > RTT::Methods should be implemented as follows (or there should at
> > least additionally be such a thread safe variant to choose from)
> >
> > Caller Callee
> >
> > send Message to callee
> > and block waiting for
> > response
> >
> > when callee gets around
> > processing Messages, invoke
> > computation requested by
> > caller and send response back
> >
> >
> > gets response and
> > continues
> >
> >
> > The Method is synchronous on both sides and the race condition goes
> > away. From a user point of view there is no difference except that
> > there isn't any race condition anymore. The IPC by which the message
> > is transported can be configured to anything from sockets, shared mem,
> > to carrier pidgeons (but will typically not be required because the
> > deployer makes the best choice anyway.)
> >
> > Have I found you again?
> >
> Yes you have. From my point of view, this makes Methods unusable in
> real-time systems by design. The reason: It blocks the Caller for a
> certain, unpredictable amount of time. This is not done in real-time
> systems. I do appreciate your effort to make Methods thread-safe but
> this isn't the way.

I see. But where would what I suggest be different from the current
implementation? It is only for the case that the computation of the
method is stateless and therefore can be executed truely concurrent
without locking.

Otherwise if the critical paths of the method are protected with
mutexes as the manual suggests, an implicit serialization will take
place resulting in a behavior pretty much the same than what I
suggested.

Maybe these two Method types stateless/side effect free and
statefull/serialized should be distinguished and provided seperately
for performance reasons.

What do you think?

Markus

synch event handling

On Mon, 27 Apr 2009, Vandenbroucke Sander wrote:

>>> On the other hand, if the event handle is executed in the thread of
>>> the component which emitted the event (TaskA), it is easy to
>>> demonstrate that we are very sensible to catastrophic errors (and it
>>> is impossible to prevent such situation in the user's code!!!).
>>> The only solution I can see is that the subscribers to the event
>>> (TaskB) creates an extra thread responsible for the execution of
>>> synchronous handles.
>>> I know, I know!! it sounds non optimal, resource consuming and
>>> "dirty", but I insist that the current implementation is much
>>> unsafer.
>>
>> I agree with you, but I think we should go a step further and question
>> if these synchronous communication mechanisms (methods and synchronous
>> events) don't create more problems than they solve.
>>
>> 1) they make it easy to create race conditions
>>
>> 2) it is *only* the component which receives an event which can
>> decide when it is safe and best to be handled.
>>
>> 3) it makes things really complicated!
>>
>>> I hope you can be help finding out a better solution.
>>
>> I know I'm repeating myself, but I belive all we need are asynchronous
>> messages. If all communication primitves are modeled with messages all
>> problems mentioned above go away.
>>
> Ok if:
> - also no more Method interface. They have the same risk as synchronous
> event handling.

I don't know wether I fully agree with this statement. When you are using a method, you know who your are talking to, so this means that at _design_ time of your component, you already know with whom you will interact. Typically in the usecase of events you don't _require_ the other one, you just _provide_ the event. And in this case, at _design_ time of the component, you don't know with what other components it will interact.

> - on failure of a message queue (queue full) there is a deterministic
> exception handling that is capable of informing _all_ components, even
> the broken ones.

Agreed.

Klaas

synch event handling

On Mon, 27 Apr 2009, Klaas Gadeyne wrote:

> On Mon, 27 Apr 2009, Vandenbroucke Sander wrote:
>
>>>> On the other hand, if the event handle is executed in the thread of
>>>> the component which emitted the event (TaskA), it is easy to
>>>> demonstrate that we are very sensible to catastrophic errors (and it
>>>> is impossible to prevent such situation in the user's code!!!).
>>>> The only solution I can see is that the subscribers to the event
>>>> (TaskB) creates an extra thread responsible for the execution of
>>>> synchronous handles.
>>>> I know, I know!! it sounds non optimal, resource consuming and
>>>> "dirty", but I insist that the current implementation is much
>>>> unsafer.
>>>
>>> I agree with you, but I think we should go a step further and question
>>> if these synchronous communication mechanisms (methods and synchronous
>>> events) don't create more problems than they solve.
>>>
>>> 1) they make it easy to create race conditions
>>>
>>> 2) it is *only* the component which receives an event which can
>>> decide when it is safe and best to be handled.
>>>
>>> 3) it makes things really complicated!
>>>
>>>> I hope you can be help finding out a better solution.
>>>
>>> I know I'm repeating myself, but I belive all we need are asynchronous
>>> messages. If all communication primitves are modeled with messages all
>>> problems mentioned above go away.
>>>
>> Ok if:
>> - also no more Method interface. They have the same risk as synchronous
>> event handling.
>
> I don't know wether I fully agree with this statement. When you are
> using a method, you know who your are talking to, so this means that at
> _design_ time of your component, you already know with whom you will
> interact.

I don't know whether I fully agree with this statement.
(Find the seven, uh, one difference... :-))

You (should) only know the _method name and signature_ but not where your
called object is residing, and how your method call is transported to that
callee (via middleware, via linking, ...)

> Typically in the usecase of events you don't _require_ the
> other one, you just _provide_ the event. And in this case, at _design_
> time of the component, you don't know with what other components it will
> interact.

A good component-based design starts from the same design criteria: don't
rely on knowing with whom you will be interacting.

The _real_ difference between an event and a method is that _you_ want to
block in the case of a method call. And in the special case of a
_synchronous_ event handling, your _system architect_ wants you to block
while waiting for the event to be handled. A good design will not make use
of _any_ information about the called component, in all cases...

>> - on failure of a message queue (queue full) there is a deterministic
>> exception handling that is capable of informing _all_ components, even
>> the broken ones.
>
> Agreed.
This seems a "mission impossible", unless you have a simplistic
interpretation of what a "broken" component is... :-)

Herman

synch event handling

On Mon, 27 Apr 2009, Herman Bruyninckx wrote:
> On Mon, 27 Apr 2009, Klaas Gadeyne wrote:
>> On Mon, 27 Apr 2009, Vandenbroucke Sander wrote:
>>>>> On the other hand, if the event handle is executed in the thread of
>>>>> the component which emitted the event (TaskA), it is easy to
>>>>> demonstrate that we are very sensible to catastrophic errors (and it
>>>>> is impossible to prevent such situation in the user's code!!!).
>>>>> The only solution I can see is that the subscribers to the event
>>>>> (TaskB) creates an extra thread responsible for the execution of
>>>>> synchronous handles.
>>>>> I know, I know!! it sounds non optimal, resource consuming and
>>>>> "dirty", but I insist that the current implementation is much
>>>>> unsafer.
>>>>
>>>> I agree with you, but I think we should go a step further and question
>>>> if these synchronous communication mechanisms (methods and synchronous
>>>> events) don't create more problems than they solve.
>>>>
>>>> 1) they make it easy to create race conditions
>>>>
>>>> 2) it is *only* the component which receives an event which can
>>>> decide when it is safe and best to be handled.
>>>>
>>>> 3) it makes things really complicated!
>>>>
>>>>> I hope you can be help finding out a better solution.
>>>>
>>>> I know I'm repeating myself, but I belive all we need are asynchronous
>>>> messages. If all communication primitves are modeled with messages all
>>>> problems mentioned above go away.
>>>>
>>> Ok if:
>>> - also no more Method interface. They have the same risk as synchronous
>>> event handling.
>>
>> I don't know wether I fully agree with this statement. When you are
>> using a method, you know who your are talking to, so this means that at
>> _design_ time of your component, you already know with whom you will
>> interact.
>
> I don't know whether I fully agree with this statement.
> (Find the seven, uh, one difference... :-))
>
> You (should) only know the _method name and signature_ but not where your
> called object is residing, and how your method call is transported to that
> callee (via middleware, via linking, ...)

Let me keep on disagreeing.
This is _not_ what I said! I _never_ stated that you should know
where your called object is residing. The fact that there is a
_callee_ (without having to know where it resides) as you write above
_is_ the difference. There is no callee in the case of events.

Klaas

synch event handling

>
> > Typically in the usecase of events you don't _require_ the
> > other one, you just _provide_ the event. And in this case, at
_design_
> > time of the component, you don't know with what other components it
will
> > interact.
>
> A good component-based design starts from the same design criteria:
don't
> rely on knowing with whom you will be interacting.
>
> The _real_ difference between an event and a method is that _you_ want
to
> block in the case of a method call. And in the special case of a
> _synchronous_ event handling, your _system architect_ wants you to
block
> while waiting for the event to be handled. A good design will not make
use
> of _any_ information about the called component, in all cases...
>
> >> - on failure of a message queue (queue full) there is a
deterministic
> >> exception handling that is capable of informing _all_ components,
even
> >> the broken ones.
> >
> > Agreed.
> This seems a "mission impossible", unless you have a simplistic
> interpretation of what a "broken" component is... :-)
>
I mean a component whom is unable to process its message queue for
whatever reason.

Sander.

synch event handling

On Mon, 27 Apr 2009, Vandenbroucke Sander wrote:

[...]
>>>> - on failure of a message queue (queue full) there is a deterministic
>>>> exception handling that is capable of informing _all_ components, even
>>>> the broken ones.
>>>
>>> Agreed.
>> This seems a "mission impossible", unless you have a simplistic
>> interpretation of what a "broken" component is... :-)
>>
> I mean a component whom is unable to process its message queue for
> whatever reason.

How are you going to notify this process if it cannot process its messages
anymore? Maybe via a message to its "supervisor" component, who can use a
method call to 'reset' the faulting component's queue in one way or
another?

Herman

synch event handling

> the post about "messages" was going to became a debate about event
> handling, therefore I have created this separate post.
> As I have stated in the wiki page [Contribute! Which weakness have you
> detected in RTT?], I have seen a serious issue in the current
> implementation of synchronous event handling.
>

> We do all agree (I guess)that, from a theoretical point of view,
something
> like an "immediate" reaction to an event must be present in RTT.
> On the other hand, if the event handle is executed in the thread of
the
> component which emitted the event (TaskA), it is easy to demonstrate
that
> we are very sensible to catastrophic errors (and it is impossible to
> prevent such situation in the user's code!!!).
At least it is possible to point out to the user he is doing something
tricky. I have created a wrapper around a RTT::Event witch only allows
void(...) const functions as synchronous event handling. Theoretically a
sync-function can only read the current state of the component. I also
created thread-safe objects for data exchange between sync-function and
component. This way at least the risk is minimized.

We also should think about this kind of risk when it comes to methods,
right?

> The only solution I can see is that the subscribers to the event
(TaskB)
> creates an extra thread responsible for the execution of synchronous
> handles.
> I know, I know!! it sounds non optimal, resource consuming and
"dirty",
> but I insist that the current implementation is much unsafer.
> I hope you can be help finding out a better solution.
>
Then you simply move the problems to the 3rd thread.

In the ideal world we would have decoupling that takes no time and
always succeeds. :-)

Sander.