Skip to content

Commit b6fc6de

Browse files
Merge pull request #26 from indeedeng/pattern
Add design patterns
2 parents 54a2b5b + 455f746 commit b6fc6de

67 files changed

Lines changed: 4887 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,120 @@ We also have smaller [code snippets](https://github.com/indeedeng/iwf-java-code-
1212

1313
_Note that by default this project will listen on 8803 port
1414

15+
## Design Patterns
16+
Check out all the [design patterns](./src/main/java/io/iworkflow/patterns) that we use iwf to build applications.
17+
18+
### [Cron Schedule Workflow](./src/main/java/io/iworkflow/patterns/workflow/cron)
19+
A pattern for replacing traditional Orc jobs with workflow-based cron scheduling. This pattern demonstrates how to use scheduled workflows to execute tasks at specified intervals using CRON expressions. Key features include automatic initialization, configurable scheduling, and management through Temporal Cloud UI.
20+
21+
**Use Cases**: Periodic data processing, cleanup tasks, automated reports, scheduled maintenance
22+
**Endpoints**: N/A (automatically scheduled)
23+
24+
### [Drain Channels Patterns](./src/main/java/io/iworkflow/patterns/workflow/drainchannels)
25+
26+
#### [Drain Internal Channels](./src/main/java/io/iworkflow/patterns/workflow/drainchannels/internal)
27+
Demonstrates graceful shutdown of internal communication channels between workflow threads. One thread sends commands through internal channels while another continuously processes messages, ensuring no messages are lost during shutdown.
28+
29+
**Use Cases**: Consumer-producer patterns, message processing with graceful shutdown
30+
**Endpoints**: `GET /design-pattern/drainchannels/internal/start?workflowId={workflowId}`
31+
32+
#### [Drain Signal Channels](./src/main/java/io/iworkflow/patterns/workflow/drainchannels/signal)
33+
Shows how to process signals until channels are empty, then immediately complete the workflow to keep it short-lived. Uses atomic checking to determine if channels are empty before closing.
34+
35+
**Use Cases**: Processing queued refund requests, LLM evaluation with bandwidth limits
36+
**Endpoints**: `GET /drainchannels/signal/startorsignal?workflowId={workflowId}`
37+
38+
### [Interruptible Execution](./src/main/java/io/iworkflow/patterns/workflow/interruptible)
39+
Allows workflows to be gracefully interrupted and terminated based on external signals. This pattern enables dynamic control over long-running workflow execution with proper state management.
40+
41+
**Use Cases**: Dynamic task management, resource optimization, error handling and recovery
42+
**Endpoints**:
43+
- Start: `GET /design-pattern/interruptible/start?workflowId={workflowId}`
44+
- Cancel: `GET /design-pattern/interruptible/cancel?workflowId={workflowId}`
45+
46+
### [Manual Intervention](./src/main/java/io/iworkflow/patterns/workflow/intervention)
47+
Handles scenarios where API calls fail and require human intervention to retry or skip operations. Supports manual interaction through Temporal Cloud UI, built-in endpoints, or custom RPC endpoints.
48+
49+
**Use Cases**: API failure handling, manual decision points, external system integration issues
50+
**Endpoints**: `GET /design-pattern/intervention/start?workflowId={workflowId}`
51+
52+
### [Parallel States](./src/main/java/io/iworkflow/patterns/workflow/parallel)
53+
Demonstrates running multiple states concurrently with two variants: simple parallel execution and parallel execution with await completion. Supports both different states running in parallel and the same state running multiple times.
54+
55+
**Use Cases**: Independent concurrent operations, bulk processing, simultaneous notifications
56+
**Endpoints**:
57+
- Simple: `GET /parallel/start/simple?workflowId={workflowId}`
58+
- With Await: `GET /parallel/start/withAwait?workflowId={workflowId}`
59+
60+
### [Parent-Child Workflows](./src/main/java/io/iworkflow/patterns/workflow/parentchild)
61+
Shows how to start child workflows and wait for their completion using client API. This pattern supports many-to-many relationships between parent and child workflows, making it more flexible than signal-based approaches.
62+
63+
**Use Cases**: Fan-out execution patterns, hierarchical task processing
64+
**Endpoints**: Varies based on implementation
65+
66+
### [Polling Patterns](./src/main/java/io/iworkflow/patterns/workflow/polling)
67+
68+
#### Simple Polling
69+
Periodically checks external system readiness using timer commands with consistent intervals.
70+
71+
#### Backoff Polling
72+
Uses exponential backoff retry mechanism with state API retry policies for more efficient resource usage.
73+
74+
**Use Cases**: External system readiness checks, data ingestion, payment verification, resource availability monitoring
75+
**Endpoints**:
76+
- Simple: `GET /design-pattern/polling/start/simple?workflowId={workflowId}`
77+
- Backoff: `GET /design-pattern/polling/start/backoff?workflowId={workflowId}`
78+
79+
### [Failure Recovery](./src/main/java/io/iworkflow/patterns/workflow/recovery)
80+
Implements the Saga pattern for handling failures in multi-step transactions with compensation actions. Demonstrates both state API backoff retry and failure recovery mechanisms.
81+
82+
**Use Cases**: Payment processing, distributed transactions, multi-step operations requiring rollback
83+
**Endpoints**: `GET /recovery/start?workflowId={workflowId}&itemName={itemName}&quantity={quantity}`
84+
85+
### [Reminders](./src/main/java/io/iworkflow/patterns/workflow/reminders)
86+
Sends periodic reminders to users while handling opt-out requests and managing timeouts. Includes automatic reminder scheduling and user preference management.
87+
88+
**Use Cases**: User engagement, task completion reminders, automated follow-ups
89+
**Endpoints**:
90+
- Start: `GET /design-pattern/workflow-with-reminder/start`
91+
- Accept: `GET /design-pattern/workflow-with-reminder/accept?workflowId={workflowId}`
92+
- Opt-out: `GET /design-pattern/workflow-with-reminder/optout?workflowId={workflowId}`
93+
94+
### [Resettable Timer](./src/main/java/io/iworkflow/patterns/workflow/resettabletimer)
95+
Implements a timer that can be reset before firing, useful for scenarios requiring action after periods of inactivity with the ability to restart the countdown.
96+
97+
**Use Cases**: Inactivity notifications, data cleanup after abandonment, time-sensitive processes
98+
**Endpoints**:
99+
- Start: `GET /design-pattern/resettabletimer/start?workflowId={workflowId}`
100+
- Reset: `GET /design-pattern/resettabletimer/reset?workflowId={workflowId}`
101+
102+
### [Scalable Parallel Processing](./src/main/java/io/iworkflow/patterns/workflow/scalableparallel)
103+
Advanced parent-child pattern for high scalability with unlimited request acceptance, partitioned processing, and configurable parallelism control. Includes request buffering and queue management.
104+
105+
**Use Cases**: CSV file processing, large dataset analysis, high-volume task processing
106+
**Endpoints**: `GET /design-pattern/parallelism/start?workflowId={workflowId}&numOfChildWfs={number}`
107+
108+
### [Storage Pattern](./src/main/java/io/iworkflow/patterns/workflow/storage)
109+
Implements a singleton workflow acting as persistent storage service with RPC-based operations. Provides long-lived data persistence across workflow executions with a 4MB storage limit.
110+
111+
**Use Cases**: Small database replacement, persistent workflow state, demo/MVP data storage
112+
**Endpoints**:
113+
- Add: `POST /design-pattern/storage/add`
114+
- Get: `GET /design-pattern/storage/get`
115+
- Remove: `POST /design-pattern/storage/remove`
116+
117+
### [Timeout Handling](./src/main/java/io/iworkflow/patterns/workflow/timeout)
118+
Manages task execution within designated time frames with parallel timeout monitoring. Can forcibly terminate workflows that exceed time limits or handle timeouts gracefully.
119+
120+
**Use Cases**: Task duration control, preventing endless execution, time-bounded operations
121+
**Endpoints**: `GET /design-pattern/timeout/start?workflowId={workflowId}&successfulWorkflow={boolean}`
122+
123+
### [Wait for State Completion](./src/main/java/io/iworkflow/patterns/workflow/waitforstatecompletion)
124+
Notifies clients when operations complete while starting background processes. Simplifies architectures by replacing complex CDC patterns and polling mechanisms.
125+
126+
**Use Cases**: Database CDC replacement, frontend data rendering, background operation triggers
127+
**Endpoints**: `GET /design-pattern/waitforstatecompletion/start?workflowId={workflowId}`
128+
15129
## Product Use case samples
16130

17131
### [Money transfer workflow/SAGA Patten](src/main/java/io/iworkflow/workflow/money/transfer)
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package io.iworkflow.config;
2+
3+
import io.iworkflow.patterns.services.ServiceDependency;
4+
import io.iworkflow.patterns.workflow.cron.CronScheduleWorkflow;
5+
import io.iworkflow.patterns.workflow.drainchannels.internal.DrainInternalChannelsWorkflow;
6+
import io.iworkflow.patterns.workflow.drainchannels.signal.DrainSignalChannelsWorkflow;
7+
import io.iworkflow.patterns.workflow.interruptible.InterruptibleExecutionWorkflow;
8+
import io.iworkflow.patterns.workflow.intervention.ManualInterventionWorkflow;
9+
import io.iworkflow.patterns.workflow.parallel.ParallelStatesWithAwaitWorkflow;
10+
import io.iworkflow.patterns.workflow.parallel.SimpleParallelStatesWorkflow;
11+
import io.iworkflow.patterns.workflow.parentchild.ParentWorkflowV2;
12+
import io.iworkflow.patterns.workflow.polling.BackoffPollingWorkflow;
13+
import io.iworkflow.patterns.workflow.polling.SimplePollingWorkflow;
14+
import io.iworkflow.patterns.workflow.recovery.FailureRecoveryWorkflow;
15+
import io.iworkflow.patterns.workflow.resettabletimer.ResettableTimerWorkflow;
16+
import io.iworkflow.patterns.workflow.scalableparallel.ChildWorkflow;
17+
import io.iworkflow.patterns.workflow.scalableparallel.ParentWorkflow;
18+
import io.iworkflow.patterns.workflow.scalableparallel.RequestReceiverWorkflow;
19+
import io.iworkflow.patterns.workflow.storage.StorageWorkflow;
20+
import io.iworkflow.patterns.workflow.timeout.HandlingTimeoutWorkflow;
21+
import io.iworkflow.patterns.workflow.waitforstatecompletion.WaitForStateCompletionWorkflow;
22+
import io.iworkflow.core.Client;
23+
import io.iworkflow.core.ObjectWorkflow;
24+
import io.iworkflow.core.WorkflowOptions;
25+
import io.iworkflow.core.exceptions.WorkflowAlreadyStartedException;
26+
import org.springframework.context.annotation.Bean;
27+
import org.springframework.context.annotation.Configuration;
28+
29+
@Configuration
30+
class PatternWorkflowsConfig {
31+
private static final String CRON_SCHEDULE_WORKFLOW_ID = "cron-schedule-sample";
32+
33+
@Bean
34+
public ObjectWorkflow simplePollingWorkflow() {
35+
return new SimplePollingWorkflow();
36+
}
37+
38+
@Bean
39+
public ObjectWorkflow backoffPollingWorkflow(ServiceDependency service) {
40+
return new BackoffPollingWorkflow(service);
41+
}
42+
43+
@Bean
44+
public ObjectWorkflow resettableTimerWorkflow() {
45+
return new ResettableTimerWorkflow();
46+
}
47+
48+
@Bean
49+
public ObjectWorkflow interruptibleExecutionWorkflow() {
50+
return new InterruptibleExecutionWorkflow();
51+
}
52+
53+
@Bean
54+
public ObjectWorkflow manualInterventionWorkflow() {
55+
return new ManualInterventionWorkflow();
56+
}
57+
58+
@Bean
59+
public ObjectWorkflow storageWorkflow() {
60+
return new StorageWorkflow();
61+
}
62+
63+
@Bean
64+
public ObjectWorkflow cronScheduleWorkflow() {
65+
return new CronScheduleWorkflow();
66+
}
67+
68+
@Bean
69+
public ObjectWorkflow failureRecoveryWorkflow() {
70+
return new FailureRecoveryWorkflow();
71+
}
72+
73+
@Bean
74+
public SimpleParallelStatesWorkflow simpleParallelStatesWorkflow() {
75+
return new SimpleParallelStatesWorkflow();
76+
}
77+
78+
@Bean
79+
public ParallelStatesWithAwaitWorkflow parallelStatesWithAwaitWorkflow() {
80+
return new ParallelStatesWithAwaitWorkflow();
81+
}
82+
83+
@Bean
84+
public ObjectWorkflow requestReceiverWorkflow(final Client iwfClient) {
85+
return new RequestReceiverWorkflow(iwfClient);
86+
}
87+
88+
@Bean
89+
public ObjectWorkflow parentWorkflow(final Client iwfClient) {
90+
return new ParentWorkflow(iwfClient);
91+
}
92+
93+
@Bean
94+
public ObjectWorkflow childWorkflow(final Client iwfClient) {
95+
return new ChildWorkflow(iwfClient);
96+
}
97+
98+
@Bean
99+
public ObjectWorkflow parentWorkflowV2(final Client iwfClient) {
100+
return new ParentWorkflowV2(iwfClient);
101+
}
102+
103+
104+
@Bean
105+
public WaitForStateCompletionWorkflow waitForStateCompletionWorkflow() {
106+
return new WaitForStateCompletionWorkflow(new ServiceDependency(), new ServiceDependency());
107+
}
108+
109+
@Bean
110+
public DrainInternalChannelsWorkflow drainInternalChannelsWorkflow() {
111+
return new DrainInternalChannelsWorkflow(new ServiceDependency(), new ServiceDependency());
112+
}
113+
114+
@Bean
115+
public DrainSignalChannelsWorkflow drainSignalChannelsWorkflow() {
116+
return new DrainSignalChannelsWorkflow();
117+
}
118+
119+
@Bean
120+
public HandlingTimeoutWorkflow handlingTimeoutWorkflow() {
121+
return new HandlingTimeoutWorkflow();
122+
}
123+
}

0 commit comments

Comments
 (0)