chrono_forge 0.3.0 โ†’ 0.3.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b16c027867c5aca8d3f168ccb252125feef563731af33f40a129bfa9bfb781c5
4
- data.tar.gz: 0ebd43e1896ea8df4ceb00c9c9af49c57a1e74d309149e817e43f9acfdfd5b8a
3
+ metadata.gz: 8c9315ad74de7245484119f385f2eb9706d1e3e532e142696d03d204e37f81ad
4
+ data.tar.gz: 4ea5ef5858c6d5fc8903f5432dd1ddc643d3cb6d26e65693c8a30664224a51c5
5
5
  SHA512:
6
- metadata.gz: c94edc3ed7339bf3c7304c54e547bb1f86bc098dda586ffa049cfaf2fc29efcc7b44cce9429789ee1c3c5559dd3dd75859b75e74a27587c2a804160fee600f42
7
- data.tar.gz: f7350954cace2c26ca57c7c0253a81d098a2eb655a5f283e6627eedec9d2b4acc11e0f58d3bebe47cd8a4c82907e1c4410d3655c43695ec8f02b8cc0af6a52c2
6
+ metadata.gz: 4713568fd2d32ddc70737fb5eb2f91db90aa41ff80d446afcd91f79719938e427f87b06da69dae18fb253c751aec07a70954e2f941053cb748db7fed04304ff0
7
+ data.tar.gz: caed47e85300d073b9ee1309d33b05047f2b0e6f60e95612ca247c86f233a32c823f9d68307e77384573c250b1779407e630a2f7ecd3557d2c033482f4326263
data/README.md CHANGED
@@ -47,17 +47,45 @@ $ rails db:migrate
47
47
 
48
48
  ## ๐Ÿ“‹ Usage
49
49
 
50
+ ### Creating and Executing Workflows
51
+
52
+ ChronoForge workflows are ActiveJob classes that prepend the `ChronoForge::Executor` module. Each workflow can **only** accept keyword arguments:
53
+
54
+ ```ruby
55
+ # Define your workflow class
56
+ class OrderProcessingWorkflow < ApplicationJob
57
+ prepend ChronoForge::Executor
58
+
59
+ def perform(order_id:, customer_id:)
60
+ # Workflow steps...
61
+ end
62
+ end
63
+ ```
64
+
65
+ All workflows require a unique identifier when executed. This identifier is used to track and manage the workflow:
66
+
67
+ ```ruby
68
+ # Execute the workflow
69
+ OrderProcessingWorkflow.perform_later(
70
+ "order-123", # Unique workflow key
71
+ order_id: "order-134", # Custom kwargs
72
+ customer_id: "customer-456" # More custom kwargs
73
+ )
74
+ ```
75
+
50
76
  ### Basic Workflow Example
51
77
 
52
78
  Here's a complete example of a durable order processing workflow:
53
79
 
54
80
  ```ruby
55
81
  class OrderProcessingWorkflow < ApplicationJob
56
- include ChronoForge::Executor
82
+ prepend ChronoForge::Executor
83
+
84
+ def perform(order_id:)
85
+ @order_id = order_id
57
86
 
58
- def perform
59
87
  # Context can be used to pass and store data between executions
60
- context.set_once "order_id", SecureRandom.hex
88
+ context.set_once "execution_id", SecureRandom.hex
61
89
 
62
90
  # Wait until payment is confirmed
63
91
  wait_until :payment_confirmed?
@@ -75,16 +103,16 @@ class OrderProcessingWorkflow < ApplicationJob
75
103
  private
76
104
 
77
105
  def payment_confirmed?
78
- PaymentService.confirmed?(context["order_id"])
106
+ PaymentService.confirmed?(@order_id, context["execution_id"])
79
107
  end
80
108
 
81
109
  def process_order
82
- OrderProcessor.process(context["order_id"])
110
+ OrderProcessor.process(@order_id, context["execution_id"])
83
111
  context["processed_at"] = Time.current.iso8601
84
112
  end
85
113
 
86
114
  def complete_order
87
- OrderCompletionService.complete(context["order_id"])
115
+ OrderCompletionService.complete(@order_id, context["execution_id"])
88
116
  context["completed_at"] = Time.current.iso8601
89
117
  end
90
118
  end
@@ -92,6 +120,28 @@ end
92
120
 
93
121
  ### Core Workflow Features
94
122
 
123
+ #### ๐Ÿš€ Executing Workflows
124
+
125
+ ChronoForge workflows are executed through ActiveJob's standard interface with a specific parameter structure:
126
+
127
+ ```ruby
128
+ # Perform the workflow immediately
129
+ OrderProcessingWorkflow.perform_now(
130
+ "order-123", # Unique workflow key
131
+ order_id: "O-123", # Custom parameter
132
+ customer_id: "C-456" # Another custom parameter
133
+ )
134
+
135
+ # Or queue it for background processing
136
+ OrderProcessingWorkflow.perform_later(
137
+ "order-123-async", # Unique workflow key
138
+ order_id: "O-124",
139
+ customer_id: "C-457"
140
+ )
141
+ ```
142
+
143
+ **Important:** Workflows must use keyword arguments only, not positional arguments.
144
+
95
145
  #### โšก Durable Execution
96
146
 
97
147
  The `durably_execute` method ensures operations are executed exactly once, even if the job fails and is retried:
@@ -147,13 +197,15 @@ if context.key?(:user_id)
147
197
  end
148
198
  ```
149
199
 
200
+ The context supports serializable Ruby objects (Hash, Array, String, Integer, Float, Boolean, and nil) and validates types automatically.
201
+
150
202
  ### ๐Ÿ›ก๏ธ Error Handling
151
203
 
152
204
  ChronoForge automatically tracks errors and provides configurable retry capabilities:
153
205
 
154
206
  ```ruby
155
207
  class MyWorkflow < ApplicationJob
156
- include ChronoForge::Executor
208
+ prepend ChronoForge::Executor
157
209
 
158
210
  private
159
211
 
@@ -198,14 +250,18 @@ class WorkflowTest < ActiveJob::TestCase
198
250
  include ChaoticJob::Helpers
199
251
 
200
252
  def test_workflow_completion
201
- # Enqueue the job
202
- OrderProcessingWorkflow.perform_later("order_123")
253
+ # Enqueue the job with a unique key and custom parameters
254
+ OrderProcessingWorkflow.perform_later(
255
+ "order-test-123",
256
+ order_id: "O-123",
257
+ customer_id: "C-456"
258
+ )
203
259
 
204
260
  # Perform all enqueued jobs
205
261
  perform_all_jobs
206
262
 
207
263
  # Assert workflow completed successfully
208
- workflow = ChronoForge::Workflow.last
264
+ workflow = ChronoForge::Workflow.find_by(key: "order-test-123")
209
265
  assert workflow.completed?
210
266
 
211
267
  # Check workflow context
data/export.json CHANGED
@@ -5,7 +5,7 @@
5
5
  },
6
6
  {
7
7
  "path": "/Users/stefan/Documents/plutonium/chrono_forge/README.md",
8
- "contents": "# ChronoForge\n\nChronoForge is a Ruby gem that provides a robust framework for building durable, distributed workflows in Ruby on Rails applications. It offers a reliable way to handle long-running processes, state management, and error recovery.\n\n## Features\n\n- **Durable Execution**: Automatically tracks and recovers from failures during workflow execution\n- **State Management**: Built-in workflow state tracking with support for custom contexts\n- **Concurrency Control**: Advanced locking mechanisms to prevent concurrent execution of the same workflow\n- **Error Handling**: Comprehensive error tracking and retry strategies\n- **Execution Logging**: Detailed logging of workflow execution steps and errors\n- **Wait States**: Support for time-based waits and condition-based waiting\n- **Database-Backed**: All workflow state is persisted to the database for durability\n- **ActiveJob Integration**: Seamlessly works with any ActiveJob backend\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'chrono_forge'\n```\n\nThen execute:\n\n```bash\n$ bundle install\n```\n\nOr install it directly:\n\n```bash\n$ gem install chrono_forge\n```\n\nAfter installation, run the generator to create the necessary database migrations:\n\n```bash\n$ rails generate chrono_forge:install\n$ rails db:migrate\n```\n\n## Usage\n\n### Basic Workflow Example\n\nHere's a complete example of a durable order processing workflow:\n\n```ruby\nclass OrderProcessingWorkflow < ApplicationJob\n include ChronoForge::Executor\n\n def perform\n # Context can be used to pass and store data between executions\n context[\"order_id\"] = SecureRandom.hex\n\n # Wait until payment is confirmed\n wait_until :payment_confirmed?\n\n # Wait for potential fraud check\n wait 1.minute, :fraud_check_delay\n\n # Durably execute order processing\n durably_execute :process_order\n\n # Final steps\n complete_order\n end\n\n private\n\n def payment_confirmed?\n PaymentService.confirmed?(context[\"order_id\"])\n end\n\n def process_order\n context[\"processed_at\"] = Time.current.iso8601\n OrderProcessor.process(context[\"order_id\"])\n end\n\n def complete_order\n context[\"completed_at\"] = Time.current.iso8601\n OrderCompletionService.complete(context[\"order_id\"])\n end\nend\n```\n\n### Workflow Features\n\n#### Durable Execution\n\nThe `durably_execute` method ensures operations are executed exactly once:\n\n```ruby\n# Execute a method\ndurably_execute(:process_payment, max_attempts: 3)\n\n# Or with a block\ndurably_execute -> (ctx) {\n Payment.process(ctx[:payment_id])\n}\n```\n\n#### Wait States\n\nChronoForge supports both time-based and condition-based waits:\n\n```ruby\n# Wait for a specific duration\nwait 1.hour, :cooling_period\n\n# Wait until a condition is met\nwait_until :payment_processed, \n timeout: 1.hour,\n check_interval: 5.minutes\n```\n\n#### Workflow Context\n\nChronoForge provides a persistent context that survives job restarts:\n\n```ruby\n# Set context values\ncontext[:user_name] = \"John Doe\"\ncontext[:status] = \"processing\"\n\n# Read context values\nuser_name = context[:user_name]\n```\n\n### Error Handling\n\nChronoForge automatically tracks errors and provides retry capabilities:\n\n```ruby\nclass MyWorkflow < ApplicationJob\n include ChronoForge::Executor\n\n private\n\n def should_retry?(error, attempt_count)\n case error\n when NetworkError\n attempt_count < 5\n when ValidationError\n false # Don't retry validation errors\n else\n attempt_count < 3\n end\n end\nend\n```\n\n## Testing\n\nChronoForge is designed to be easily testable using [ChaoticJob](https://github.com/fractaledmind/chaotic_job), a testing framework that makes it simple to test complex job workflows. Here's how to set up your test environment:\n\n1. Add ChaoticJob to your Gemfile's test group:\n\n```ruby\ngroup :test do\n gem 'chaotic_job'\nend\n```\n\n2. Set up your test helper:\n\n```ruby\n# test_helper.rb\nrequire 'chrono_forge'\nrequire 'minitest/autorun'\nrequire 'chaotic_job'\n```\n\nExample test:\n\n```ruby\nclass WorkflowTest < ActiveJob::TestCase\n include ChaoticJob::Helpers\n\n def test_workflow_completion\n # Enqueue the job\n OrderProcessingWorkflow.perform_later(\"order_123\")\n \n # Perform all enqueued jobs\n perform_all_jobs\n \n # Assert workflow completed successfully\n workflow = ChronoForge::Workflow.last\n assert workflow.completed?\n \n # Check workflow context\n assert workflow.context[\"processed_at\"].present?\n assert workflow.context[\"completed_at\"].present?\n end\nend\n```\n\nChaoticJob provides several helpful methods for testing workflows:\n\n- `perform_all_jobs`: Processes all enqueued jobs, including those enqueued during job execution\n\nFor testing with specific job processing libraries like Sidekiq or Delayed Job, you can still use their respective testing modes, but ChaoticJob is recommended for testing ChronoForge workflows as it better handles the complexities of nested job scheduling and wait states.\n\n\n## Database Schema\n\nChronoForge creates three main tables:\n\n1. `chrono_forge_workflows`: Stores workflow state and context\n2. `chrono_forge_execution_logs`: Tracks individual execution steps\n3. `chrono_forge_error_logs`: Records detailed error information\n\n## Development\n\nAfter checking out the repo, run:\n\n```bash\n$ bin/setup # Install dependencies\n$ bundle exec rake test # Run the tests\n$ bin/appraise # Run the full suite of appraisals\n$ bin/console # Start an interactive console\n```\n\nThe test suite uses SQLite by default and includes:\n- Unit tests for core functionality\n- Integration tests with ActiveJob\n- Example workflow implementations\n\n## Contributing\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin feature/my-new-feature`)\n5. Create a new Pull Request\n\nPlease include tests for any new features or bug fixes.\n\n## License\n\nThis gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n"
8
+ "contents": "# ChronoForge\n\n![Version](https://img.shields.io/badge/version-0.3.0-blue.svg)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n> A robust framework for building durable, distributed workflows in Ruby on Rails applications\n\nChronoForge provides a powerful solution for handling long-running processes, managing state, and recovering from failures in your Rails applications. Built on top of ActiveJob, it ensures your critical business processes remain resilient and traceable.\n\n## ๐ŸŒŸ Features\n\n- **Durable Execution**: Automatically tracks and recovers from failures during workflow execution\n- **State Management**: Built-in workflow state tracking with persistent context storage\n- **Concurrency Control**: Advanced locking mechanisms to prevent parallel execution of the same workflow\n- **Error Handling**: Comprehensive error tracking with configurable retry strategies\n- **Execution Logging**: Detailed logging of workflow steps and errors for visibility\n- **Wait States**: Support for time-based waits and condition-based waiting\n- **Database-Backed**: All workflow state is persisted to ensure durability\n- **ActiveJob Integration**: Compatible with all ActiveJob backends, though database-backed processors (like Solid Queue) provide the most reliable experience for long-running workflows\n\n## ๐Ÿ“ฆ Installation\n\nAdd to your application's Gemfile:\n\n```ruby\ngem 'chrono_forge'\n```\n\nThen execute:\n\n```bash\n$ bundle install\n```\n\nOr install directly:\n\n```bash\n$ gem install chrono_forge\n```\n\nAfter installation, run the generator to create the necessary database migrations:\n\n```bash\n$ rails generate chrono_forge:install\n$ rails db:migrate\n```\n\n## ๐Ÿ“‹ Usage\n\n### Creating and Executing Workflows\n\nChronoForge workflows are ActiveJob classes that prepend the `ChronoForge::Executor` module. Each workflow can **only** accept keyword arguments:\n\n```ruby\n# Define your workflow class\nclass OrderProcessingWorkflow < ApplicationJob\n prepend ChronoForge::Executor\n \n def perform(order_id:, customer_id:)\n # Workflow steps...\n end\nend\n```\n\nAll workflows require a unique identifier when executed. This identifier is used to track and manage the workflow:\n\n```ruby\n# Execute the workflow\nOrderProcessingWorkflow.perform_later(\n \"order-123\", # Unique workflow key\n order_id: \"order-134\", # Custom kwargs\n customer_id: \"customer-456\" # More custom kwargs\n)\n```\n\n### Basic Workflow Example\n\nHere's a complete example of a durable order processing workflow:\n\n```ruby\nclass OrderProcessingWorkflow < ApplicationJob\n prepend ChronoForge::Executor\n\n def perform(order_id:)\n @order_id = order_id\n\n # Context can be used to pass and store data between executions\n context.set_once \"execution_id\", SecureRandom.hex\n\n # Wait until payment is confirmed\n wait_until :payment_confirmed?\n\n # Wait for potential fraud check\n wait 1.minute, :fraud_check_delay\n\n # Durably execute order processing\n durably_execute :process_order\n\n # Final steps\n complete_order\n end\n\n private\n\n def payment_confirmed?\n PaymentService.confirmed?(@order_id, context[\"execution_id\"])\n end\n\n def process_order\n OrderProcessor.process(@order_id, context[\"execution_id\"])\n context[\"processed_at\"] = Time.current.iso8601\n end\n\n def complete_order\n OrderCompletionService.complete(@order_id, context[\"execution_id\"])\n context[\"completed_at\"] = Time.current.iso8601\n end\nend\n```\n\n### Core Workflow Features\n\n#### ๐Ÿš€ Executing Workflows\n\nChronoForge workflows are executed through ActiveJob's standard interface with a specific parameter structure:\n\n```ruby\n# Perform the workflow immediately\nOrderProcessingWorkflow.perform_now(\n \"order-123\", # Unique workflow key\n order_id: \"O-123\", # Custom parameter\n customer_id: \"C-456\" # Another custom parameter\n)\n\n# Or queue it for background processing\nOrderProcessingWorkflow.perform_later(\n \"order-123-async\", # Unique workflow key\n order_id: \"O-124\",\n customer_id: \"C-457\"\n)\n```\n\n**Important:** Workflows must use keyword arguments only, not positional arguments.\n\n#### โšก Durable Execution\n\nThe `durably_execute` method ensures operations are executed exactly once, even if the job fails and is retried:\n\n```ruby\n# Execute a method\ndurably_execute(:process_payment, max_attempts: 3)\n\n# Or with a block\ndurably_execute -> (ctx) {\n Payment.process(ctx[:payment_id])\n}\n```\n\n#### โฑ๏ธ Wait States\n\nChronoForge supports both time-based and condition-based waits:\n\n```ruby\n# Wait for a specific duration\nwait 1.hour, :cooling_period\n\n# Wait until a condition is met\nwait_until :payment_processed, \n timeout: 1.hour,\n check_interval: 5.minutes\n```\n\n#### ๐Ÿ”„ Workflow Context\n\nChronoForge provides a persistent context that survives job restarts. The context behaves like a Hash but with additional capabilities:\n\n```ruby\n# Set context values\ncontext[:user_name] = \"John Doe\"\ncontext[:status] = \"processing\"\n\n# Read context values\nuser_name = context[:user_name]\n\n# Using the fetch method (returns default if key doesn't exist)\nstatus = context.fetch(:status, \"pending\")\n\n# Set a value with the set method (alias for []=)\ncontext.set(:total_amount, 99.99)\n\n# Set a value only if the key doesn't already exist\ncontext.set_once(:created_at, Time.current.iso8601)\n\n# Check if a key exists\nif context.key?(:user_id)\n # Do something with the user ID\nend\n```\n\nThe context supports serializable Ruby objects (Hash, Array, String, Integer, Float, Boolean, and nil) and validates types automatically.\n\n### ๐Ÿ›ก๏ธ Error Handling\n\nChronoForge automatically tracks errors and provides configurable retry capabilities:\n\n```ruby\nclass MyWorkflow < ApplicationJob\n prepend ChronoForge::Executor\n\n private\n\n def should_retry?(error, attempt_count)\n case error\n when NetworkError\n attempt_count < 5 # Retry network errors up to 5 times\n when ValidationError\n false # Don't retry validation errors\n else\n attempt_count < 3 # Default retry policy\n end\n end\nend\n```\n\n## ๐Ÿงช Testing\n\nChronoForge is designed to be easily testable using [ChaoticJob](https://github.com/fractaledmind/chaotic_job), a testing framework that makes it simple to test complex job workflows:\n\n1. Add ChaoticJob to your Gemfile's test group:\n\n```ruby\ngroup :test do\n gem 'chaotic_job'\nend\n```\n\n2. Set up your test helper:\n\n```ruby\n# test_helper.rb\nrequire 'chrono_forge'\nrequire 'minitest/autorun'\nrequire 'chaotic_job'\n```\n\nExample test:\n\n```ruby\nclass WorkflowTest < ActiveJob::TestCase\n include ChaoticJob::Helpers\n\n def test_workflow_completion\n # Enqueue the job with a unique key and custom parameters\n OrderProcessingWorkflow.perform_later(\n \"order-test-123\",\n order_id: \"O-123\",\n customer_id: \"C-456\"\n )\n \n # Perform all enqueued jobs\n perform_all_jobs\n \n # Assert workflow completed successfully\n workflow = ChronoForge::Workflow.find_by(key: \"order-test-123\")\n assert workflow.completed?\n \n # Check workflow context\n assert workflow.context[\"processed_at\"].present?\n assert workflow.context[\"completed_at\"].present?\n end\nend\n```\n\n## ๐Ÿ—„๏ธ Database Schema\n\nChronoForge creates three main tables:\n\n1. **chrono_forge_workflows**: Stores workflow state and context\n2. **chrono_forge_execution_logs**: Tracks individual execution steps\n3. **chrono_forge_error_logs**: Records detailed error information\n\n## ๐Ÿ” When to Use ChronoForge\n\nChronoForge is ideal for:\n\n- **Long-running business processes** - Order processing, account registration flows\n- **Processes requiring durability** - Financial transactions, data migrations\n- **Multi-step workflows** - Onboarding flows, approval processes, multi-stage jobs\n- **State machines with time-based transitions** - Document approval, subscription lifecycle\n\n## ๐Ÿš€ Development\n\nAfter checking out the repo, run:\n\n```bash\n$ bin/setup # Install dependencies\n$ bundle exec rake test # Run the tests\n$ bin/appraise # Run the full suite of appraisals\n$ bin/console # Start an interactive console\n```\n\nThe test suite uses SQLite by default and includes:\n- Unit tests for core functionality\n- Integration tests with ActiveJob\n- Example workflow implementations\n\n## ๐Ÿ‘ฅ Contributing\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin feature/my-new-feature`)\n5. Create a new Pull Request\n\nPlease include tests for any new features or bug fixes.\n\n## ๐Ÿ“œ License\n\nThis gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n"
9
9
  },
10
10
  {
11
11
  "path": "/Users/stefan/Documents/plutonium/chrono_forge/chrono_forge.gemspec",
@@ -61,11 +61,11 @@
61
61
  },
62
62
  {
63
63
  "path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/version.rb",
64
- "contents": "# frozen_string_literal: true\n\nmodule ChronoForge\n VERSION = \"0.2.0\"\nend\n"
64
+ "contents": "# frozen_string_literal: true\n\nmodule ChronoForge\n VERSION = \"0.3.1\"\nend\n"
65
65
  },
66
66
  {
67
67
  "path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/workflow.rb",
68
- "contents": "# frozen_string_literal: true\n\n# == Schema Information\n#\n# Table name: chrono_forge_workflows\n#\n# id :integer not null, primary key\n# completed_at :datetime\n# context :json not null\n# job_class :string not null\n# key :string not null\n# kwargs :json not null\n# options :json not null\n# locked_at :datetime\n# started_at :datetime\n# state :integer default(\"idle\"), not null\n# created_at :datetime not null\n# updated_at :datetime not null\n#\n# Indexes\n#\n# index_chrono_forge_workflows_on_key (key) UNIQUE\n#\nmodule ChronoForge\n class Workflow < ActiveRecord::Base\n self.table_name = \"chrono_forge_workflows\"\n\n has_many :execution_logs, -> { order(id: :asc) }\n has_many :error_logs, -> { order(id: :asc) }\n\n enum :state, %i[\n idle\n running\n completed\n failed\n stalled\n ]\n\n # Serialization for metadata\n serialize :metadata, coder: JSON\n\n def executable?\n idle? || running?\n end\n\n def job_klass\n job_class.constantize\n end\n end\nend\n"
68
+ "contents": "# frozen_string_literal: true\n\n# == Schema Information\n#\n# Table name: chrono_forge_workflows\n#\n# id :integer not null, primary key\n# completed_at :datetime\n# context :json not null\n# job_class :string not null\n# key :string not null\n# kwargs :json not null\n# options :json not null\n# locked_at :datetime\n# started_at :datetime\n# state :integer default(\"idle\"), not null\n# created_at :datetime not null\n# updated_at :datetime not null\n#\n# Indexes\n#\n# index_chrono_forge_workflows_on_key (key) UNIQUE\n#\nmodule ChronoForge\n class Workflow < ActiveRecord::Base\n self.table_name = \"chrono_forge_workflows\"\n\n has_many :execution_logs, -> { order(id: :asc) }, dependent: :destroy\n has_many :error_logs, -> { order(id: :asc) }, dependent: :destroy\n\n enum :state, %i[\n idle\n running\n completed\n failed\n stalled\n ]\n\n # Serialization for metadata\n serialize :metadata, coder: JSON\n\n def executable?\n idle? || running?\n end\n\n def job_klass\n job_class.constantize\n end\n end\nend\n"
69
69
  },
70
70
  {
71
71
  "path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge.rb",
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ChronoForge
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.1"
5
5
  end
@@ -25,8 +25,8 @@ module ChronoForge
25
25
  class Workflow < ActiveRecord::Base
26
26
  self.table_name = "chrono_forge_workflows"
27
27
 
28
- has_many :execution_logs, -> { order(id: :asc) }
29
- has_many :error_logs, -> { order(id: :asc) }
28
+ has_many :execution_logs, -> { order(id: :asc) }, dependent: :destroy
29
+ has_many :error_logs, -> { order(id: :asc) }, dependent: :destroy
30
30
 
31
31
  enum :state, %i[
32
32
  idle
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chrono_forge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Froelich