<?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>DEV Community: asimnazir</title>
    <description>The latest articles on DEV Community by asimnazir (@asimnazir).</description>
    <link>https://dev.to/asimnazir</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%2F317157%2Faee92bde-5739-4512-81fe-8952aa986f03.jpeg</url>
      <title>DEV Community: asimnazir</title>
      <link>https://dev.to/asimnazir</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/asimnazir"/>
    <language>en</language>
    <item>
      <title>Expose yourself to the world</title>
      <dc:creator>asimnazir</dc:creator>
      <pubDate>Sun, 09 Feb 2020 16:48:35 +0000</pubDate>
      <link>https://dev.to/asimnazir/expose-yourself-to-the-world-ieh</link>
      <guid>https://dev.to/asimnazir/expose-yourself-to-the-world-ieh</guid>
      <description>&lt;p&gt;Expose your local application without deployment with free custom domain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FwC9F3R2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3200/1%2AbZUNQx9YZz1Ei-9B_2L8lg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FwC9F3R2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3200/1%2AbZUNQx9YZz1Ei-9B_2L8lg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a free account : &lt;a href="https://packetriot.com/"&gt;https://packetriot.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6Y7fI2M8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AKElVYD2ogTwjFYQF8ul2VQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6Y7fI2M8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AKElVYD2ogTwjFYQF8ul2VQ.png" alt="Chose Free Tier"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For windows, download and unzip the the file : h&lt;a href="https://packetriot.com/docs#downloads"&gt;ttps://packetriot.com/docs#downloads&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Command line change directory to the unzipped location which contains “pktriot.exe”. Optionally the path can also be added to the system environment variable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run following commands to route http/https traffic to localhost&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;pktriot configure&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choose the path and then authenticate by visiting the generated URL and select the region&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run following command to get the host name&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;pktriot info&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Note down the host name, this host name will also be visible in &lt;a href="https://packetriot.com/tunnels"&gt;https://packetriot.com/tunnels&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Optionally can update the tunnel name with following command&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;pktriot edit --name '{your tunnel name}'&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Expose your localhost port 80 over https with following command&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;pktriot route http add --domain {your host name} --destination localhost --http 80 --secure --redirect&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run following command to start receiving traffic from outside&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;pktriot start&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can browse with &lt;a href="https://%7Byour"&gt;https://{your&lt;/a&gt; host name}/ . You can also monitor the traffic by login to &lt;a href="https://packetriot.com/"&gt;https://packetriot.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Free Domain
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Look for a domain on &lt;a href="https://www.freenom.com/"&gt;https://www.freenom.com/&lt;/a&gt; . “.tk”, “.ml”, “.ga”, “.cf” &amp;amp; “.gq” domains are free.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note: use “.tk” etc in lookup otherwise there is a bug that you might not be able to select the domain&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select required domain and signup&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Route traffic from custom domain
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Login to &lt;a href="https://packetriot.com/"&gt;https://packetriot.com/&lt;/a&gt; , under “Domains” click “Verify Domain” and add the custom domain name. It will generate the TXT Record&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go to &lt;a href="https://my.freenom.com/"&gt;https://my.freenom.com/&lt;/a&gt; (Services &amp;gt; My Domains &amp;gt; Manage Domains &amp;gt; Manage Freenom DNS)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add a record with Type “TXT” and the Target same as generated in above step&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add record for Type “CNAME” with any subdomain name and the Target same as &lt;a href="https://%7Byour"&gt;{your&lt;/a&gt; host name}.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note: It will take couple of minutes before the status of the domain will be changed to “verified”. You can track the status under: &lt;a href="https://packetriot.com/domains"&gt;https://packetriot.com/domains&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Run following command to route traffic from custom domain to localhost&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;pktriot route http add --domain {your subdomain e-g: example.domain.com} --destination localhost --http 80 --secure --letsencrypt --redirect&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run following command to start receiving traffic locally from your custom domain&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;pktriot start&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>localtunnel</category>
      <category>ngrok</category>
      <category>serveo</category>
      <category>freedomain</category>
    </item>
    <item>
      <title>Azure Durable Functions</title>
      <dc:creator>asimnazir</dc:creator>
      <pubDate>Sun, 09 Feb 2020 16:41:27 +0000</pubDate>
      <link>https://dev.to/asimnazir/azure-durable-functions-3jaf</link>
      <guid>https://dev.to/asimnazir/azure-durable-functions-3jaf</guid>
      <description>&lt;p&gt;Azure durable functions help to define stateful workflow in code for stateless functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OGei3XJ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3840/1%2AMiVnU9RTe47fZWUdoQaOmg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OGei3XJ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3840/1%2AMiVnU9RTe47fZWUdoQaOmg.png" alt="" width="880" height="183"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Durable Functions in a nutshell:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;An extension to Azure Functions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stateful functions in a serverless environment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define workflows in code&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Benefits of Durable Functions
&lt;/h3&gt;

&lt;p&gt;Some of the key benefits of Durable Functions are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Parallel execution of functions (Fan-out &amp;gt; Fan-in)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Central Error handling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easy to understand the dependencies among functions via “Orchestrator Function”&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0_HODuLn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ANWzhr3JBCCnZWOhNIfCfdA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0_HODuLn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ANWzhr3JBCCnZWOhNIfCfdA.png" alt="Durable Function overview" width="407" height="292"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Starter Function&lt;/strong&gt;: Simple Azure Function that starts the Orchestration by calling the Orchestrator function. It uses an OrchestrationClient binding.&lt;/p&gt;

&lt;p&gt;OrchestrationClient is responsible for starting/stopping orchestrators and monitoring their status.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Orchestrator Function&lt;/strong&gt;: Defines a stateful workflow in code and invokes the activity functions. Sleeps during activity invocation and replays when wakes up. Which also provides separation of concerns for defining the workflow and performing actual activity.&lt;/p&gt;

&lt;p&gt;The code in an orchestrator function MUST be deterministic because during the flow the code will be executed again and again till all activity functions finish. You declare a function as an orchestrator by using a OrchestrationTrigger&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Orchestration Function limitations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Be Deterministic: No NewGuid(), Random, DateTime.Now, Http calls etc..&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be non-blocking: No I/O operations (e-g: table storage logic etc..) , no Thread.sleep etc..&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Never initiate any async operations without using its context&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Activity Functions&lt;/strong&gt;: Simple Azure Functions that performs a single step in a workflow and can receive or return data. An Activity function uses an ActivityTrigger so that can be invoked by the orchestrator&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Sub Orchestration:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Durable Functions also supports Sub Orchestration. This feature enables us to create sub orchestrators which orchestrate several activities. An orchestrator function can call another orchestrator function using the CallSubOrchestratorAsync or the CallSubOrchestratorWithRetryAsync methods.&lt;/p&gt;

&lt;p&gt;It could be handy for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Complex orchestration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In cases where retry mechanism is needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In cases where delay is needed in the activity function. Delay in activity function will be considered as part of function execution time, thus its billed where as timmer delay in orchestrator will not be billed as the orchestrator will go to sleep till timer is triggered.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tSP8H_zV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A-vHtO4l6a9R43ZKziD6gew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tSP8H_zV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A-vHtO4l6a9R43ZKziD6gew.png" alt="Sub Orchestrator" width="622" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Patterns
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N2AcnLni--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A2rt6peaAIzWgWagrSN9Lyw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N2AcnLni--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A2rt6peaAIzWgWagrSN9Lyw.png" alt="" width="880" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Durable Functions internal mechanism
&lt;/h2&gt;

&lt;p&gt;Durable functions make use of &lt;strong&gt;storage queues. **Message in the queue triggers the next function. State of orchestrations is saved in the **storage table&lt;/strong&gt;, it make use of event sourcing to play the current events and to trigger the next event.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M9yIrbsi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AWFEhFrf3UQcfa0Q5EI6N9A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M9yIrbsi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AWFEhFrf3UQcfa0Q5EI6N9A.png" alt="Durable Functions Storage Queues &amp;amp; Tables" width="278" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Event source events:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;During work flow execution, events are stored for following activities&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Orchestrator Started&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Activity 1 Scheduled&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Orchestrator Goes to Sleep (No explicit event is registered for it)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Orchestrator Started (Wakes up) &amp;gt; Activity 1 Completed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Activity 2 Scheduled ……&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Orchestrator Completed&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Storage tables:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DurableFunctionsHubInstances&lt;/strong&gt;: Contains records for each orchestrator instance with its input , final output and the RuntimeStatus&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**DurableFunctionsHubHistory: **Contains event source events for each orchestrator instance.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XqclZsc_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2400/0%2ATh38ZRsf3WPuPVEN.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XqclZsc_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2400/0%2ATh38ZRsf3WPuPVEN.png" alt="Durable Functions internal mechanism" width="880" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;**Note&lt;/em&gt;&lt;em&gt;: The tables &amp;amp; queues names mentioned above are default names for durable function; if storage is shared among different Function apps then it is advisable to specify custom hub name in host.json.&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Function Version 2.0 host.json:

"extensions": {

     "durableTask": {

           "hubName": "PeppolSupportedDocumentUpdaterHub"

      }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Monitoring progress
&lt;/h2&gt;

&lt;p&gt;Starter / OrchestrationClient with HttpTrigger can return a response with “CreateCheckStatusResponse” which contains the “statusQueryGetUri” that can be used to monitor the progress of the work flow.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;statusQueryGetUri:

http://{BaseUri}/runtime/webhooks/durabletask/instances/{InstanceId}?taskHub=DurableFunctionsHub&amp;amp;connection=Storage&amp;amp;code={FunctionKey}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If there are sub tasks involved then the progress / output of sub tasks can be monitored by adding following additional query parameters to “statusQueryGetUri”:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;amp;showHistoryOutput=true&amp;amp;showHistory=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Delay &amp;amp; Retry Mechanism
&lt;/h2&gt;

&lt;p&gt;context.CreateTimer, can be used to add delay between individual task execution in the chain.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var activityTask = context.CallActivityAsync&amp;lt;ActivityLog&amp;gt;(nameof(FunctionName), inputValueToFunction);

//add 3-sec delay between execution of tasks
var timeToStart = await context.CurrentUtcDateTime.AddSeconds(3);

var delayedActivityTask =  context.CreateTimer(timeToStart, CancellationToken.None).ContinueWith(t =&amp;gt; activityTask);

tasks.Add(delayedActivityTask);

await Task.WhenAll(tasks);

var result = tasks.Select(task =&amp;gt; task.Result).ToList();

return result;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Activity function can be retried in Orchestrator , and can also specify the delay between each retry. Optionally can also specify the exception for which to retry the activity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j9eVVtNr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AFErWVsjPnD40JyoVrmOqoQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j9eVVtNr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AFErWVsjPnD40JyoVrmOqoQ.png" alt="Retry Activity Function for “InvalidOperationException”" width="736" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Resources:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview?tabs=csharp#application-patterns"&gt;&lt;strong&gt;Durable Functions Overview - Azure&lt;/strong&gt;&lt;br&gt;
*Introduction to the Durable Functions extension for Azure Functions.*docs.microsoft.com&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.serverless360.com/blog/azure-durable-functions-patterns-best-practices"&gt;&lt;strong&gt;Azure Best Practices for Durable Functions Patterns | Serverless360&lt;/strong&gt;&lt;br&gt;
*In a previous post on Serverless360 blog, we introduced Durable Functions and later discussed when to choose Durable…*www.serverless360.com&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-sub-orchestrations?tabs=csharp"&gt;&lt;strong&gt;Sub-orchestrations for Durable Functions - Azure&lt;/strong&gt;&lt;br&gt;
*In addition to calling activity functions, orchestrator functions can call other orchestrator functions. For example…*docs.microsoft.com&lt;/a&gt;&lt;/p&gt;



</description>
      <category>azuredurablefunction</category>
      <category>serverless</category>
      <category>azurefunctions</category>
      <category>statefulworkflow</category>
    </item>
  </channel>
</rss>
