<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: orkes</title>
    <description>The latest articles on Forem by orkes (@nvn07).</description>
    <link>https://forem.com/nvn07</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F766956%2Fa64ec272-2caf-4656-b999-146e8cfb6ea4.png</url>
      <title>Forem: orkes</title>
      <link>https://forem.com/nvn07</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nvn07"/>
    <language>en</language>
    <item>
      <title>Netflix Conductor : Handling retries and timeout</title>
      <dc:creator>orkes</dc:creator>
      <pubDate>Tue, 25 Jan 2022 18:39:54 +0000</pubDate>
      <link>https://forem.com/nvn07/netflix-conductor-handling-retries-and-timeout-1d3i</link>
      <guid>https://forem.com/nvn07/netflix-conductor-handling-retries-and-timeout-1d3i</guid>
      <description>&lt;h2&gt;
  
  
  What is Conductor
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Netflix/conductor"&gt;Conductor&lt;/a&gt; is a Microservices orchestration platform from Netflix, released under Apache 2.0 Open Source License.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design for failures
&lt;/h2&gt;

&lt;p&gt;Failures and service degradation are the fact of any system, this is especially true with large interconnected systems running in cloud.  Conductor is designed with principles that systems can and will go down, degrade in performance and any dependencies should be able to handle such failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tasks in Conductor
&lt;/h2&gt;

&lt;p&gt;Conductor workflows are orchestration of many activities known as &lt;code&gt;task&lt;/code&gt;.  Each task represents a (ideally) stateless worker that given a specific input does the work and produces output.  The tasks are typically running outside of Conductor server and there are many factors that could effect their availability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing for failures
&lt;/h2&gt;

&lt;p&gt;Conductor allows you to define your stateful applications that can handle failures and temporary degradation of services and without having to write code for that. &lt;/p&gt;

&lt;h3&gt;
  
  
  Configuring tasks to handle failures
&lt;/h3&gt;

&lt;p&gt;Each task in Conductor can be configured how it responds to availability events such as: 1) Failures 2) Timeouts and 3) Rate limits&lt;br&gt;
Here is a sample task defintion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "createdBy": "user",
  "name": "sample_task_name_1",
  "description": "This is a sample task for demo",
  "responseTimeoutSeconds": 10,
  "timeoutSeconds": 30,
  "timeoutPolicy": "TIME_OUT_WF",
  "retryCount": 3,
  "retryLogic": "FIXED",
  "retryDelaySeconds": 5,
  "rateLimitPerFrequency": 0,
  "rateLimitFrequencyInSeconds": 1
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;retry* parameters specify how to handle cases where the task execution fails and retries can be configured to be with fixed delay or exponential backoff.  Similarly timeout* parameters specify how time time to give for task to complete execution and if the task should be marked as 'Timed Out' if it runs longer than that.&lt;/p&gt;

&lt;h2&gt;
  
  
  More Details
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://orkes.io/content/docs/how-tos/task-configurations"&gt;https://orkes.io/content/docs/how-tos/task-configurations&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://github.com/Netflix/conductor/"&gt;https://github.com/Netflix/conductor/&lt;/a&gt;&lt;br&gt;
for the source code and updates.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>opensource</category>
    </item>
    <item>
      <title>TIL: You can use JQ in Conductor</title>
      <dc:creator>orkes</dc:creator>
      <pubDate>Thu, 09 Dec 2021 20:59:05 +0000</pubDate>
      <link>https://forem.com/nvn07/til-you-can-use-jq-in-conductor-52b2</link>
      <guid>https://forem.com/nvn07/til-you-can-use-jq-in-conductor-52b2</guid>
      <description>&lt;h2&gt;
  
  
  What is Conductor
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Netflix/conductor"&gt;Conductor&lt;/a&gt; is a Microservices orchestration platform from Netflix, released under Apache 2.0 Open Source License.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is jq
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;jq&lt;/code&gt; (&lt;a href="https://stedolan.github.io/jq/"&gt;https://stedolan.github.io/jq/&lt;/a&gt;) is like sed for JSON data - you can use it to slice and filter and map and transform structured data with the same ease that sed, awk, grep and friends let you play with text.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conductor + JQ
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Netflix/conductor"&gt;Conductor&lt;/a&gt; allows you to create tasks that can process JSON payloads in your workflows without writing custom code using jq.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Use cases
&lt;/h3&gt;

&lt;p&gt;JSON is a popular format of choice for data-interchange. It is widely used in web and server applications, document storage, API I/O etc. It’s also used within Conductor to define workflow and task definitions and passing data and state between tasks and workflows. This makes a tool like JQ a natural fit for processing task related data. Some common usages within Conductor includes, working with HTTP task, JOIN tasks or standalone tasks that try to transform data from the output of one task to the input of another.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;Here is an example of a &lt;em&gt;&lt;code&gt;JSON_JQ_TRANSFORM&lt;/code&gt;&lt;/em&gt; task. The &lt;code&gt;inputParameters&lt;/code&gt; attribute is expected to have a value object&lt;br&gt;
that has the following&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A list of key value pair objects denoted key1/value1, key2/value2 in the example below. Note the key1/value1 are&lt;br&gt;
arbitrary names used in this example.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A key with the name &lt;code&gt;queryExpression&lt;/code&gt;, whose value is a JQ expression. The expression will operate on the value of&lt;br&gt;
the &lt;code&gt;inputParameters&lt;/code&gt; attribute. In the example below, the &lt;code&gt;inputParameters&lt;/code&gt; has 2 inner objects named by attributes&lt;br&gt;
&lt;code&gt;key1&lt;/code&gt; and &lt;code&gt;key2&lt;/code&gt;, each of which has an object that is named &lt;code&gt;value1&lt;/code&gt; and &lt;code&gt;value2&lt;/code&gt;. They have an associated array of&lt;br&gt;
strings as values, &lt;code&gt;"a", "b"&lt;/code&gt; and &lt;code&gt;"c", "d"&lt;/code&gt;. The expression &lt;code&gt;key3: (.key1.value1 + .key2.value2)&lt;/code&gt; concat's the 2&lt;br&gt;
string arrays into a single array against an attribute named &lt;code&gt;key3&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jq_example_task"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"taskReferenceName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"my_jq_example_task"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JSON_JQ_TRANSFORM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"inputParameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"value1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"b"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"value2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"d"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"queryExpression"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{ key3: (.key1.value1 + .key2.value2) }"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The execution of this example task above will provide the following output. The &lt;code&gt;resultList&lt;/code&gt; attribute stores the full&lt;br&gt;
list of the &lt;code&gt;queryExpression&lt;/code&gt; result. The &lt;code&gt;result&lt;/code&gt; attribute stores the first element of the resultList. An&lt;br&gt;
optional &lt;code&gt;error&lt;/code&gt;&lt;br&gt;
attribute along with a string message will be returned if there was an error processing the query expression.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key3"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"d"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resultList"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"key3"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"d"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Input Configuration
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;name&lt;/td&gt;
&lt;td&gt;Task Name. A unique name that is descriptive of the task function&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;taskReferenceName&lt;/td&gt;
&lt;td&gt;Task Reference Name. A unique reference to this task. There can be multiple references of a task within the same workflow definition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;type&lt;/td&gt;
&lt;td&gt;Task Type. In this case, JSON_JQ_TRANSFORM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inputParameters&lt;/td&gt;
&lt;td&gt;The input parameters that will be supplied to this task. The parameters will be a JSON object of atleast 2 attributes, one of which will be called queryExpression. The others are user named attributes. These attributes will be accessible by the JQ query processor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inputParameters/user-defined-key(s)&lt;/td&gt;
&lt;td&gt;User defined key(s) along with values.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inputParameters/queryExpression&lt;/td&gt;
&lt;td&gt;A JQ query expression&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Output Configuration
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;result&lt;/td&gt;
&lt;td&gt;The first results returned by the JQ expression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;resultList&lt;/td&gt;
&lt;td&gt;A List of results returned by the JQ expression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;error&lt;/td&gt;
&lt;td&gt;An optional error message, indicating that the JQ query failed processing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Want to learn more about JQ?
&lt;/h2&gt;

&lt;p&gt;See tutorials at &lt;a href="https://stedolan.github.io/jq/tutorial/"&gt;https://stedolan.github.io/jq/tutorial/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://github.com/Netflix/conductor/"&gt;https://github.com/Netflix/conductor/&lt;/a&gt;&lt;br&gt;
for the source code and updates.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Go: Netflix Conductor Worker</title>
      <dc:creator>orkes</dc:creator>
      <pubDate>Sun, 05 Dec 2021 16:43:23 +0000</pubDate>
      <link>https://forem.com/nvn07/go-netflix-conductor-worker-4d8a</link>
      <guid>https://forem.com/nvn07/go-netflix-conductor-worker-4d8a</guid>
      <description>&lt;h2&gt;
  
  
  What is Conductor
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Netflix/conductor"&gt;Conductor&lt;/a&gt; is a Microservices orchestration platform from Netflix, released under Apache 2.0 Open Source License.&lt;/p&gt;

&lt;h2&gt;
  
  
  Download and start Conductor server in 5 minutes
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://orkes.io/content/docs/getting-started/install/running-locally"&gt;Quickstart&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Golang package
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go get github.com/netflix/conductor/client/go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implementing a Task a Worker
&lt;/h2&gt;

&lt;p&gt;task package provides the types used to implement the worker. Here is a reference worker implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package task

import (
    "fmt"
)

// Implementation for "task_1"
func Task_1_Execution_Function(t *task.Task) (taskResult *task.TaskResult, err error) {
    log.Println("Executing Task_1_Execution_Function for", t.TaskType)

    //Do some logic
    taskResult = task.NewTaskResult(t)

    output := map[string]interface{}{"task":"task_1", "key2":"value2", "key3":3, "key4":false}
    taskResult.OutputData = output
    taskResult.Status = "COMPLETED"
    err = nil

    return taskResult, err
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Worker Polling
&lt;/h2&gt;

&lt;p&gt;Here is an example that shows how to start polling for tasks after defining the tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "github.com/netflix/conductor/client/go"
    "github.com/netflix/conductor/client/go/task/sample"
)

func main() {
    c := conductor.NewConductorWorker("http://localhost:8080", 1, 10000)

    c.Start("task_1", "", sample.Task_1_Execution_Function, false)
    c.Start("task_2", "mydomain", sample.Task_2_Execution_Function, true)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  NewConductorWoker parameters
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;baseUrl: Server address.&lt;/li&gt;
&lt;li&gt;threadCount: No. of threads. Number of threads should be at-least same as the number of workers&lt;/li&gt;
&lt;li&gt;pollingInterval: Time in millisecond between subsequent polls&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;See &lt;br&gt;
&lt;a href="https://github.com/Netflix/conductor/tree/main/polyglot-clients/go"&gt;https://github.com/Netflix/conductor/tree/main/polyglot-clients/go&lt;/a&gt;&lt;br&gt;
for the source code and follow us on GitHub for updates.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>go</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Netflix Conductor Workers in Python</title>
      <dc:creator>orkes</dc:creator>
      <pubDate>Thu, 02 Dec 2021 23:47:17 +0000</pubDate>
      <link>https://forem.com/nvn07/netflix-conductor-workers-in-python-3a4a</link>
      <guid>https://forem.com/nvn07/netflix-conductor-workers-in-python-3a4a</guid>
      <description>&lt;h2&gt;
  
  
  What is Conductor
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Netflix/conductor"&gt;Conductor&lt;/a&gt; is a Microservices orchestration platform from Netflix, released under Apache 2.0 Open Source License.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install the python client
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;virtualenv conductorclient
source conductorclient/bin/activate
cd ../conductor/client/python
python setup.py install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implement a Task Worker
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Netflix/conductor/blob/main/polyglot-clients/python/conductor/ConductorWorker.py#L36"&gt;ConductorWorker&lt;/a&gt; class is used to implement task workers.&lt;br&gt;
The following script shows how to bring up two task workers named &lt;code&gt;book_flight&lt;/code&gt; and &lt;code&gt;book_car&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;__future__&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;print_function&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;conductor.ConductorWorker&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ConductorWorker&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;book_flight_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'COMPLETED'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'output'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'booking_ref'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2341111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'airline'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'delta'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="s"&gt;'logs'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'trying delta'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'skipping aa'&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;book_car_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'COMPLETED'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'output'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'booking_ref'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"84545fdfd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'agency'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'hertz'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="s"&gt;'logs'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'trying hertz'&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Starting Travel Booking workflows'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConductorWorker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'http://localhost:8080/api'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'book_flight'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;book_flight_task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'book_car'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;book_car_task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'__main__'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;ConductorWorker&lt;/code&gt; parameters
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;server_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;hosting&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;conductor&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;Ex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'http://localhost:8080/api'&lt;/span&gt;

&lt;span class="n"&gt;thread_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;threads&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;polling&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt;
    &lt;span class="n"&gt;executing&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;case&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;using&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;polling_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;seconds&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt; &lt;span class="n"&gt;thread&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;wait&lt;/span&gt;
    &lt;span class="n"&gt;between&lt;/span&gt; &lt;span class="n"&gt;polls&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;conductor&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;worker_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;optional&lt;/span&gt;
    &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;worker_id&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;going&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;execute&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt;
    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;For&lt;/span&gt; &lt;span class="n"&gt;further&lt;/span&gt; &lt;span class="n"&gt;details&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;refer&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;documentation&lt;/span&gt;
    &lt;span class="n"&gt;By&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;hostname&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;machine&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;start&lt;/code&gt; method parameters
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;taskType: str
    The name of the task that the worker is looking to execute

exec_function: function
    The function that the worker will execute. The function
    must return a dict with the `status`, `output` and `logs`
    keys present. If this is not present, an Exception will be
    raised

wait: bool
    Whether the worker will block execution of further code.
    Since the workers are being run in daemon threads, when the
    program completes execution, all the threads are destroyed.
    Setting wait to True prevents the program from ending.
    If multiple workers are being called from the same program,
    all but the last start call but have wait set to False.
    The last start call must always set wait to True. If a
    single worker is being called, set wait to True.

domain: str, optional
    The domain of the task under which the worker will run. For
    further details refer to the conductor server documentation
    By default, it is set to None
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See &lt;br&gt;
&lt;a href="https://github.com/Netflix/conductor/tree/main/polyglot-clients/python"&gt;https://github.com/Netflix/conductor/tree/main/polyglot-clients/python&lt;/a&gt;&lt;br&gt;
for the source code and follow us on GitHub for updates.&lt;/p&gt;

</description>
      <category>python</category>
      <category>microservices</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
