Skip to content

Query APIs

Gurmit Teotia edited this page Jan 3, 2020 · 19 revisions

Query APIs let you query the workflow history events for useful information. Query API will be useful in determining the state of workflow and individual workflow item (activity, Lambda function...). Query APIs are loosely grouped in to two categories:

Note: This document does not cover all the available query APIs

  1. Workflow specific query APIs: Using these APIs you can query workflow specific events and these are available in Guflow.Decider.Workflow class. Here is the list of APIs:

    • AllSignalEvents: It will return all the signals, this workflow instance has received.
    • AllMarkerEvents: Returns all the marker recorded in to the history of the workflow.
    • AllCancellationRequestedEvents: Returns all the cancellation requests, made to the workflow.
    • HasActiveEvent: Return true if workflow history has any active/live event for any of its children. e.g. if an activity is just scheduled but not picked up and completed by a worker then it means this activity is active.
    • StartedEvent: Returns workflow started event. WorkflowStartedEvent has useful information like workflow input and various timeouts.
  2. Workflow children specific query APIs: Using these APIs you can query the status of workflow children like- activity, timer, Lambda function and child workflow.

    IWorkflowItem.IsActive: It is a generic APIs available for all child items. It returns true if the workflow item - activity, Lambda .... is still active in Amazon SWF.

    IWorkflowItem.AllEvents(): Returns all events for given workflow item.

    IWorkflowItem.LastEvent(): Returns the latest event for given workflow item.

Guflow, does the heavy lifting of parsing the scattered history events and combining them together for a given workflow item. Let us understand it through following example. Let us assume workflow history events has following event for an activity:

  EventId      Event
    101      ActivityCompleted
    ...
    94       ActivityStarted
    ...
    89       ActivityScheduled
    ...
    82       ActivityFailed
    ...
    79       ActivityStarted
    ...
    71       ActivityScheduled

In above example a activity has been to scheduled two times, first time it failed and second time it succeeded. For this activity "IWorkflowItem.AllEvents" method will return two events- ActivityCompletedEvent and ActivityFailedEvent. While IWorkflowItem.LatestEvent will return ActivityCompletedEvent. You can use these APIs and other query APIs in taking custom workflow actions:

[WorkflowDescription("1.0")]
public class TranscodeWorkflow : Workflow
{
   public TranscodeWorkflow()
   {
      ScheduleActivity<DownloadActivity>().OnFailure(RetryTwoTimes);
   }
   
   private WorkflowAction RetryTwoTimes(ActivityFailedEvent @event)
   {
      // You can write your custom logic here.
      if(Activity(@event).AllEvents().OfType<ActivityFailedEvent>().Count() <2 )
         return Reschedule(@event);
      
      return DefaultAction(@event)
   }
}

There are many extension methods available for activity, Lambda function, timer and child workflow to query status. Some of them are:

Result: Returns the result as dynamic object when activity, Lambda function or child workflow has successfully completed. Throws exception when item is not successfully completed.

Result<>: Returns the result as type T when workflow child- activity, Lambda function... is successfully completed otherwise throws exception.

Following example shows how you can use access activity result-

[WorkflowDescription("1.0")]
public class TranscodeWorkflow : Workflow
{
  public TranscodeWorkflow()
  {
     ScheduleActivity<DownloadActivity>();
     ScheduleActivity<TranscodeActivity>().AfterActivity<DownloadActivity>() 
          .WithInput(a=>a.ParentActivity().Result().DownloadedPath);
     ScheduleActivity<UploadActivity>().AfterActivity<TranscodeActivity>()
          .WithInput(a=>a.ParentActivity().Result().TranscodedPath);
     ScheduleActivity<SendConfirmation>().AfterActivity<UploadActivity();
  }
}
Clone this wiki locally