Hi Ken,
Thanks for the rapid response.
First, let me explain some background here.
I am looking for Java based pipelining solutions to incorporate into an
exisiting application. The use of pipelining is well established in the
sector, with applications like Pipeline Pilot and Knime, and so many
of the common needs have been well established over several years by
these applciations.
Key issues that my initial investigations of Jakarta Pipeline seem to
identify are:
1. Branching is very common. This typically takes 2 forms:
1.1. Splitting data. A stage could (for instance) have 2 output ports,
"pass" and "fail". Data is processed by the stage and sent to whichever
port is appropriate. Different stages would be attached to each port,
resulting in the pipeline being brached by this pass/fail decision.
1.2. Attaching multiple stages to a particular output port.
The stage just sends its output onwards. It has no interest in what
happens once the data is sent, and is not concerned whether zero, one or
100 stages receive the output. This is the stage1,2,3,4 scenario I
outlined previously.
2. Merging is also common (though less common than branching).
By analogy with braching, I would see this conceptually as a stage
having multiple input ports (A and B in the merging example).
Taken together I can see a generalisation here using named ports (input
and outut), which is similar, but not identical, to your current concept
of branches.
So you have:
BaseStage.emit(String branch, Object obj);
whereas I would conceptually see this as:
emit(String port, Object obj);
and you have:
Stage.process(Object obj);
whereas I would would conceptually see this as:
Stage.process(String port, Object obj);
And when a pipeline is being assembled a downstream stage is attached to
a particular port of a stage, not the stage itself. It then just
recieves data sent to that particular port, but not the other ports.
I'd love to hear how compatible the current system is with this way of
seeing things. Are we just talking about a new type of Stage
implementation, or a more fundamental incompatibility at the API level.
Many thanks.
Tim
Ken Tanaka wrote:
Tim Dudgeon wrote:
Ken Tanaka wrote:
The Pipeline Basics tutorial has now been incorporated into the
project page. Thanks to some help and cleanup from Rahul Akolkar the
documentation submitted was installed quickly. See
http://commons.apache.org/sandbox/pipeline/pipeline_basics.html
-Ken
That documentation is really useful. Thanks!
Wow, someone is actually looking at this. I'll work on cleaning up the
documentation some. I hope people realize that some of the color-coded
examples got some inadvertent newlines added--but this isn't relevant to
your questions.
Could I follow up one of the earlier questions in this thread on
branching and merging.
From those docs it looks to me like the way data was set to a branch
is a bit strange. There appears to be a FileReaderStage class that has
Java bean property called htmlPipelineKey:
<stage className="com.demo.pipeline.stages.FileReaderStage"
driverFactoryId="df1" htmlPipelineKey="sales2html"/>
and later in the pipeline a branch is defined that names the pipeline
according to that name:
<pipeline key="sales2html">
This seems pretty inflexible to me. Any branches have to be hardcoded
into the stage definition. I was expecting a situation where multiple
stages could be the recipients of the output of any stage, and these
can be "wired up" dynamically. e.g. something like this:
|--stage2
|
stage1---+--stage3
|
|--stage4
so that all you needed to do was to define a stage5 as one more
downstream stage for stage 1 and it would transparently receive the data.
Is this possible, or does the branching have to be hard-coded into the
stage definition?
I wouldn't call the way branches are specified "hard coding", since the
xml file here is a configuration file. For our current use, branches are
pretty rare, so the pipeline framework deals best with simple cases that
are fairly linear. Also, if stage1 is a branching stage, then that stage
was written with branching in mind, and the "htmlPipelineKey" is a
hard-coded property name in the stage source code, so it can direct
output when it passes data out to the framework. To simplify matters,
all your branching stages could follow a convention of using "branchKey"
(or some other generic name), then you wouldn't have to remember what
variable holds the branch name for which stage.
A stage could be written to take an arbitrary number of branch names,
and thus send output down multiple branches, although it can get
complicated configuring rules on what goes where if the same thing isn't
going to all the branches. So rather than making stage1 a branching
stage, it could be followed by "stageMulti", which would send copies of
it's input to a number of outputs:
|-----stage2
|
stage1----stageMulti----stage3
|
|-----stage4
stageMulti could then be used to add branching to any stage it follows.
I can imagine making configuration files a little simpler with regards
to setting up branching, but the more intelligent configuration file
reader to handle that hasn't been written.
Similarly for merging. To follow up the previous question, let say I
had stageA that output some A's and stage B that output some B's (lets
assume both A's and B's are simple numbers). Now I wanted to have a
stageC that takes all A's and all B's and generates some output with
the, (lets assume the output is A * B so that every combination of A *
B is output). So this would look like this:
stageA--+
|
|----stageC
|
stageB--+
Is it possble to do this, so that stageA and stageB are both writing
to stageC, but that stageC can distinguish the 2 different streams of
data?
First off, the current design expects all pipelines to start with one
stage, to accept feed values out of the config file (or place command
line arguments into the first stage queue if the main pipeline
application was been written to do that). So maybe you have a stageInit
which takes a single number like "3"
feed "3" --> stageInit----stageA
|
----------stageB
stageInit can then pass "3" on to stageA and stageB, possibly causing
stageA to create 3 2-digit numbers and stageB to create 3 3-digit numbers.
For merging, stageC will accept normal input from a stage as well as
watch for events carrying additional data. stageC may well have to
accumulate input and then produce output as events are received. Stages
normally accept one input, which is either a feed or the output of the
stage immediately preceding them. Input from elsewhere or from more than
one source is currently handled as events raised by the source and
received by a "notify" method in the receiving stage.
feed "3" --> stageInit----stageA-------------stageC --> 10*111, 10*222,
10*333, 20*111, 20*222, 20*333, 30*111....
| 3 10, 20, 30 :
----------stageB................:
3 111, 222, 333
---- normal data flow
.... event passed data
Like branching, for our uses merging is rare. Also beware of running out
of memory if you are doing any accumulation of data to merge input from
more than one stage.
-Ken
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]