Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi step workflow #1201

Merged
merged 12 commits into from
Aug 8, 2019
Merged

Multi step workflow #1201

merged 12 commits into from
Aug 8, 2019

Conversation

antho1404
Copy link
Member

@antho1404 antho1404 commented Jul 31, 2019

Fix #1197

TODO:

  • Add multiple tasks to workflows
  • Create hash for workflows
  • Add workflow hash to execution
  • Resolve next steps on workflow based on workflowHash + execution height (length of the chain)

Testing:

Note that the CLI is not yet updated for that so you will need to use the GRPC API directly.

We will create the following workflow:

+------------+      +------------+      +------------+     +------------+
|  ServiceA  |      |  ServiceB  |      |  ServiceC  |     |  ServiceB  |
|   taskX    +----->+   taskY    +----->+   taskZ    +---->+   taskY    |
+------------+      +------------+      +------------+     +------------+
when Result of ServiceA#taskX
  then Call ServiceB#taskY
  then Call ServiceC#taskZ
  then Call ServiceB#taskY

These services are just accumulator that take a message in input and return a message that is the concatenation of the input plus the task executed.

You can find the services here:

ServiceA:

{"name":"serviceA","tasks":[{"inputs":[{"type":"String","key":"message"}],"outputs":[{"type":"String","key":"message"}],"key":"taskX"},{"key":"emits"}],"events":[{"data":[{"type":"String","key":"message"}],"key":"eventX"}],"configuration":{},"hash":"9P49TPmeToJDb2vSLwv3iovz56UWJJinRMhM3TMkEcEw","sid":"serviceA","source":"QmUojyMjo2JUvhktLU4royUBDEsVzU4z1onPovGpVQAFDW"}

ServiceB:

{"name":"serviceB","tasks":[{"inputs":[{"type":"String","key":"message"}],"outputs":[{"type":"String","key":"message"}],"key":"taskY"}],"configuration":{},"hash":"3vZaZD59AUzxMAaRREFFR2XEKvU6mYDVv5UweTgSQF4c","sid":"serviceB","source":"Qmf2e92jNxxmYyjxEFrCBJdCNUS1LKNWet2ZQt3ByEUpAP"}

ServiceC:

{"name":"serviceC","tasks":[{"inputs":[{"type":"String","key":"message"}],"outputs":[{"type":"String","key":"message"}],"key":"taskZ"},{"inputs":[{"type":"String","key":"message"}],"outputs":[{"type":"String","key":"message"}],"key":"taskA"}],"configuration":{},"hash":"EvYgwFjAQpGs19EgoXi4EExJXoH7DL6Fmae4RStQZzt2","sid":"serviceC","source":"QmPuHX3LumnDkrxY3wUR8J2J9xmXGw8yTVy5jf7P24MprN"}

Once these services are created and started you can write the following workflow:

{
  "sid": "workflow",
  "name": "workflow",
  "source": "QmbtKRgiDxB8dChfdRA2Hk7MYtB1yB3dXrnh2msus7Ft8P",
  "workflows": [
    {
      "key": "event",
      "trigger": {
        "type": 1,
        "instanceHash": "88YtHw3iZtjpAeDDUWHsDFg9MLvgircPzCFHxFqJ2ex9",
        "key": "eventX"
      },
      "tasks": [
        {
          "instanceHash": "8qKUdaMPAn35ozeUWVcT9BQ5gHNJYbJJ5rTCWqfnJgpW",
          "taskKey": "taskY"
        },
        {
          "instanceHash": "7sTRCDpWCXYBSVgh7dKKV6pP69PHdYQY8kyBohumEWNu",
          "taskKey": "taskZ"
        }
      ]
    },
    {
      "key": "result",
      "trigger": {
        "type": 2,
        "instanceHash": "88YtHw3iZtjpAeDDUWHsDFg9MLvgircPzCFHxFqJ2ex9",
        "key": "taskX"
      },
      "tasks": [
        {
          "instanceHash": "8qKUdaMPAn35ozeUWVcT9BQ5gHNJYbJJ5rTCWqfnJgpW",
          "taskKey": "taskY"
        },
        {
          "instanceHash": "7sTRCDpWCXYBSVgh7dKKV6pP69PHdYQY8kyBohumEWNu",
          "taskKey": "taskZ"
        }
      ]
    },
    {
      "key": "result-from-other-workflow",
      "trigger": {
        "type": 2,
        "instanceHash": "8qKUdaMPAn35ozeUWVcT9BQ5gHNJYbJJ5rTCWqfnJgpW",
        "key": "taskY"
      },
      "tasks": [
        {
          "instanceHash": "7sTRCDpWCXYBSVgh7dKKV6pP69PHdYQY8kyBohumEWNu",
          "taskKey": "taskZ"
        }
      ]
    }
  ]
}

Where

  • 88YtHw3iZtjpAeDDUWHsDFg9MLvgircPzCFHxFqJ2ex9: Hash of instance of serviceA
  • 8qKUdaMPAn35ozeUWVcT9BQ5gHNJYbJJ5rTCWqfnJgpW: Hash of instance of serviceB
  • 7sTRCDpWCXYBSVgh7dKKV6pP69PHdYQY8kyBohumEWNu: Hash of instance of serviceC

Now if you execute taskX from serviceA all the tasks of the workflow will be triggered.

grpcurl -plaintext \
  -d "{\"instanceHash\":\"88YtHw3iZtjpAeDDUWHsDFg9MLvgircPzCFHxFqJ2ex9\", \"taskKey\":\"taskX\", \"inputs\":{\"message\":\"\"}}" \
  localhost:50052 api.Execution/Create

You can also try with events by calling the emits task from serviceA with no inputs

grpcurl -plaintext \
  -d "{\"instanceHash\":\"88YtHw3iZtjpAeDDUWHsDFg9MLvgircPzCFHxFqJ2ex9\", \"taskKey\":\"emits\", \"inputs\":{}}" \
  localhost:50052 api.Execution/Create

@antho1404 antho1404 added the enhancement New feature or request label Jul 31, 2019
@antho1404 antho1404 added this to the next milestone Jul 31, 2019
@antho1404 antho1404 self-assigned this Jul 31, 2019
@antho1404 antho1404 requested review from krhubert and NicolasMahe and removed request for krhubert August 1, 2019 12:15
@antho1404 antho1404 marked this pull request as ready for review August 1, 2019 12:16
@antho1404 antho1404 requested a review from krhubert August 1, 2019 12:16
sdk/execution/execution.go Outdated Show resolved Hide resolved
protobuf/types/service.proto Show resolved Hide resolved
execution/execution.go Show resolved Hide resolved
workflow/workflow.go Show resolved Hide resolved
workflow/workflow.go Outdated Show resolved Hide resolved
workflow/workflow.go Outdated Show resolved Hide resolved
@antho1404 antho1404 force-pushed the feature/multi-step-workflow branch from 5c411be to 3765b02 Compare August 2, 2019 03:39
@antho1404 antho1404 force-pushed the feature/multi-step-workflow branch from 5fab386 to 1aa2933 Compare August 3, 2019 12:38
Copy link
Member

@NicolasMahe NicolasMahe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow should be based on simple yet generic graph definition (nodes and edges).
The engine should check for the graph complexity (only directive and radius of 1).

panic("parent hash should be present if event is not")
}
if exec.ParentHash.Equal(exec.Hash) {
panic("parent hash cannot be equal to execution hash")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should return the error, no?

}

func (w *Workflow) triggerExecution(wf *service.Workflow, prev *execution.Execution, eventHash hash.Hash, data map[string]interface{}) error {
height, err := w.getHeight(wf, prev)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, the calculation of the height bring a few problems mainly when the workflow is circular (or multiple workflow are).
The height could be saved directly in the Execution.
Also, height is only valid for mono-branch workflow, fine for now but big limitation for the future.

@NicolasMahe NicolasMahe merged commit 8934dfb into dev Aug 8, 2019
@NicolasMahe NicolasMahe deleted the feature/multi-step-workflow branch August 8, 2019 09:16
@NicolasMahe NicolasMahe removed this from the next milestone Aug 16, 2019
@NicolasMahe NicolasMahe added this to the v0.13.0 milestone Aug 16, 2019
@NicolasMahe NicolasMahe added the release:add Pull requests that add something label Aug 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request release:add Pull requests that add something
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add the chain of task
3 participants