flogo-lib
flogo-lib copied to clipboard
activities.Factory
¿Why do the triggers follow the Factory pattern and the activities instead just use a constructor method?
Currently there can be multiple instances of a trigger so we chose a factory pattern. There is only one instance of an activity and at the moment we do not need to inject anything into Activity so there was no need to impose a factory. For consistency we could look into enforcing a factory pattern.
I don't get what you mean by single instance of activities. You could have as much as you want, can't you? For example 2 different CoAP activities sending messages to different servers.
As for the inject part, are you refering to the metadata? Because you are also injecting metadata to the activities through the constructor for the activities and through the factory for the triggers case.
I'm not trying to question your design, jsut trying to understand it.
An activity object is only instantiated once in the engine, it is basically a singleton. All of the necessary data to execute it (which is described in the metadata) is sent along in the activity.Context when the Eval is executed. So essentially it is sort of like a function call.
We could enhance the interface in the future so that the fact that it behaves like a function call might be more clear... lets say for example:
Eval(context, inputs) (outputs, done, err)
The engine doesn't inject the metadata into an Activity, the activity provides it as a description of what are required inputs and subsequent outputs when it is called. Technically the activity implementation just has to implement activity.Activity and register itself. The CLI generates code to facilitate that registration if you adhere to providing a factory method "func NewActivity(metadata *activity.Metadata) activity.Activity" in your code, so we are kind of doing a factory by convention and not interface.
NewActivity(metadata *activity.Metadata) activity.Activity
is used by code auto-generated from the CLI to register the activity so that it can then be instantiated. I managed to find this in flogo-cli's code some time ago, as I wasn't finding where that method was being called. I must say that this approach is a bit unclear as it is not docummented.
This is one of the reasons I asked for a glossary. I'm gonna try to make a formal definition, correct whatever is not right or whatever is missing.
- An application is a set of trigger instances and action instances, the mappings relating both and the activity instances that will execute the tasks that form an action instance.
-
App = {ti, ai, m, AI}
whereti
is the set of all trigger instances,ai
is the set of all action instances,m
the set of all mappings andAI
the set of all activity instances..
- Triggers:
-
ti implements t
wheret
is the set of all trigger types. -
size(t) = N
whereN
is the ammount of trigger types. -
t = {t_1, t_2, ..., t_i, ..., t_N}
wheret_i
is the trigger typei
. -
size(ti) = M = sum(i=(1=>N), M_i)
whereM
is the ammount of trigger instances of any type andM_i
the ammount of instances of typei
. -
ti = {ti_(1,1), ..., ti_(i,j), ..., ti_(N,M_N)}
whereti_(i,j)
is the trigger instancej
oft_i
.
- Actions:
-
ai implemts a
wherea
is the set of all action types. -
size(a) = O
whereO
is the ammount of action types. -
a = {a_1, a_2, ..., a_k, ..., a_O}
wherea_i
is the action typek
. -
size(ai) = P = sum(k=(1=>O),P_k)
whereP
is the ammount of action instances of any type andP_k
the ammount of instances of typek
. -
ai = {ai_(1,1), ..., ai_(k,l), ..., ai_(O,P_O)}
whereai_(k,l)
is the action instancel
ofa_k
.
- Each trigger instance starts any ammount of action instances. This may not be actual components of the application right now from a code perspective but are references in the config and will become more tangible components with future releases as explained in the first Flogo Happy Hour.
-
size(m) = M
-
m = {m_(1,1), ..., m_(i,j), ..., m_(N,M_N)}
wherem_(i,j)
is the set of relations of trigger instanceti_(i,j)
. -
m_(i,j) = {ti_(i,j), [ai]}
where[ai]
is a vector containing each of the actions that the triggerti_(i,j)
starts.
- Activities:
-
AI implements A
whereA
is the set of all activity types. -
size(A) = Q
whereQ
is the ammount of activity types. -
A = {A_1, A_2, ..., A_m, ..., A_Q}
whereA_m
is the activity typem
. -
size(AI) = Q
-
AI = {AI_1, AI_2, ..., AI_m, ..., AI_Q}
whereAI_m
is the activity instance ofA_m
.
- Each action instance is made up of tasks that are executed by the (method
activity.Eval(metada *activity.Metadata) activity.Activity
of the) activities instancesAI
:
-
ai_(k,l) = [T_(k,l,1,m), T_(k,l,2,m), ..., T_(k,l,n,m), ..., T_(k,l,R_(1,k),m)]
whereT_(k,l,n,m)
is the taskn
executed byAI_m
belonging toai_(k,l)
andR_(k,l)
is the ammount of tasks ofai_(k,l)
.
Equations 8-11 and 20 can be simplified due to the fact that there's only 1 action type, but being located in flogo-contrib suggests that there may be more action types in the future, thats why I sticked to the more general version. The simplified version would be:
- 8-11
-
size(a) = 1
-
a = {a_1}
-
size(ai) = P = P_1
-
ai = {ai_1, ..., ai_l, ..., ai_,P}
- 20
-
ai_l = [T_(l,1,m), T_(l,2,m), ..., T_(l,n,m), ..., T_(l,R_(1,k),m)]
Answering to #111 I was not sure if the single activity instance was per App or per Flow/Action.