Workflows
Audience: Programmer
Overview
pyck combines Temporal workflow engine with our CRUD+ API to create complete, customized warehouse software solutions. This document explains the workflow architecture, integration points, and development patterns.
System Architecture
Key Components
pyck Core Services: Our CRUD+ microservices providing foundational warehouse functionality
Temporal Service: Durable execution service integrated within our core
Database: Persistent storage for both pyck services and Temporal
API Layer: GraphQL API from pyck services and gRPC API from Temporal
External Workflows: Custom workflow implementations that operate outside the core system
Frontend Applications: Mobile and web UIs that interact with the system
Workflow Architecture
┌─────────────────────────────────────────────┐
│ pyck Core │
│ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ │ │ │ │
│ │ Database │◄───┤ Core Services │ │
│ │ │ │ │ │
│ └─────────────┘ └────────┬────────┘ │
│ ▲ │
│ │ │
│ ┌─────────────┐ │ │
│ │ │ │ │
│ │ Temporal │────────────┘ │
│ │ │ │
│ └─────────────┘ │
│ │
└─────────────┬──────────────┬────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌────────────────┐
│ │ │ │
│ GraphQL API │ │ gRPC API │
│ │ │ (Temporal) │
└────────┬────────┘ └────────┬───────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ External Systems │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ │ │ │ │
│ │ Workflows │────────────────►│ Frontend Apps │ │
│ │ │ │ │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘Why Temporal?
Temporal provides critical capabilities for warehouse operations:
Crash-proof Execution: Workflows never lose state, even when systems fail
Fault Tolerance: Business logic continues despite network failures or API outages
Long-running Processes: Support for workflows that run for days, weeks, or months
Task Retries: Automatic retries with configurable policies for intermittent failures
Visibility: Complete history and real-time status of workflow executions
Workflow Development
Setup and Configuration
Project Structure: A typical warehouse workflow project includes directories for workflow definitions, activity implementations, data models, API clients, worker service entry point, and tests.
Dependencies: Workflow projects require dependencies for the Temporal SDK and pyck client libraries.
Workflow Registration
Workflows must be registered with both Temporal and the pyck API. This two-step registration process happens during application startup:
Temporal Registration: Workflows and activities are registered with the Temporal worker
pyck API Registration: Workflows are registered with the pyck GraphQL API to associate them with specific events
The registration process maps workflows to specific event types in the system. For example, a workflow named "TemporalWorkflowPicking_OrderCreate" would be triggered by the "OrderCreate" event.
Workflow ID Generation
Workflow IDs in pyck are generated deterministically to ensure consistency and prevent duplicate executions:
With pyck_data_id: When
pyck_data_idis present in the search attributes, it is used as the suffix for the workflow ID (e.g.,WorkflowName_<pyck_data_id>)Without pyck_data_id: When no
pyck_data_idis provided, a new UUID is generated as the suffix (e.g.,WorkflowName_<uuid>)
This deterministic ID generation ensures that:
Workflows tied to specific data entities can be uniquely identified
Duplicate workflows for the same data entity are prevented
Workflow state can be reliably tracked across the system
Workflow Definition
Workflows in Temporal are defined as functions that orchestrate a series of activities. A typical picking workflow would include steps like:
Fetching order details
Allocating inventory
Generating picking tasks
Updating mobile app UI for picker
Waiting for picking completion
Processing results and updating inventory
Frontend Control Points
Workflows control frontend behavior through a combination of:
Activity Properties: Each workflow activity can define UI properties that should be displayed
Signal Channels: Workflows wait for user input through signal channels
NextActivityName: Defining the next activity tells the frontend what screen to show
Event Triggering and Signal Routing
Workflows are triggered by events from the system through an advanced signal routing mechanism that differentiates between START and INTERMEDIATE signals:
START Signals: Create new workflow instances when triggered
INTERMEDIATE Signals: Forward signals to already running workflow instances
When an event occurs in the pyck system:
The system uses JetStream-based routing to determine which workflows should be triggered
START signals will create new workflow instances (or fail if a workflow with the same ID is already running)
INTERMEDIATE signals will be forwarded to matching running workflows
For example, when an order is created in the system, the "OrderCreate" event is fired, which then triggers the "TemporalWorkflowPicking_OrderCreate" workflow.
Important Breaking Change: As of the latest version, running workflows cannot be reassigned on re-trigger. Attempting to start a workflow that is already running will result in an error. This ensures workflow state consistency and prevents accidental duplicate executions.
User Input Communication Flow
The communication between Temporal workflows and the frontend when waiting for user input follows a specific stateful pattern:
1. Workflow State Management
Workflows maintain their state through a query mechanism that allows external systems to inspect their current state without affecting execution:
Query Handler: Each workflow exposes its current UI state through a query handler for "nextActivityProperties"
Activity Definition: The workflow defines what activity the user should perform next
Signal Channels: The workflow creates channels to receive signals from the frontend
Waiting for Input: The workflow pauses execution while waiting for user input
2. Frontend Interaction Cycle
The frontend interacts with workflows through a well-defined cycle:
Discover Workflows: Frontend finds workflows assigned to the current user via the
checkAssignedWorkflowsGraphQL mutationGet Current Activity: The system retrieves the current activity information from the workflow
Render UI Components: Frontend displays the appropriate UI based on the activity properties
Collect User Input: User interacts with the UI and provides the requested information
Submit Input and Get Next Step: When the user submits input, the frontend calls a single GraphQL mutation (
userDataInput) that:Sends the user input to the workflow
Waits for the workflow to process the input
Returns the next activity in the same response
This means the frontend doesn't need to separately poll for the next activity after submitting user input - it gets both acknowledgment of the submitted data and instructions for the next step in a single GraphQL mutation.
3. GraphQL Mutation Synchronization
When the userDataInput GraphQL mutation is called:
Signal Sending: The GraphQL resolver sends the user input to the workflow via a Temporal signal
Synchronous Waiting: The resolver then waits for the workflow to process the input
State Transition Detection: The resolver monitors the workflow state, waiting for it to change from the current activity to the next activity
Response with Next Step: Once the workflow updates its state, the GraphQL mutation returns with information about the next activity the frontend should display
4. Workflow Processing
Inside the workflow, when it receives user input:
Signal Reception: The workflow's signal channel receives the user input
State Update: The workflow updates its activity state to indicate the current activity is passed
Input Processing: The workflow processes the input, often calling an activity
Next Activity Definition: The workflow defines the next activity for the user
State Exposure: The updated state becomes available to the GraphQL resolver
This continuous cycle allows the workflow to drive the frontend state while maintaining the reliability guarantees provided by Temporal's durable execution model.
BPMN to Code Translation
We use BPMN for visual workflow design and translate it to Temporal code:
BPMN Process: Designed with logistics team for business requirements
Activities: BPMN tasks become Temporal activities
Gateways: BPMN gateways become workflow conditions
Events: BPMN events map to Temporal signals/triggers
The workflow directory structure typically follows this pattern:
Reference Implementation
For a practical example, see our reference implementation: https://github.com/pyck-ai/pyck-customer-template
Best Practices
Idempotency: Ensure all activities are idempotent for reliable retries
Deterministic Workflows: Keep workflows deterministic by moving non-deterministic code to activities
Error Handling: Use appropriate retry policies for different failure types
Testing: Write comprehensive tests for workflows and activities
Monitoring: Set up proper monitoring and alerting using Temporal metrics
Versioning: Use versioning for workflow changes to handle in-flight workflows
Last updated
Was this helpful?
