edda-framework 0.7.0__py3-none-any.whl → 0.9.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
edda/storage/models.py CHANGED
@@ -31,6 +31,7 @@ CREATE TABLE IF NOT EXISTS workflow_instances (
31
31
  owner_service TEXT NOT NULL,
32
32
  status TEXT NOT NULL DEFAULT 'running',
33
33
  current_activity_id TEXT,
34
+ continued_from TEXT,
34
35
  started_at TEXT NOT NULL DEFAULT (datetime('now')),
35
36
  updated_at TEXT NOT NULL DEFAULT (datetime('now')),
36
37
  input_data TEXT NOT NULL,
@@ -39,8 +40,9 @@ CREATE TABLE IF NOT EXISTS workflow_instances (
39
40
  locked_at TEXT,
40
41
  lock_timeout_seconds INTEGER,
41
42
  CONSTRAINT valid_status CHECK (
42
- status IN ('running', 'completed', 'failed', 'waiting_for_event', 'waiting_for_timer', 'compensating', 'cancelled')
43
+ status IN ('running', 'completed', 'failed', 'waiting_for_event', 'waiting_for_timer', 'waiting_for_message', 'compensating', 'cancelled', 'recurred')
43
44
  ),
45
+ FOREIGN KEY (continued_from) REFERENCES workflow_instances(instance_id),
44
46
  FOREIGN KEY (workflow_name, source_hash) REFERENCES workflow_definitions(workflow_name, source_hash)
45
47
  );
46
48
  """
@@ -53,6 +55,7 @@ WORKFLOW_INSTANCES_INDEXES = [
53
55
  "CREATE INDEX IF NOT EXISTS idx_instances_locked ON workflow_instances(locked_by, locked_at);",
54
56
  "CREATE INDEX IF NOT EXISTS idx_instances_updated ON workflow_instances(updated_at);",
55
57
  "CREATE INDEX IF NOT EXISTS idx_instances_hash ON workflow_instances(source_hash);",
58
+ "CREATE INDEX IF NOT EXISTS idx_instances_continued_from ON workflow_instances(continued_from);",
56
59
  ]
57
60
 
58
61
  # SQL schema for workflow execution history (for deterministic replay)
@@ -75,6 +78,26 @@ WORKFLOW_HISTORY_INDEXES = [
75
78
  "CREATE INDEX IF NOT EXISTS idx_history_created ON workflow_history(created_at);",
76
79
  ]
77
80
 
81
+ # SQL schema for archived workflow history (for recur pattern)
82
+ WORKFLOW_HISTORY_ARCHIVE_TABLE = """
83
+ CREATE TABLE IF NOT EXISTS workflow_history_archive (
84
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
85
+ instance_id TEXT NOT NULL,
86
+ activity_id TEXT NOT NULL,
87
+ event_type TEXT NOT NULL,
88
+ event_data TEXT NOT NULL,
89
+ created_at TEXT NOT NULL,
90
+ archived_at TEXT NOT NULL DEFAULT (datetime('now')),
91
+ FOREIGN KEY (instance_id) REFERENCES workflow_instances(instance_id) ON DELETE CASCADE
92
+ );
93
+ """
94
+
95
+ # Indexes for workflow history archive
96
+ WORKFLOW_HISTORY_ARCHIVE_INDEXES = [
97
+ "CREATE INDEX IF NOT EXISTS idx_history_archive_instance ON workflow_history_archive(instance_id);",
98
+ "CREATE INDEX IF NOT EXISTS idx_history_archive_archived ON workflow_history_archive(archived_at);",
99
+ ]
100
+
78
101
  # SQL schema for compensation transactions (LIFO stack for Saga pattern)
79
102
  WORKFLOW_COMPENSATIONS_TABLE = """
80
103
  CREATE TABLE IF NOT EXISTS workflow_compensations (
@@ -93,27 +116,6 @@ WORKFLOW_COMPENSATIONS_INDEXES = [
93
116
  "CREATE INDEX IF NOT EXISTS idx_compensations_instance ON workflow_compensations(instance_id, created_at DESC);",
94
117
  ]
95
118
 
96
- # SQL schema for event subscriptions (for wait_event)
97
- WORKFLOW_EVENT_SUBSCRIPTIONS_TABLE = """
98
- CREATE TABLE IF NOT EXISTS workflow_event_subscriptions (
99
- id INTEGER PRIMARY KEY AUTOINCREMENT,
100
- instance_id TEXT NOT NULL,
101
- event_type TEXT NOT NULL,
102
- activity_id TEXT,
103
- timeout_at TEXT,
104
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
105
- FOREIGN KEY (instance_id) REFERENCES workflow_instances(instance_id) ON DELETE CASCADE,
106
- CONSTRAINT unique_instance_event UNIQUE (instance_id, event_type)
107
- );
108
- """
109
-
110
- # Indexes for event subscriptions
111
- WORKFLOW_EVENT_SUBSCRIPTIONS_INDEXES = [
112
- "CREATE INDEX IF NOT EXISTS idx_subscriptions_event ON workflow_event_subscriptions(event_type);",
113
- "CREATE INDEX IF NOT EXISTS idx_subscriptions_timeout ON workflow_event_subscriptions(timeout_at);",
114
- "CREATE INDEX IF NOT EXISTS idx_subscriptions_instance ON workflow_event_subscriptions(instance_id);",
115
- ]
116
-
117
119
  # SQL schema for timer subscriptions (for wait_timer)
118
120
  WORKFLOW_TIMER_SUBSCRIPTIONS_TABLE = """
119
121
  CREATE TABLE IF NOT EXISTS workflow_timer_subscriptions (
@@ -134,6 +136,110 @@ WORKFLOW_TIMER_SUBSCRIPTIONS_INDEXES = [
134
136
  "CREATE INDEX IF NOT EXISTS idx_timer_subscriptions_instance ON workflow_timer_subscriptions(instance_id);",
135
137
  ]
136
138
 
139
+ # SQL schema for group memberships (Erlang pg style)
140
+ WORKFLOW_GROUP_MEMBERSHIPS_TABLE = """
141
+ CREATE TABLE IF NOT EXISTS workflow_group_memberships (
142
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
143
+ instance_id TEXT NOT NULL,
144
+ group_name TEXT NOT NULL,
145
+ joined_at TEXT NOT NULL DEFAULT (datetime('now')),
146
+ FOREIGN KEY (instance_id) REFERENCES workflow_instances(instance_id) ON DELETE CASCADE,
147
+ CONSTRAINT unique_instance_group UNIQUE (instance_id, group_name)
148
+ );
149
+ """
150
+
151
+ # Indexes for group memberships
152
+ WORKFLOW_GROUP_MEMBERSHIPS_INDEXES = [
153
+ "CREATE INDEX IF NOT EXISTS idx_group_memberships_group ON workflow_group_memberships(group_name);",
154
+ "CREATE INDEX IF NOT EXISTS idx_group_memberships_instance ON workflow_group_memberships(instance_id);",
155
+ ]
156
+
157
+ # =============================================================================
158
+ # Channel-based Message Queue System
159
+ # =============================================================================
160
+
161
+ # SQL schema for channel messages (persistent message queue)
162
+ CHANNEL_MESSAGES_TABLE = """
163
+ CREATE TABLE IF NOT EXISTS channel_messages (
164
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
165
+ channel TEXT NOT NULL,
166
+ message_id TEXT NOT NULL UNIQUE,
167
+ data_type TEXT NOT NULL,
168
+ data TEXT,
169
+ data_binary BLOB,
170
+ metadata TEXT,
171
+ published_at TEXT NOT NULL DEFAULT (datetime('now')),
172
+ CONSTRAINT valid_data_type CHECK (data_type IN ('json', 'binary')),
173
+ CONSTRAINT data_type_consistency CHECK (
174
+ (data_type = 'json' AND data IS NOT NULL AND data_binary IS NULL) OR
175
+ (data_type = 'binary' AND data IS NULL AND data_binary IS NOT NULL)
176
+ )
177
+ );
178
+ """
179
+
180
+ # Indexes for channel messages
181
+ CHANNEL_MESSAGES_INDEXES = [
182
+ "CREATE INDEX IF NOT EXISTS idx_channel_messages_channel ON channel_messages(channel, published_at);",
183
+ "CREATE INDEX IF NOT EXISTS idx_channel_messages_id ON channel_messages(id);",
184
+ ]
185
+
186
+ # SQL schema for channel subscriptions
187
+ CHANNEL_SUBSCRIPTIONS_TABLE = """
188
+ CREATE TABLE IF NOT EXISTS channel_subscriptions (
189
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
190
+ instance_id TEXT NOT NULL,
191
+ channel TEXT NOT NULL,
192
+ mode TEXT NOT NULL,
193
+ activity_id TEXT,
194
+ cursor_message_id INTEGER,
195
+ subscribed_at TEXT NOT NULL DEFAULT (datetime('now')),
196
+ FOREIGN KEY (instance_id) REFERENCES workflow_instances(instance_id) ON DELETE CASCADE,
197
+ CONSTRAINT valid_mode CHECK (mode IN ('broadcast', 'competing')),
198
+ CONSTRAINT unique_instance_channel UNIQUE (instance_id, channel)
199
+ );
200
+ """
201
+
202
+ # Indexes for channel subscriptions
203
+ CHANNEL_SUBSCRIPTIONS_INDEXES = [
204
+ "CREATE INDEX IF NOT EXISTS idx_channel_subscriptions_channel ON channel_subscriptions(channel);",
205
+ "CREATE INDEX IF NOT EXISTS idx_channel_subscriptions_instance ON channel_subscriptions(instance_id);",
206
+ "CREATE INDEX IF NOT EXISTS idx_channel_subscriptions_waiting ON channel_subscriptions(channel, activity_id);",
207
+ ]
208
+
209
+ # SQL schema for channel delivery cursors (broadcast mode: track who read what)
210
+ CHANNEL_DELIVERY_CURSORS_TABLE = """
211
+ CREATE TABLE IF NOT EXISTS channel_delivery_cursors (
212
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
213
+ channel TEXT NOT NULL,
214
+ instance_id TEXT NOT NULL,
215
+ last_delivered_id INTEGER NOT NULL,
216
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
217
+ FOREIGN KEY (instance_id) REFERENCES workflow_instances(instance_id) ON DELETE CASCADE,
218
+ CONSTRAINT unique_channel_instance UNIQUE (channel, instance_id)
219
+ );
220
+ """
221
+
222
+ # Indexes for channel delivery cursors
223
+ CHANNEL_DELIVERY_CURSORS_INDEXES = [
224
+ "CREATE INDEX IF NOT EXISTS idx_channel_delivery_cursors_channel ON channel_delivery_cursors(channel);",
225
+ ]
226
+
227
+ # SQL schema for channel message claims (competing mode: who is processing what)
228
+ CHANNEL_MESSAGE_CLAIMS_TABLE = """
229
+ CREATE TABLE IF NOT EXISTS channel_message_claims (
230
+ message_id TEXT PRIMARY KEY,
231
+ instance_id TEXT NOT NULL,
232
+ claimed_at TEXT NOT NULL DEFAULT (datetime('now')),
233
+ FOREIGN KEY (message_id) REFERENCES channel_messages(message_id) ON DELETE CASCADE,
234
+ FOREIGN KEY (instance_id) REFERENCES workflow_instances(instance_id) ON DELETE CASCADE
235
+ );
236
+ """
237
+
238
+ # Indexes for channel message claims
239
+ CHANNEL_MESSAGE_CLAIMS_INDEXES = [
240
+ "CREATE INDEX IF NOT EXISTS idx_channel_message_claims_instance ON channel_message_claims(instance_id);",
241
+ ]
242
+
137
243
  # SQL schema for transactional outbox pattern
138
244
  OUTBOX_EVENTS_TABLE = """
139
245
  CREATE TABLE IF NOT EXISTS outbox_events (
@@ -176,10 +282,16 @@ ALL_TABLES = [
176
282
  WORKFLOW_DEFINITIONS_TABLE,
177
283
  WORKFLOW_INSTANCES_TABLE,
178
284
  WORKFLOW_HISTORY_TABLE,
285
+ WORKFLOW_HISTORY_ARCHIVE_TABLE,
179
286
  WORKFLOW_COMPENSATIONS_TABLE,
180
- WORKFLOW_EVENT_SUBSCRIPTIONS_TABLE,
181
287
  WORKFLOW_TIMER_SUBSCRIPTIONS_TABLE,
288
+ WORKFLOW_GROUP_MEMBERSHIPS_TABLE,
182
289
  OUTBOX_EVENTS_TABLE,
290
+ # Channel-based Message Queue System
291
+ CHANNEL_MESSAGES_TABLE,
292
+ CHANNEL_SUBSCRIPTIONS_TABLE,
293
+ CHANNEL_DELIVERY_CURSORS_TABLE,
294
+ CHANNEL_MESSAGE_CLAIMS_TABLE,
183
295
  ]
184
296
 
185
297
  # All index creation statements
@@ -187,8 +299,14 @@ ALL_INDEXES = (
187
299
  WORKFLOW_DEFINITIONS_INDEXES
188
300
  + WORKFLOW_INSTANCES_INDEXES
189
301
  + WORKFLOW_HISTORY_INDEXES
302
+ + WORKFLOW_HISTORY_ARCHIVE_INDEXES
190
303
  + WORKFLOW_COMPENSATIONS_INDEXES
191
- + WORKFLOW_EVENT_SUBSCRIPTIONS_INDEXES
192
304
  + WORKFLOW_TIMER_SUBSCRIPTIONS_INDEXES
305
+ + WORKFLOW_GROUP_MEMBERSHIPS_INDEXES
193
306
  + OUTBOX_EVENTS_INDEXES
307
+ # Channel-based Message Queue System
308
+ + CHANNEL_MESSAGES_INDEXES
309
+ + CHANNEL_SUBSCRIPTIONS_INDEXES
310
+ + CHANNEL_DELIVERY_CURSORS_INDEXES
311
+ + CHANNEL_MESSAGE_CLAIMS_INDEXES
194
312
  )