From 46db8a8409d2ff4f0000fcfa2919bd539feb75f4 Mon Sep 17 00:00:00 2001 From: Doug Sillars Date: Wed, 20 Apr 2022 13:37:02 -0400 Subject: [PATCH 1/2] james blog --- blog/2022-04-21-conductor-and-clojure.md | 134 +++++++++++++++++++++++ blog/authors.yml | 6 + static/img/blogassets/clojure.jpeg | Bin 0 -> 17048 bytes 3 files changed, 140 insertions(+) create mode 100644 blog/2022-04-21-conductor-and-clojure.md create mode 100644 static/img/blogassets/clojure.jpeg diff --git a/blog/2022-04-21-conductor-and-clojure.md b/blog/2022-04-21-conductor-and-clojure.md new file mode 100644 index 00000000..3d0b648f --- /dev/null +++ b/blog/2022-04-21-conductor-and-clojure.md @@ -0,0 +1,134 @@ +--- +slug: conductor-using-clojure +title: Enhancing Conductor With Clojure +authors: james +tags: [Netflix Conductor, Orkes, SDK, clojure, 2022] +image: https://orkes.io/content/img/blogassets/clojure.jpeg +--- + + +#Enhancing Conductor With Clojure + +## What is Conductor + +Conductor is a workflow orchestration engine that connects all of your microservices together to create fully functional workflows that can run at scale. Each workflow is comprised of tasks. Tasks can be System Tasks, these are provided by Conductor, or Custom Tasks which are called Workers. These workers can be written in any language - from Conductor's point of view - data goes in, and results come out - the language that processes the data is irrelevant. + +Workflows are defined in JSON and Tasks are defined in JSON. Workflows can be composed of other workflows. The way I see it everything is just data. + +Clojure is a functional programming language that runs on the JVM, with really interesting features, that match really well with the way I understand Conductor. Workflows and tasks are "just data" and Clojure programs are "just data" + +In the POST I want to show you how you can create tasks, workflows and run Clojure workers, with just data. + +## Getting started + +For this example you'll need a conductor instance, you can go ahead and clone `https://github.com/Netflix/conductor` cd into the docker folder and build with docker-compose + +```bash +cd docker +docker-compose build +docker-compose up +``` + +If that went well you should have a conductor instance running in port 8080. There is also a UI running on port 5000. http://localhost:5000 + +## NOT creating a project + +When I started writing this blog post, I thought I'll go through creating a project and adding the dependencies etc. Basically what you usually do in [insert language here]. But lets do something better, lets do _nothing_ + +![image](https://thumbs.gfycat.com/JadedAdeptDugong-size_restricted.gif) + +Assuming you have clojure-tools lets use Alex Miller plugin and do everything on the repl, for references on the plugin visit this link [https://insideclojure.org/2018/05/04/add-lib/] + +So lets start a repl with the following arguments. + +````clojure +clj -Sdeps "{:deps + {org.clojure/tools.deps.alpha + {:git/url \"https://github.com/clojure/tools.deps.alpha.git\" + :sha \"83a477b305839c697666401508c395cfed29506a\"}}}" +```` +That will download dependencies etc, once that is done just copy/paste `(use 'clojure.tools.deps.alpha.repl)` +After that we have the ability to require dependencies of our own. So lets first add the clojure sdk library by typing (or copy and pasting) this: + +`(add-libs {'io.orkes/conductor-clojure {:mvn/version "orkes-0.1.3"}})` + +## Creating tasks and workflows +In order to create tasks and workflows we'll need to use the `conductor.metadata` namespace. This namespace holds the functions for creating tasks and workflows in conductor. +`(require '[conductor.metadata :as metadata])` +After requiring the namespace lets define an options map for our options since we are using netflix-conductor we don't need authentication so we'll just specify the Url + +````clojure +(def options { + :url "http://localhost:8080/api/" + } ) +```` + +With that defined we can start creating tasks and workflows lets create our first task. + +````clojure +(metadata/register-tasks options [{:name "simplest_task" + :description "This task will be able to run Clj" + :owner-email "mail@gmail.com" + :retry-count 3 + :timeout-seconds 300 + :response-timeout-seconds 180}, + ]) +```` +If when evaluating the above nil was returned to the terminal, then we are on the right track and we've just created our first task in conductor. Lets create a workflow that uses the above task: + +````clojure +(metadata/register-workflow-def options {:name "simple_wf" + :description "created programmatically from clj" + :version 1 + :tasks [{:name "simplest_task" + :task-reference-name "repl_task_ref" + :input-parameters {"firstNumber" "${workflow.input.firstNumber}" + "secondNumber" "${workflow.input.secondNumber}"} + :type :simple}] + :input-parameters ["firstNumber" "secondNumber"] + :output-parameters {"result" "${repl_task_ref.output.result}"} + :schema-version 2 + :restartable true + :owner-email "mail@yahoo.com" + :timeout-seconds 0 + :timeout-policy :alert-only}) + +```` +Ok so we created a workflow that uses a task of type simple (which means its a task we'll have to write a worker for) that take two parameters. and returns a result. + +## Writing a worker and polling for tasks + +To be able to write a worker we need to bring in the client namespace: +`(require '[conductor.client :as conductor])` +The client namespace allows us to start a workflow and run workers, Lets create a worker and run a Runner instance to poll for work: + +````clojure +(def instance (conductor/runner-executor-for-workers + (list {:name "simplest_task" + :execute (fn [someData] + [:completed {"result" (+ (get someData "firstNumber") (get someData "secondNumber"))}])}) + options)) +```` +*Note:* we are using a `def` thats because the above function returns a TaskRunnerConfigurer instance which we can start/shutdown. After evaluating the above +our newly created worker will start polling for associated with the "simplest_task" we defined earlier. This is tru for every workflow that uses our simplest_task. + +## Starting the Workflow + +Lets start the workflow and provide the two input parameters: + +````clojure +(conductor/start-workflow options {:version 1 :input { + "firstNumber" 4 + "secondNumber" 5 +} :name "simple_wf"}) +```` + +If that went well that function will return a string with the execution id. if you head over to http://localhost:5000 under executions you should be able to see the result + +# Conclusion + +To conclude I want to point some things out + +1. Getting started with conductor is so easy that you don't even need to create a project. + +2. Conductor tasks are just Data, Conductor workflows are just Data, and Clojure is just Data. \ No newline at end of file diff --git a/blog/authors.yml b/blog/authors.yml index b9963b8f..19cda4f0 100644 --- a/blog/authors.yml +++ b/blog/authors.yml @@ -33,6 +33,12 @@ orkes: url: https://github.com/orkes-io image_url: /content/img/branding/orkes-logo-mark-purple-2x.png +james: + name: James Stuart + title: Software Engineer + url: https://www.linkedin.com/in/jstuartmilne/ + image_url: https://orkes.io/static/James%20Stuart-18cb5c06883620166675f2aba41feace.jpg + azeez: name: Azeez Lukman title: Guest Author diff --git a/static/img/blogassets/clojure.jpeg b/static/img/blogassets/clojure.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..aa507b0a408fca79eb64df1c58ea14d4c03b2e27 GIT binary patch literal 17048 zcmcJ$1$3M{uP8cUPQ%R1%*-(12{R`RGd9?UnVFfHo1~$JnYj&9!;F3D-ap-U&RX}~ zb>DHazL6zcmNl~EPh5GD{{WB_nfFbGtz-va=G_t}9% zfc=^1KMNSlyQr|>5WiOeuz%xkW&TO~|MW>F0syA~guk~9hm;8iLz4)LL#2>GB_Sn& zjYDN60Z0V>pYi)&21O-BLnWi407Lt0fd7T`-&Iga{*4urkqHl=g6w6XAX82PQbNYl zqyfN<;KDx}K@JQI6exo$%LCHT!6m5B(O}`ig9iFU(If^2`b2_0Q~aCBe}%v)P|(6f zStYA|+E!fDD8~C50oCpa=)2ATyDmqL2ua ze+N`p0x96A011?Efi!9I=x`!Q0JQMWGO}nv0RYqwB~+oB(YM*{8?O@b0srQTlI`o? z@A4Z!GIsL(_8pz%-xLX76Lq(#Z2))6fjQj2(U3}%vL_+{k0s`_xPM{6(DhYw0RZIB zPs;-V|H6{lba;Hqj4kR1fPK9ovi-LfV6!#p*LH~oCX7z`5PyuRj5&JO@r~V?{j(=H z90|Blv>)?kKly%lIZLnoO3`P?fzK4+a6vtA;bKN<0C^dS0u}1LVHdpLfYteB>bR}J zwVK0bSFSKNLCU%~n@T@b2>POWJ~(ynN`D%#n)22~qrbS5=@m;>G4hk=&ffiSb1&n* z!{W|yBehtYA7cTGF|2)-&(7v!H}r&VWqOY zZMVymBfB8yQ9?{9$A0YHf5n|#k-{Wxy0w|%`~_^Mvy(0$cT zdYA8-Vxh5r7}4X6HFkg}?Apl@1s%NNXZ8QQVgGi{mgYk>*SO&Hb+c^yHhW+H)06w{ zWX#TMI}tzeryqOoq7=8yEb6~-)3fr^i$`tuKI!T(3qs}FMZidUx*0$E`InxEUB5+5 z&Z@NODrH*?-mF=5J}+z%B$FHIniGybp*tK1FPTm#63a8)-&ILJomw~bF1aT&;qd9g2kZ_$&lGv(9?aqzVf@jo zp^z*043W>gH#7cJm;TlWhzqJkrL#4k>&>O7vm=>)$eY?6o;~eGY8(LI(eV_7t_HUw zjP@Ug@G_t2WLbMs_FB^SbLh|6_eRe7BVS(8r)Ni10rm6LgUyOc4 zRlM%>Wv75pGf(Ps(CfMHRzbe$^co#{?v2CA0rQXP6$WB~S8s03KN9ZKbdMhSJnrZo zDtyak6=YEJfm&O_bZ^;w6#+o#9vIa#de14kZcHdWuVxwIVc8p|`$;xhL78j4y>6bU z_v~ojnfx)DZ1p8V!uV_L!>VU?g+F}zuM3t}9oIFd-Zkkua8qBB*I>t(N^EeqL<0bj zPj+199!4{|J~eX^fX|GSe%SzS4qGX5c@Q{sYs__fgmeZ!()Z z*ZXU)p}KHp!_ZzAOzU+Gb+I(9iVd-Tb^H6$hZ66FYBpNxyq7du;-l7GbLvz*o0_Z!PXrypPp}vBLD!yDG{RZTwl|% zu_yWP?UU|JjjKDcxcrjT?C!4_5&!@in^MXBkM!?_?4!LaH+GIQ?dANvN^D|LrBI8n zu>R9K1x#I2*uz8ZuT~Hl1$kT^#Bv1PrTFKelr}~C7Yz&%$S(!}D16-<2>2Hg zWvHZ`1b`SB+VCgJ{iDFrAAiFE5Gu5{{09=8%<-h=11z}rC;Y1ah$3KcFONBf($z!H z6Kgm6_M>F~@`CToB#1>Ms6_tB_WhF#HsRlNvj3#~N2C8ei25FX|M#u_Ym5Jw&VMET z|AP6SAK||h)Bk+~g#W(9`LqA|j}6fK_6GtS4Cb%>4>-zy+w=b#33mTYQSWaq6r0+g zcosk|f7KA8KTPvlkOcgxpj%ugnxiL$zvVbP_WVJ>>M?Zb$i*Uv8b!xGNY)-%o^|ve zUV{(3FDZs5{#qxl4rzh22pdkd>b&+?{o27_zOfkhMgRcY!UiXff2QECP&`8GuM9(n zrL?wJx;Pw_?d>PW3P?VF_4GGMME1V`$UM!tRmW>Lm0!5aPWo~B&IAz+zLC~ECM=oV zYG=EtG2M1V4Tg4$n;wE;6SYN4%^q`F_={5KP)5yfwGpK6F7u#_9xe@PNg$>@j@}cP~qWutQ{-bEsh>bH|g<|&0rUe7#jI{_fd+3He zy`;+84gG`qlZ8c9Rn3XZYRW+{_gbztW3n3V2A@y%Wa{_MJTOU#y03|k&mMV!g{n&c zFiC`WR{$}{A7TF`6|URN?cll&fcotHuC?Ig3%8^G5o+!EKRN`2r$<4>B)-Rm_u^Ao z8M#xnrv3A;+W*vp_}$F#{$XbSF$M%A6gU|4UseY3KV)Tq$jPF=M~nzIP&_j{{HsE1 z@c`r9@)rn8a!l9gLFhpAOYyI|=JrxEX~LkL*;j+O#p569b}-4+?}QyPgzN8?jEgyT z?#18r)@Byg`ZjL7#6{kHwWL9dv(G|4eiwmxwFOmnFoNgT<}wcI@tOQm9j2}7^6bgr zIB)^V_9HI~YpD_?G<%^>hk`i#o|%3or`x~G?NmPlGamVzP3*k^p{SoKBIhjdcxOC1 z`j*nuJ%~-|?Lw>L>yw)m;RL388_zTJ19*D1Tg59kK+%=4<7+^UoBYDo;P%MUefvqK zMXK+}Mc3j~<10@;A>g?-^^dz&CUYiLHC8~i9!2@yd_tS|*zVb%2wm$ZknP6-?2U`A zMc-|DEt%I^L;#atjNaD~j}P^n6EoWFSRH`;eENOKv3Bww3&Xj8de;H~KspkJppzZ& z2ZTwc6Q6R~sQUx|kCi`fXhJ9eFi0>6FlcaSI7l$4_p!ji-c1J@0E3ExhE77t%7wv+ zNyZ`~YJ`PNPQk{ZtfB@|Rd)(xH;&7z`^P&R7$V>|;J`4Z)3fblC^nXu*mNi~+Nnl> zz->p*<{jX>e23qGxtJ{1ol?A=TD+Z7LY}4f|91dyNAEA>pO$kmoqyVM4*dpb<@nuH zgymR=*UUN{XPi1*c3as7W!JT&;Ww2wH(dPDXX>D=oM#Vt(<{Q#b6N zk`eNG<7;iJEwk*ZPnm=8=otSTrz)nYvBdGM5hPtjXw^u@24Vv-V<6x*AFO?0eArWJ zPgP!kwr1z8AnY${Qn9-SBK#CH34#xz%X&JQ5EPif&K*OjHGJBM)?OZ{3&mER{~Nk;B&`Sv5M^Qr?;?UMFH1GzYZq;~r}iHudVT@D^KV}-o! zu{=2|_Uw4W72NvW`kdy-UCy*(RJife*J6OXI`m{vg19{yF)L6pM5FFhT3eD{x=^uvfckBn^`g9hbu1hAn(`#cY&!YE$RN}Bcz#TI ztWbg?j4e9)8KUnr28zf9@YeS0rVT2e+9n6-?aDk+B1(D)78ZrAfIiydZuys|XCTkh z46aAIB`%{K6T1WyKYex-OmYfTzpMJ-pZkrYdz`SHKERsH5oH^-%A{fiKPWg18Q^9juNruOv_`*blVm7{OG9s`!Ift7G#b#@{V8^=i3WtA;K5qvSn=t8C71r51FD$XdwH zoYtNhB6RC$O66i#r2Vy)ejGJCs$~7F#ExDLN=^hEomZ*3@jPlwAwryyQ^k96q;_E$q$4_DN7)Wk=1HWky%ePMp4*ymsWPv)7|7qCzULF=P8F_ zipG>MD2t4jYqC#0t3Q!<+wD|iR$KeAC+N8^4NI(WswcvF2(PUMir4Kt(%W{V5#2UP z$$=fS@z;`ehL5HEZ@?y&FHN_s;hk4%vz@nHXlH@H$~r+iZMv2+99C~Xw;nYC8T(1A z*7=-9*G=3$8Z}&>x4EXjRO9-PnzodLnS^zb&cK-lWKztd-*Lt`eK%jxIC^TQ*2Y{i zNCi%w4rzKQrZUr!mBQy}PIt#P$MsQzZTH$GDcIyPS5~hV08e^zdYp*+n>B=q zLx&&?^e!BbD((u@x%8-7`l9TZH1q;ar7q6gWEOYLPRLg*bvYSs<(>)w53|K+ZVX`A^PF_s4ZCSelAXZW3*8= zna>YGOLAW2y4qC6;BCUyG(Rq5ZSW^oI$NzF9QDka6ZN1l>8C&PALNVp30l+%Kl96=__U^%k%+$ffqGtW?7>%{6EXXZ-BH3I^~F zz%0gMp;?Dh4mlFU+Vcxok#`*xZttG)Os zL%^d4-`v@RBTJCvC||!DA7C`5x6(F6o28Qpco10HeCJQQoNSmjjb(F=+xGKK7q4~2BlRiz+%T&Es_BN5CAZQp zY$+c{J|9QyaL1pYfUEge=!|z&+RWJs?xB|)ed1G6$a-8qhu(jl^pF={z17h-^tl?+ zYRKDdHUoyG56Yar#ur+YLlk?A6`VM-b5jYNx~W#6x`EfYMO27}JwGKz=?~iJxi^5| z3koXe9Gg7QX)U7Cm}pYiJ&2y_D5al@?`=Q#(j8eSF!4H$48cyQ#r8JV&2*$UVhYux z!Im>8Xvt{17{(cN6M#Gh=bDN-zs3(dj9Mv>IU5LmOR5p|V`WZ{c=tQbsc~;H?b#nL zF6=mBb~qylF0wUe+$g_$%hlA@l<7#(oUBT02@U;IK}SA`*%tSb9)8b#!20HZt*E|; z`Ddx%kxnZWOdhp8ZUjWLLViooEZ14f)nNr2mc&?C$Nye2ViFWVbY)t56qP4nk*KI> zsW2tgA3qKEGah`TBP1GG6jNKz%*`)@W>EhnT-`Yka@3b?M1R4$Y|T$LhxEnnglB+! z{kyZg)b~m>Of(e=HOB6*bUuMaY}?EmtyX&um?)B07pHTugMg|azuFmnXz>F@( zyPSfr%pxb(H21l0su+8O{x)@73uhuK(BOj>=EqfYlvT%13T_l)l9Gz5j5WZj7*`QR zd`Y!yCCa?C#v_tZ%H2k0>(!gJ4_*>S9R`z$bCyCL{Jrhn*V%I@cU_ut=Q&z8YZ-x6 zgUf70#77;C8X6#5mth-%Ak2AXlg~~yZlg9yi#xqIyk<>ys1RD?3w1+3ft0&%C!KJU z?8M(g3y|s6!mHXnhl($^F+dckiog(XO%0AAxJ?_O$PFD%QuO18y5=3y*g4Pd=**Hz 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 literal 0 HcmV?d00001 From 9d26dd796e2268a3ea8a712893fa6f4e04cc0bfb Mon Sep 17 00:00:00 2001 From: Doug Sillars Date: Wed, 20 Apr 2022 13:38:23 -0400 Subject: [PATCH 2/2] james blog --- blog/2022-04-21-conductor-and-clojure.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blog/2022-04-21-conductor-and-clojure.md b/blog/2022-04-21-conductor-and-clojure.md index 3d0b648f..bb04a25c 100644 --- a/blog/2022-04-21-conductor-and-clojure.md +++ b/blog/2022-04-21-conductor-and-clojure.md @@ -7,7 +7,7 @@ image: https://orkes.io/content/img/blogassets/clojure.jpeg --- -#Enhancing Conductor With Clojure +# Enhancing Conductor With Clojure ## What is Conductor @@ -18,7 +18,7 @@ Workflows are defined in JSON and Tasks are defined in JSON. Workflows can be co Clojure is a functional programming language that runs on the JVM, with really interesting features, that match really well with the way I understand Conductor. Workflows and tasks are "just data" and Clojure programs are "just data" In the POST I want to show you how you can create tasks, workflows and run Clojure workers, with just data. - + ## Getting started For this example you'll need a conductor instance, you can go ahead and clone `https://github.com/Netflix/conductor` cd into the docker folder and build with docker-compose