[Click] "Graft" ports

Philip Prindeville philipp_subx at redfish-solutions.com
Fri Jan 21 20:42:18 EST 2011


The original concern (with exposing global objects into the guts of an elementclass) was that this would only work for a single instance is valid... that is, if A imports B, then you can only have a single object of class A.

The advantage of graft points was that you'd have to plumb instances individually, same as for input and output ports.

My only point about graft point was that (a) they would simplify keeping track of indices on complex objects (especially for objects that are generated from scripts with variable numbers of inputs and outputs); (b) they would simplify notation by specifying both input and output to the grafted-to object at the same time, and (c) they would impose rules about graft points being used in pairs that doesn't exist for inputs and outputs which are orthogonal to each other (at least with respect to an object's perspective of the outside world).

I thought about it some more, and if the default for any unspecified (graft) connection was :: { input -> output } then that would make it very easy to "pepper" an object with various inspection and instrumentation points, or points where you might later want to apply additional processing on a packet as it flows through the innards of a class.

I could easily foresee a complex object where I had graft points for:

[0] the packet at ingress;
[1] the packet after it has SNATting performed;
[2] the packet after deep inspection into layer 7 and rewriting of addresses;
[3] resetting the timer on the association;
...
[n] the packet at egress;

And you wouldn't need to recode an object to add to peek into it at various well-known (and previously defined) places.

Like I said: graft points are just a notational convenience.  At the end of the day, they would just map into pairs of input and output ports... but the implementation would be handled by the preprocessor.


On 1/21/11 4:47 PM, Eddie Kohler wrote:
> Hey, a couple points.
>
> (1) Unlike Cliff and Ian, I see some value for importing external elements into a compound.  Perhaps a statement like "import(ELEMENTNAME)" would be required.  Although new errors could happen, they'd be pretty easy to understand even now, and the messages could be improved.
>
> (2) On the below, we generally write debuggers like this:
>
> // elementclass Debugger {$tag | input -> output};
> elementclass Debugger {$tag | input -> IPPrint($tag, MAXLENGTH 64) -> output};
>
> Then you refer to Debugger as an element.
>
> I want to note that graft points as used in THIS mail are supported now; they are implemented as normal inputs and outputs.  I don't understand what you gain by treating grafts as separate from normal inputs and outputs.  They must always be connected or there are errors.
>
> Eddie
>
>
> On 01/20/2011 04:11 PM, Philip Prindeville wrote:
>> One other nice property about graft-points is this:
>>
>> elementclass MyIncrediblyHairyObject {
>> ...
>> }
>>
>> miho :: MyIncrediblyHairyObject;
>> ...
>>
>> miho [0]<->   null :: { input ->   output }<->   [0] miho;
>> // miho [0]<->   dbg0 :: { IPPrint("Inspection 0", MAXLENGTH=64) }<->   [0] miho;
>>
>>
>> and by just moving the comment prefix around, I can turn on or off debugging, without having to disturb the body of the elementclass itself.
>>
>>
>>
>>
>> On 1/20/11 3:59 PM, Philip Prindeville wrote:
>>> I've been thinking about this some more...
>>>
>>> If I have the following:
>>>
>>> elementclass Foo {
>>>
>>>      stuff1 ->   external-object ->   stuff2;
>>>
>>> }
>>>
>>> then this can be rewritten as:
>>>
>>> elementclass Foo {
>>>      stuff1 ->   [N] output;
>>>      input [M] ->   stuff2;
>>> }
>>>
>>> f :: Foo;
>>>
>>> f [N] ->   external-object ->   [M] f;
>>>
>>> I'd like to propose a notational convenience called "graft" (as in a graft-point).
>>>
>>> graft[0] would be short-hand for 1+ the highest used input, and [0] graft would be 1+ the highest used input.
>>>
>>> (and so on for [1], [2], etc.)
>>>
>>> We'd need a new operator for graft-points.  Maybe:
>>>
>>> f [G]<->   [a] external-object [b]<->   [G] f;
>>>
>>> it would be a syntactic error to mismatch subscripts for the object being grafted to.
>>>
>>> The notation inside the elementclass would be:
>>>
>>> elementclass Foo {
>>>      stuff1 ->   graft [G] ->   stuff2;    // or ... [G] graft ...
>>> }
>>>
>>> Does that make sense?
>>>
>>> -Philip
>>>
>>>
>>> On 1/18/11 3:43 PM, Beyers Cronje wrote:
>>>> The config you posted below Ian explicitly states "This would be legal:" at
>>>> the top.  I think Ian is referring to the second config that will cause
>>>> issues:
>>>>
>>>> "
>>>> I think this should complain that fd[0] is being used twice (port
>>>> connection error), although it may take a minute to see why that's the
>>>> case (and would be much trickier to see in a more complex config):
>>>> --------------------------------------
>>>> fd::FromDevice(...);
>>>>
>>>> elementclass Bar {
>>>>       fd[0] ->   Print() ->   [0]output;
>>>> }
>>>>
>>>> a::Bar() ->   Discard();
>>>> b::Bar() ->   Discard();
>>>> --------------------------------------
>>>> "
>>>>
>>>>
>>>> On Wed, Jan 19, 2011 at 12:32 AM, Philip Prindeville<
>>>> philipp_subx at redfish-solutions.com>   wrote:
>>>>
>>>>> On 1/18/11 7:34 AM, Ian Rose wrote:
>>>>>> If I am thinking this through correctly, IMHO it wouldn't be a good idea
>>>>>> to allow elementclasses to do this.  Reason being that in some cases you
>>>>>> could create port connection errors merely through declaring multiple
>>>>>> elements of your new elementclass type.  This would be an unexpected and
>>>>>> confusing error since its impossible to do currently.  AFAIK currently
>>>>>> there are no errors that can occur merely by *declaring* too many
>>>>>> elements of some type.  So this would introduce a whole new category of
>>>>>> error.  Some examples:
>>>>>>
>>>>>> This would be legal:
>>>>>> --------------------------------------
>>>>>> fd::FromDevice(...);
>>>>>>
>>>>>> elementclass Bar {
>>>>>>         fd[0] ->    Print() ->    [0]output;
>>>>>> }
>>>>>>
>>>>>> a::Bar() ->    Discard();
>>>>>> --------------------------------------
>>>>>>
>>>>>> I think this should complain that fd[0] is being used twice (port
>>>>>> connection error), although it may take a minute to see why that's the
>>>>>> case (and would be much trickier to see in a more complex config):
>>>>> Sorry, not seeing why the above case represents using the port twice...
>>>>>
>>>>>
>>>>>> --------------------------------------
>>>>>> fd::FromDevice(...);
>>>>>>
>>>>>> elementclass Bar {
>>>>>>         fd[0] ->    Print() ->    [0]output;
>>>>>> }
>>>>>>
>>>>>> a::Bar() ->    Discard();
>>>>>> b::Bar() ->    Discard();
>>>>>> --------------------------------------
>>>>>>
>>>>>> In order to cause this same error currently (without the proposed
>>>>>> elementclass enhancement) you'd have to do this, which I think makes the
>>>>>> error more obvious:
>>>>>> --------------------------------------
>>>>>> fd::FromDevice(...);
>>>>>>
>>>>>> elementclass Bar {
>>>>>>         input[0] ->    Print() ->    [0]output;
>>>>>> }
>>>>>>
>>>>>> fd[0] ->    a::Bar() ->    Discard();
>>>>>> fd[0] ->    b::Bar() ->    Discard();
>>>>>> --------------------------------------
>>>>>>
>>>>>>
>>>>>> Just my $0.02.
>>>>>>
>>>>>> - Ian
>>>>>>
>>>>>>
>>>>>> On 01/17/2011 07:55 PM, Philip Prindeville wrote:
>>>>>>> Yeah, it especially makes sense to have arpfoo be global if it needs to
>>>>> be accessible from two different elementclass's, one that deals with the IP
>>>>> flow (input [0] and output [0]) and another one that deals strictly with the
>>>>> ARP request/reply flow (input [1] and output [1]).
>>>>>>> Someone else will have to come up with the patches...  I've not yet
>>>>> dabbled in the code itself.
>>>>>>>
>>>>>>> On 1/17/11 4:35 PM, Eddie Kohler wrote:
>>>>>>>> Hi Philip,
>>>>>>>>
>>>>>>>> I can see why you thought compound elements would work that way, but
>>>>> they don't.  They are very strictly encapsulated: all connections to other
>>>>> elements must take place through explicit inputs and outputs.
>>>>>>>> I admit it would make sense to do it the way you've imagined.  Patches
>>>>> welcome...
>>>>>>>> Eddie
>>>>>>>>
>>>>>>>>
>>>>>>>> On 1/15/11 2:53 PM, Philip Prindeville wrote:
>>>>>>>>> I've got a configuration where I do:
>>>>>>>>>
>>>>>>>>> ...
>>>>>>>>> arpfoo :: ARPQuerier(...);
>>>>>>>>>
>>>>>>>>> elementclass Bar {
>>>>>>>>> ...
>>>>>>>>>           class :: classifier(...);
>>>>>>>>> ...
>>>>>>>>>            class [2] ->       [1] arpfoo;
>>>>>>>>> ...
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> but it complains that "unknown element class 'arpfoo'" in a few
>>>>> places, and that input 1 isn't used...
>>>>>>>>> So I'm confused.  Everything is scoped globally... even stuff defined
>>>>> within an elementclass gets scoped globally.
>>>>>>>>> Why then can't I access a global variable from within an
>>>>> elementclass's scope?
>>>>>>>>> What am I missing?
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>>
>>>>>>>>> -Philip
>>>>>
>>>
>>



More information about the click mailing list