Skip to content

Latest commit

 

History

History
102 lines (79 loc) · 3.19 KB

File metadata and controls

102 lines (79 loc) · 3.19 KB
description Prevent infinite loops in Mechanic tasks — guard against re-triggers when a task modifies the same Shopify resource it subscribes to.

Preventing action loops

Action loops occur when a task writes to a Shopify resource, triggering an update webhook that re-triggers the same task. For example, a task subscribed to shopify/products/update that adds a tag to a product will cause Shopify to fire another shopify/products/update event, creating a loop. This can lead to excessive API calls, duplicated data, or rate-limiting issues.

This guide covers strategies to prevent action loops in your Mechanic tasks.

Manual Prevention

1. Conditional Checks

Example: Skip Tagging if Tag Already Exists

{% code overflow="wrap" lineNumbers="true" fullWidth="false" %}

{% if event.topic == "shopify/products/update" or event.preview %}
  {% assign existing_tags = product.tags | split: ", " %}
  
  {% unless existing_tags contains "NewTag" %}
    {% action "shopify" %}
      mutation {
        tagsAdd(
          id: {{ product.admin_graphql_api_id | json }},
          tags: ["NewTag"]
        ) {
          userErrors {
            field
            message
          }
        }
      }
    {% endaction %}
  {% else %}
    {% log "break loop" %}
  {% endunless %}
{% endif %}

{% endcode %}

2. Timestamp-based Approach

Example: Using Timestamps to Prevent Loops

{% code overflow="wrap" lineNumbers="true" fullWidth="false" %}

{% if event.topic == "shopify/products/update" or event.preview %}
  {% assign current_timestamp = "now" | date: "%s" %}
  {% assign time_difference = current_timestamp | minus: product.metafields.custom.last_updated.value %}
  
  {% if time_difference >= 500 %}
    {% action "shopify" %}
      mutation {
        productUpdate(
          input: {
            id: {{ product.admin_graphql_api_id | json }},
            metafields: [{
              id: {{ product.metafields.custom.last_updated.metafield.admin_graphql_api_id | json }},
              namespace: "custom",
              key: "last_updated",
              value: {{ current_timestamp | json }},
              type: "number_integer"
            }]
          }
        ) {
          userErrors {
            field
            message
          }
        }
      }
    {% endaction %}
    {% comment %}
      Do your update here
    {% endcomment %}
  {% else %}
    {% log "not so fast" %}
  {% endif %}
{% endif %}

{% endcode %}

Automated Prevention

Mechanic's Built-in Features

Mechanic has some built-in features to prevent action loops:

  1. For tasks responding to mechanic/actions/perform, Mechanic will detect identical results to their predecessors and mark the task run as failed.
  2. For tasks responding to Shopify update events like shopify/products/update, Mechanic will detect repeated, identical task runs and error all action runs generated by the flagged task run.

Related