►
From YouTube: Elsa Workflows Community Meeting 20 ( 2022-08-02)
Description
Meeting 20
Topics
- Thinking about Elsa 3, parallel activities
- Demo from Frans: Fork & Join
A
Sorry
I
was
late.
I
was
walking
the
dog
I
figured
p
before
the
meeting,
but
took
a
little
bit
longer
than
expected.
Okay,
so,
let's
see
what
do
we
have
from
my
end,
not
much
last
meeting
I
messed
up
with
the
recording.
My
audio
wasn't
recorded
pretty
much
the
entire
demo
of
the
activity
definitions
got
scrapped.
I
think
I
haven't
watched
back
the
video,
but
I
believe
my
brother
was
gonna
scratch
it
because
there
was
no
audio.
A
So
what
I
would
like
to
do
is
just
do
a
new
recording
of
just
that
feature
all
right.
So,
as
I
was
saying,
much
progress
for
my
end
with
elsa
3.,
I've
been
working
on
the
job,
scheduling
or
being
able
to
run
jobs.
In
the
background
from
my
workflow
last
week,
muhammad,
he
made
a
comment
or
a
question.
He
asked
what's
the
difference
between
a
job
and
an
activity
and
as
it
turns
out,
the
only
difference
would
be
that
an
activity
executes
synchronously
while
a
job
executes
in
the
background.
A
That's
then
used
to
orchestrate
the
flow
of
the
process,
but
the
activity
execution
itself
can
just
happen
in
on
some
queue
or
in
in
some
background
threat
or
whatever
I've
been
thinking
about
that
and
I'm
gonna
do
a
little
bit
of
experimentation
around
that
as
well,
might
also
be
a
good
solution
for
those
workflows
that
depend
on
executing
work
in
parallel.
So,
as
you
know,
we
have
the
fork
activity
allowing
you
to
branch
in
multiple
paths
of
execution,
but
it's
not
really
happening
in
parallel
right.
The
way
the
engine
works.
A
It
just
schedules
one
branch
after
the
other,
but
as
those
branches
get
scheduled,
each
connected
activity
gets
executed.
So
this
could
mean
that
if
one
branch
takes
a
long
time
to
complete
an
activity-
because
maybe
it's
making
a
database
call
that's
very
slow,
then
that
means
the
second
branch
and
maybe
the
third
branch
they
don't
get
to
execute
until
the
first
one
is
finished.
A
To
be
problematic
for
some
scenarios,
the
current
workaround
would
be
to
move
those
heavy
operations
to
a
job,
maybe
a
hand
fire
job
and
then
having
the
hang
fire
job
resume
the
workflow,
so
the
activity
would
schedule
the
job,
suspend
the
workflow
and
at
that
point
the
remaining
scheduled
activities
have
a
chance
to
complete
and
then
of
course,
once
the
job
finishes
execution,
it
will
resume
the
workflow.
But
if
we
make
this
built
into
the
elsa
engine
and
the
runtime,
then
that
becomes
a
whole
lot
easier.
B
Okay,
it
could
be
interesting
to
also
look
at
what
I've
been
preparing
for
the
parallel
execution,
because
it's
kind
of
related
because
it
schedules
the
activities
in
the
list,
see
how
that
would
help
or
actually
could
be,
requiring
the
solution
that
I've
been
working
on
yeah.
Just
for
you
for
you
to
let
you
know,
I
don't
think
that
if
this
is
going
to
be
a
recording
that
it's
going
to
be
enough
of
quality
to
continue
because
oh
yeah.
B
A
B
A
B
So
far,
it's
been
great.
If
you
don't
talk
about
it,
I
think
it's
gonna.
B
B
B
I
was
wondering
how
I
would
scare
my
screen.
Basically,
so
I've
been
working
on
a
little
proof
concept
about
the
algorithm
to
how
to
handle
parallel
execution.
We
talked
that
about
that
previous
times,
and
I
created
in
a
few
samples
of
how
it
should
work.
Let
me
just
show
you
how
this
one
works
in
this
case.
We're
looking
at
an
a
simple
diagram
where
we
have
a
fork
and
a
join
and
the
join.
Is
this
time
configured
as
weight
all?
B
Basically,
it
means
that
it
needs
to
have
both
sides
of
the
elements
of
the
activities
that
are
connected
to
the
join
need
to
be
executed,
the
same
amount
of
times
before
it
will
continue
to
the
final
activity.
So
it
means
that
whenever
which
one
comes,
first,
do
something
one
or
do
something
else
to
see.
It
will
not
continue
until
the
other
one
is
also
executed,
and
the
joint
does
this
by
counting
all
the
incoming
connections
creating
counters
for
each
and
whenever
an
activity
activates
a
join
or
schedules
a
join.
It
will
then,
on
the
execution.
A
B
The
reason
for
it
is
that
you
have
to
have
a
track
of
how
many
times
something
has
executed,
and
you
could
also
do
it
differently
and
was
thinking
about
that
that
you
would
say
on
the
fork.
Maybe
then
provide
some
token
and
see
whether
or
not
both
of
the
tracks
have
executed
that
token
in
order
to
pass.
B
But
that
makes
it
really
tricky
when
you
have
an
really
complicated
process
where
you
have
different
forks
and
different
joints
that
basically
not
always
come
from
the
same
fork,
and
when
you
look
at
the
three
options
or
actually
four
options.
You
can
always
do
that
by
counting
the
incoming
execution
times.
A
Okay,
so
for
in
this
weight
all
example,
you
could
have
just
kept
a
log
of
the
inbound
activities.
Having
executed,
for
example,
do
something
one
could
be
recorded
in
a
list
that
it
has
executed
and
then
do
something
else
to
see
could
have
been
added
to
that
list,
and
once
the
joint
sees
that
it
has
two
executed
activities
of
the
inbound
pass
executed,
it
could
continue
for
that
scenario.
You
don't
need
a
counter.
You
just
maintain
a
lot
of
inbound
activities
that
have
executed.
B
Exactly
you
could
do
it
with
a
list
as
well.
You
have
to
see
how
you
do
the
counting
to
have
like.
Okay,
there
are
two
items
in
the
list.
I
can
continue,
because
this
do
something
else
to
see,
for
instance,
can
be
executed
through
another
fork
and
so
on
multiple
times,
and
then
you
have
to
be
aware
of
that
from
the
join.
Basically,
what
you're
saying
is
correct.
You
can
do
it
by
counting
just
the
execution
lock
for
that.
A
To
clarify,
I,
I
wasn't
referring
to
the
execution
log,
but
in
the
joint
you
can
imagine
at
least,
let
me
explain
the
way
it's
done
in
lsat
2
right
now.
The
join
activity
has
a
internal
list
where
it
adds
inbound
activities
that
have
executed
so
every
time
join
executes.
It's
gonna
see
what
was
the
previous
activity
that
execute
or
actually
the
other
way
around,
as
do
something
one
executes.
A
It
fires
an
event
and
then
join
handles
this
event
called
activity
executed,
and
then
it
sees
it
checks
to
see
if
that
activity
that
just
executed
so
do
something
one,
for
example.
If
it
is
a
direct
parent,
if
yes,
then
it
will
add
that
to
a
list,
just
the
the
identifier
of
the
something
one
and,
of
course,
when
do
something
else
to
c
executes.
It
also
fires
the
activity
executed
event
in
response
to
which
the
join
activity
adds
that
activity
identifier
to
its
internal
list
and
if
and
then
it
does
a
comparison
to
see.
B
A
I
waiting
for
any
more
inbound
activities
to
execute.
If
no,
then
it
continues.
If,
yes,
it
will
not
continue.
So
it's
it's
unrelated
to
the
activity,
execution
log,
but
you,
but
you
get
the
point,
I'm
just
maintaining
a
list
not
saying
that
this
has
to
be
the
same,
but
I
am
just
trying
to
understand
the
purpose
of
the
counter.
What
are
the
scenarios
where
the
counter
will
increase
to
two,
for
example?
A
So
if
you
start
from
four
on
at
at
the
top,
then
it
executes
to
something
one
that
happens
once
and
this
the
left,
the
right
branch
executes
once
as
well.
So
why
maintain
a
counter?
That's
that's
the
question,
but
I
can
imagine
that
for
this
simple
scenario,
it's
not
necessarily
useful,
but
maybe
for
other
scenarios
that
you're
gonna
discuss
well.
B
It's
basically
the
same
thing:
it's
another
way
of
doing
the
information
about
the
execution.
When
I
was
referring
to
the
execution
log,
it
was
the
internal
execution
lock
of
that
join
because
it
only
needs
to
be
tracking
the
ones
that
were
inbound
for
him
to
so
it
has
an
internal
list
of
the
things
that
gets
executed.
In
my
example,
I
do
it
a
bit
differently.
B
I
schedule
the
activities
that
need
to
be
executed
on
a
ledger
and
pick
up
the
top
one
to
be
executed,
and
then
it
tells
it
knows
how
it
was
executed
and
counts.
Then,
from
that
referring
item
so
when
it
will
not
activate
straightaway
do
something
else
to
be,
but
it
says
this
needs
to
be
executed
and
it
needs
to
be
executed
on
my
behalf,
so
I
issued
it
so
when
something
enters
to
join,
it
will
get
a
notification,
not
a
notification,
but
on
the
list
of
activities
that
need
to
be
executed.
B
B
A
Need
to
think
about
it,
yeah
if
you
can
show
some
code,
maybe
that
makes
it
a
little
bit
clearer.
I
was
also
distracted
by
my
own
thinking.
While
you
were
talking
and
explaining,
I
was
wondering:
will
this
also
work
for
any
other
float
chart
construction
so
between
the
fork
and
the
joint?
Any
kind
of
activity
can
execute,
of
course,
by
default.
This
is
a
flow
chart,
but,
for
example,
do
something
else
to
a
could
itself
be
a
fork
or
it
could
be
an
if
else
or
a
while
loop,
okay,
okay,.
B
Nice
that
can
that
can
be
the
case.
If
you
look
at
here,
let
me
see
if
I
can
make
it
a
little
bit
bigger.
This
is
the
join,
so
I
have
a
counter
the
counter,
a
list
of
counters
and
whenever
it
gets
executed,
there
aren't
any
counters,
which
is
an
odd
case,
while
it's
getting
executed.
So
who
is
executing
this
one?
B
It
adds
all
the
counters
for
connecting
activities
so
the
incoming
activities
it
creates
a
counter
for
those
and
when
it
gets
executed,
it
has
an
activation
token
and
that
activation
token
is
a
carrier
of
information
why
it
is
activated.
So
it
holds
the
previous
node.
It
can
have
additional
custom
properties
where
you
can
make
a
custom
join
act
upon.
Oh,
I'm
only
gonna
count
when
and
custom
property
is
set
or
an
id
is
set
and
yeah
the
clone
not
to
mix
up
the
stuff.
B
This
is
basically
the
carrier
of
information
from
one
activity
to
another
and
I
would
like
to
think
it
as
an
flow
context.
Why?
In
which
context
this
flow
is
running
and
when
it
happens,
increase
count
of
four
it
increases.
For
the
previous
note.
So
if
I
execute
it,
you
will
see
it
in
the
demo
and
let
me
start
it
so
here
when
we
start
it
says
next,
in
line
to
execute,
is
begin.
That's
the
first
one
that
has
no
incoming
that
is
scheduled
on
the
right.
B
You
see
the
activities
to
execute
so
only
begin
is
activated.
So
when
I
now
perform
the
step,
I
execute
begin.
It
just
schedules.
Do
something
for
the
next
one.
So
now
we're
on
the
fork
and
when
fork
gets
executed
is
active
executed
from
do
something
it
will
schedule
both
do
something
one
and
do
something
else
to
a
to
be
executed.
Then
it
grabs
the
top
one
and
it
schedules
the
join
after
that
because
after
do
something
one,
the
join
will
execute
prior
to
that
the
do
something
else
to
a
was
scheduled.
B
So
it's
gonna
execute
that
first
and
now
the
join
is
executed,
and
in
this
case
the
counters
displayed
do
something
one
will
be
added
with
one,
because
that
was
the
activated
from
and
to
do
something
else
hasn't
been
activated.
Yet
from
that
connection,
since
it's
an
weight
all
it
will
not
execute,
because
it's
only
one
executed
once
for
do
something
and
not
for
do
something
else
to
see
so
when
this
executes
now
this
is
the
execution
of
the
join,
it
will
not
schedule
anything.
B
It
just
leaves
it
like
do
something
else
to
be
when
that
executes
it
will
execute
to
c,
and
now
it
comes
to
the
join
the
counter
for
do
something
is
one:
do
something
else
to
see
becomes
one.
Therefore,
both
items
have
been
executed
and
it
will
schedule
final
and
after
final,
it
will
do
the
end
or
the
stop,
and
then
it
will
end
very
cool.
A
So
yeah
question
about
the
did
this
flow,
so
is
this
this
logic?
Is
it
specific
to
any
of
these
nodes
or
is
it?
Is
it
part
of
of
your
demo
workflow
engine,
the
counterweight.
A
B
So
the
engine
is
as
follows.
Let
me
see
if
I
let's
go
to
the
wait
all
so.
Basically
this
is
the
process
definition,
basically
the
json
that
you
also
have
in
elsa,
where
you
have
the
activities
and
you
have
a
lot
of
connections
joining
them
together
after
that
the
engine
doesn't
know
about
how
to
execute
only
that
it
holds
a
record
of
what
he
needs
to
execute.
Furthermore,
nothing
is
done
there.
The
activities
themselves
provide
back
after
a
perform
step
and
result,
and
in
that
result,
this
one
it
returns
an
execution
result.
B
A
B
B
So
dvd,
for
instance,
that
has
a
base
here,
it
says.
Basically
this
does
nothing
because
watch
shorting
time,
but
it
performs
an
execute.
It
sets
the
activation
token
to
this
after
it
executes,
and
then
it
returns
an
execution
result
with
that
activation
token,
and
it
has
the
connections
provided
and
it
says,
get
outbound
connected
nodes
for
this
and
it's
searching
the
connections.
What
is
going
to
be
the
next
or
connecting
activities?
I.
A
See
yeah,
so
this
makes
sense,
but
this
does
require
every
node
to
be
aware
of
the
fact
that
it's
part
of
a
flow
chart
so
that
that
might
become
a
little
bit
challenging
but
yeah.
We
need
I'm,
maybe
a
one
step
far
too
far
for
now,
but
it
might
be
a
little
bit
of
a
chance
to
adapt
this
to
the
lc3
model
where
activities
are
not
aware
of
their
outer
structure.
So
this
is
a
way
of
course,
that
it's
part
of
a
a
diagram
or
a
flow
chart
yeah.
So
we're
gonna
have
to
see
that.
B
A
B
B
I
will
post
this
it's
already
in
repo,
so
I
will
share
a
link
to
this
repo
and
you
can
fiddle
around
with
the
code
a
bit
and
we
will
not
go
over
all
the
details.
But
let's
go
over
this
one,
where
it's
basically
the
same
after
the
final
it
returns
back.
Then
we
can
see
a
bit
more
about
how
the
counting
goes.
So
it
will
go
to
final.
B
A
We
take
a
look
at
the
process
in
full
if
you
scroll
down
a
little
bit,
yeah
and
so
forth
on,
do
something
join.
B
A
B
You
will
see
on
the
weight
any
that
it
will
after
the
first
join
it
will
schedule
the
finals
straight
away
because
it's
the
first
one
and
after
the
second
join
here
it
will
not
schedule
the
final
which
will
stop
and
because
the
first
one
was
already
executed,
yeah
makes
sense,
continue,
always
will
basically
having
scheduled
final
already
now
for
the
first
one.
Then
the
next
one
is
activated
and
it
will
schedule
final
again,
so
that
will
trigger
it
two
times.
This
one
is
a
funny
one,
but
it
on
this
one.
B
We
can
talk
about
a
bit
more
elaborate
ways
of
determining
when
to
join
and
when
to
continue,
and
even
do
some
funny
things
with
the
execution
that
were
scheduled
so
bear
with
me,
it's
funny
one.
So
we
begin
do
something
we
fork
and
we
fork
into
three
items.
Then
we
go
to
a
join
and
on
the
right
grinds
as
well,
but
the
fork
something
goes
back
to
the
fork
want
to
go
again
in
those
joints
and
this
joint
isn't
not
a
default.
B
One
it's
a
custom
join
and
I
will
show
you
and
show
you
the
code
for
that
see
the
custom
join
here
and
in
the
execute
at
once.
It
increases
the
counter,
but
where
is
it?
Oh
yeah
here
get
execution
result.
The
count
is
where
the
node
starts
with.
Do
we
add
them
if
they
are
bigger
than
one
we'll
continue?
We
don't
care
about
the
one
that
comes
from
a
fork
because
it
was
called
for
it
doesn't
hold
do
and
we're
not
gonna
continue.
B
The
fork
is
already
on
one,
because
that
is
the
shortest
way
here
now
we
will
not
continue
because
it
starts
not
with
do
and
they
are
not
equal
or
greater
than
one.
So
the
four
doesn't
have
a
result.
Now
it
will
continue,
because
the
do
somethings
are
both
equal
to
one
or
more,
but
what
it
is
that
these
activities
are
bound
to
be
executed.
But,
as
I
clear
everything
I
just
want
to
continue
now
with
the
final.
So
if
I
do
next,
you
see
that
all
other
activities
are
now
gone
and
only
this
one
continues.
B
So
if
you
have
a
loop
that
is
scheduled
to
be
continuing,
you
can
discontinue
that
loop
by
saying,
okay
reschedule
everything
only
with
the
final.
I
don't
think
that
we
should
support
this
for
out
of
the
box,
but
it
shows
that
the
flexibility
is
there
to
come
up
with
other
custom
joints
on
different
aspects
or
different
counters
different
way
of
counting,
and
it
is
up
to
the
the
one
that
implements
a
custom
join
to
determine
what
the
conditions
need
to
be
in
order
to
continue
very
cool
yeah.
A
I
think
you
did
a
great
job
in
that
regard.
It's
it
is
a
little
bit
complicated,
but
I
get
the
overall
picture,
but,
to
be
honest,
I
will
have
to
rewatch
this
recording
and
sync
sync,
my
brain
into
the
little
details
here,
but
overall
it
makes
sense.
I
like
it
a
lot.
A
B
Well,
we
have
to
think
about
as
a
lot
of
stuff
now,
and
I
will
tell
you
what
I've
been
thinking
about
the
last
couple
of
days
and
that
is
really
tricky.
So
we
see
now
that
we
can
have
loops
in
flow
charts
or
in
any
execution.
That
means
that
activities
can
be
executed
multiple
times,
even
if
you
think
about
a
fork,
for
instance,
where
you
have
a
specific
context,
you
might
think.
Okay,
the
execution
is
also
in
a
in
a
certain
context.
B
Take
for
example,
document
flow
approval
flow,
the
sample
that
you
also
created
where
you
send
out
multiple
documents
and
they
need
to
be
approved
by
two
persons.
When
you
send
out
all
those
forms-
and
you
have
that
workflow
running
it
can
listen
to
signals
for
a
specific
document
id
and
you
can
have
a
join
for
that
is
levered
on.
Did
we
both
agree
upon
this
document
id,
and
this
is
why
we
have
have
to
have
that
flow
context
to
determine
in
which
document
context
are
we
executing
this
flow?
B
But
if
you
then
refer
back
to
a
previous
executed
activity
like,
for
instance,
get
a
property
by
name
by
name
property,
or
so
you
actually
can
have
multiple
instances
where
it
executed
and
you're
specifically
addressing
for
this
context
id
which
means,
from
this
five
times
that
it's
got
executed.
You
want
maybe
the
third
result,
because
that
was
executed
in
the
context
of
the
item
that
you're
now
dealing
with,
and
that
makes
it
really
tricky.
Yeah.
A
B
B
A
B
A
B
Yeah
yeah
and
I
couldn't
wrap
my
head
around
it-
whether
or
not
we're
now
seeking
the
x
cases
that
we
shouldn't
be
supporting,
because
it
can
be
dealt
quite
elegantly
and
simply
by
saying.
Well,
if
you
want
to
execute
something
in
a
context,
do
it
in
a
sub
workflow
or
in
a
separate
workflow
instance
that
is
dedicated
to
that
ins.
To
that
context,
and
that
makes
it
really
easy
and
also
really
visible
for
a
context,
and
that
should
could
also
be
an
solution.
Yeah.
A
A
Yeah
yeah
great
well,
we'll
we'll
give
it
some
more
thoughts
and
some
experimentations
okay
cool.
Are
we
recording
this
by
the
way?
I
also
want
to
check
that
again
yeah.
This
is
being
recorded,
so
you'll
be.
A
B
A
A
Don't
have
anything
else,
although
I
did
say
I
wouldn't
demo
the
activity
definitions
but
I'll
do
it
separately,
it's
just
just
a
demo
of
that
feature.
So
I'll
leave
that
out
of
this
okay.
A
B
The
repo
and
share
it
shall
I
put
it
in
the
weekly
in
this
blog
or
in
this
part
of
the
discord
yeah.
That
would
be
great
yeah,
okay,
cool
all.