Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Workflow Problem with Retry Predicate

I am trying to learn Google Workflow retry mechanism. My actual requirement is to request a http.get and will get a text response and i have to check that text and if it doesn't satisfy my condition, it should retry after say 10 seconds.

So to try it out, I made below example and from the docs learnt, standard retry would not fit my requirement as its based on http return codes so, went for custom predicate and defined a sub-workflow. And learnt I cannot pass any arguments to this sub-workflow, tried to raise error as per one example. But, this doesn't show any error in the code window but fails during runtime

main:
  steps:
    - first_step:
        try:
            steps:
                - getCurrentDay:
                    call: http.get
                    args:
                        url: https://us-central1-workflowsample.cloudfunctions.net/datetime
                    result: currentDateTime
                - setFromCallResult:
                    assign:
                        - dayName: ${currentDateTime.body.dayOfTheWeek}
                - whatIsToday:
                    call: sys.log
                    args:
                        data: ${dayName + " is actually a day"}
                        severity: "INFO" # Optional
                - callRetry:
                    switch:
                        - condition: ${dayName == "Thursday"}
                          raise: ${dayName}                                    
        retry:
            predicate: ${my_own_predicate}
            max_retries: 5
            backoff:
                initial_delay: 2
                max_delay: 60
                multiplier: 1
    - last_step:
        return: "OK"

my_own_predicate:
  params: [dayName]
  steps:
    - checkRetryCond:
        switch:
            - condition: ${dayName == "Thursday"}
              return: False
    - otherwise:
        return: True

Below is the error:

RuntimeError: "Thursday"
in step "first_step", routine "main", line: 24
"Thursday"

Line number 24 is

            predicate: ${my_own_predicate}

At this point I cannot figure out what the issue is

like image 683
bobby.dreamer Avatar asked Oct 15 '25 03:10

bobby.dreamer


1 Answers

Summary

The issue with the code is the logic. It is stuck in an infinite loop when it has to retry until it reaches the max_retry. This is due to the logic that is in the retry that never changes, so the same result occurs in every retry. There needs to be a logic that will exit this, otherwise you will get the error output.


To break down the problem:

Let’s say that today is “Thursday” to see what happens:

getCurrentDay gets the date (i.e. "Thursday")

setFromCallResult creates a parameter dayName="Thursday"

whatIsToday logs the dayName parameter

callRetry checks if dayName != “Thursday”. Since that is false, it does not raise the error and goes to last_step and “Ok” is returned

Now let's say that today is "Friday"

getCurrentDay gets the date (i.e. "Friday")

setFromCallResult creates a parameter dayName="Friday"

whatIsToday logs the dayName parameter

callRetry checks if dayName == "Friday". Since that is false, it raises an error with the dayName parameter

Enters the retry which calls the my_own_predicate subworkflow

my_own_predicate starts with dayName parameter equal to “Friday”. Since the condition is also if dayName != “Thursday” it returns False, meaning not to retry and the raised error is then returned.

You need to handle the raised error or have it retry in a way that has a different result.

As in the example. an except block is needed to catch the raised error and return a proper response.

TL;DR The logic that is retried (custom predicate) needs to be changed or you will get the same result. Raised errors need to be handled with except block.

Example

main:
  steps:
    - first_step:
        try:
            steps:
                - getCurrentDay:
                    #ideally, this function should be dynamic and return a different response each time (which it will for the customer)
                    call: http.get
                    args:
                        #this function is purely for demo purposes
                        url: https://us-central1-workflowsample.cloudfunctions.net/datetime
                    result: currentDateTime
                - setFromCallResult:
                    assign:
                        - dayName: ${currentDateTime.body.dayOfTheWeek}
                - whatIsToday:
                    call: sys.log
                    args:
                        data: ${dayName + " is actually a day"}
                        severity: "INFO" # Optional
                - callRetry:
                    switch:
                        #does it match the text?
                        - condition: ${dayName != "Thursday"}
                        #it does not match, we need to retry
                          raise: ${dayName}                                   
        retry:
            predicate: ${my_own_predicate}
            max_retries: 5
            backoff:
                initial_delay: 2
                max_delay: 60
                multiplier: 1
        except:
            #retries did not get the desired result, fail gracefully
            return: "hit 5 retries and did not get Thursday" 
    - last_step:
        #it enters this step only when dayName == "Thursday"
        return: "It's Thursday"
my_own_predicate:
  params: [dayName]
  steps:
    - logRetry:
        call: sys.log
        args:
            data: ${dayName + " is not the desired value, check to see if we need to retry"}
            severity: "INFO" # Optional
    - checkRetryCond:
        switch:
            - condition: ${dayName == "Thursday"} #since the response is what we need, there is no need to retry
              return: False #stop retrying
    - otherwise:
        return: True # do retry       
like image 87
Rogelio Monter Avatar answered Oct 17 '25 16:10

Rogelio Monter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!