On Thursday 29 September 2005 17:40, Marty Kraimer wrote:
> > Ralph Lange wrote:
> >> menu(LinkWait) {
> >> choice(linkWaitNo,"no")
> >> choice(linkWaitYes,"yes")
> >> choice(linkWaitGroup,"group")
> >> }
> >>
> >> struct(ProcessLink) {
> >> field(pvname,string) { link}
> >> field(wait,menu(LinkWait))
> >> field(delay,double64)
> >> }
> >>
> >> so that the example is:
> >>
> >> void collectSample=processLink=[3] {
> >> {pvname="incA”; wait=group},
> >> {pvname="incB”; wait=group,delay=1.0},
> >> {pvname="getSample”; wait=yes,delay=5.0}
> >> }
> >> }
Let us ignore the proposal to add timeouts or delays, for the moment.
I share Ralph's sentiment about loss of symmetry, but his proposal has a
drawback: It can't express adjacent but separate parallel groups.
Suppose we want to have processLink[0] and processLink[1] to be
processed in paralel, wait for both of them to complete, then process
processLink[2] and processLink[3] in paralel, too, then wait for them
to complete, and finally complete processing. This is not possible with
Ralph's 'group' approach, because 'wait=group' always groups /all/
adjacent links with this property.
Speaking generally, I think the whole problem stems from a too
low-level, that is, implementation-oriented view of how links get
processed. See, for instance, Kay's remark that "'parallel' is meant as
a 'execute in fork'"; see also the (implicit) assumption that the links
get (somehow, more or less, that is, "modulo parallel flags") processed
in the order they appear in the processLink array. All this makes it a
bit hard to reason about the semantics of the link specification.
So, let us for the moment forget that the process links are given in a
certain order and instead view them as an un-ordered set of independent
entities. We would then need to specify for each of them
(a) whether it should 'complete' immediately or only after the record it
references has completed its processing, and
(b) which other links must have completed processing, before this link
can start processing.
As regards (a), this is easily done with a boolean flag. I propose to
name it 'async' with a default value of 'false'.
With regard to (b), this could be an (unordered) list of other /links/.
To specify the identity of a link, we could use it's index in the
array. The property could be named 'after', with a default value of {}
(empty set).
Thus my (first) proposal:
void collectSample={
processLink = [3] {
{pvname = "incA"; async=true},
{pvname = "incB"; async=true},
{pvname = "getSample"; async=true; after={0,1}}
}
}
There is still one problem with this: we cannot yet specify when the
record /containing/ the links should complete it's own processing. I
can imagine a number of ad-hoc solutions, like adding a special field,
maybe grouped to gether with the process links into a struct, whatever.
However, let us again take a step back and review the problem from a
high-level perspective.
First, note that firing one of the process links on the one hand, and
completion of the record's processing on the other hand, are both
merely two special steps (actions) to be performed at certain times as
part of general record processing. The fact that they are so tightly
coupled is, I think, a legacy of the way dbPut completion was hacked
into V3. I can't see any reason why this must remain so.
Second, the new record processing semantics already subdivides record
processing into a number of steps.
Third, remember Kay's idea for plugging additional functionality into
record processing at certain predefined 'slots'.
There is a pattern here, I think. It suggests the following
generalization of the above proposal. Note that these are quite raw
ideas.
Each step of processing gets associated with a record field. This field
specifies its trigger condition in a declarative way in the form of a
list of dependent entities owned by the record. The meaning is that all
these entities must have completed their own processing, before this
one can start its processing. These 'entities' can be:
o input, output, or process links
o subentities like an embedded struct with it's own support
o maybe additional components, plugged-in at record creation time,
or even online
o a certain number of fixed points, one of them record process finish
All these things have the common attribute 'after' (or whatever it is
called). All predefined link types, processing steps, and all
subentities of fixed type (struct+support) have a default value for
this property declared in the dbd file. For instance, the default for
the "record finish field" is 'after={processLink}', meaning "record
processing has finished after all process links have". (This is with
the understanding that naming an array means "all its elements"; we
could also define some sort of scoping, i.e. inside an array of links,
it would be sufficient to give the index to identify another one of
those links. Inside a struct, the tag would suffice, etc.)
Processing steps that are specific to a certain record type can be
reflected as fields that also have this property. Additionally, the DB
designer (maybe also the record type designer) can give any such fields
other values, thereby overriding the redefined behavior in a controlled
way. Individual proocess links, for instance, could be fired at any
time during record processing, not only at the end (although this would
be the default).
Any comments?
Ben
- Replies:
- Re: [Fwd: Re: Link arrays / syntax] Marty Kraimer
- References:
- [Fwd: Re: Link arrays / syntax] Marty Kraimer
- Navigate by Date:
- Prev:
RE: data access structures, strings Jeff Hill
- Next:
Archamps Core Meeting Notes Dalesio, Leo `Bob`
- Index:
2002
2003
2004
<2005>
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
[Fwd: Re: Link arrays / syntax] Marty Kraimer
- Next:
Re: [Fwd: Re: Link arrays / syntax] Marty Kraimer
- Index:
2002
2003
2004
<2005>
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|