sfn_job 0.1.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a82f27e9eb0a157217986266bcc79a6dbce08ca4a2729315bf4a6e743408daf8
4
+ data.tar.gz: 7273359c3d3dee2e88e55bf7c13a1559eb1be81cac9ec9e0b8b147cfe12dfc0b
5
+ SHA512:
6
+ metadata.gz: 8aa931901a48dd5d2ef0e8dcd98df1c80513f69d9f496b6599b8371e6b6a819ae8115bdef48473edc5c0845e3b3c565e961a355093deab7b827808fef1e7f97e
7
+ data.tar.gz: '014449fc5d255a07c5957df6aba749337b7eeb0cff117bbe57fc21cb4c6875249598d2f2fb411aa9382ef0443ff7168fc28d24875aad7b7b55eb298aa57687cc'
data/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # SfnJob
2
+
3
+ SfnJob provides a simple way to run a job on AWS Step Functions.
4
+
5
+ This might be useful when your team use sidekiq on container
6
+ which makes it hard to run a job takes long time.
7
+
8
+ ## Installation
9
+
10
+ ```
11
+ gem install sfn_job
12
+ # or bundle add sfn_job
13
+ ```
14
+
15
+ ## Configuration
16
+
17
+ ```ruby
18
+ SfnJob.configure do |config|
19
+ config.region = "ap-northeast-1"
20
+ config.account_id = "123456789012"
21
+ config.stub_sfn_client = Rails.env.test? # Set this to true when test not to call AWS API actually
22
+ end
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ this gem provides active job adapter and runner task for enqueued job
28
+
29
+ ```ruby
30
+ class SomeJob < ApplicationJob
31
+ self.queue_adapter = :sfn_job
32
+ # Treat state machine name as queue name
33
+ queue_as "sfn_job"
34
+
35
+ def perform(item_id)
36
+ # do something
37
+ end
38
+ end
39
+ ```
40
+
41
+ The gem will call StartExecution API with input as below:
42
+
43
+ ```json
44
+ {
45
+ "serialized_job": "serialized_job_as_json"
46
+ }
47
+ ```
48
+
49
+ And create state machine which pass this serialized_job to RunTask overrided env "SERIEALIZED_JOB".
50
+
51
+ ```bash
52
+ SERIEALIZED_JOB='serialized_job_as_json' bundle exec rails sfn_job:execute
53
+ ```
54
+
55
+ ## Why
56
+
57
+ It's quite complex to handle long time async job,
58
+ such as [sidekiq-iteration](https://github.com/fatkodima/sidekiq-iteration) or split job into small pieces with `Sideiq::Batch`.
59
+
60
+ ## Why not
61
+
62
+ - hard to accept more infra complexity
63
+ - which jobs are enqueued frequently
64
+ - Be careful with sfn StartExecution api rate limit. [Step Functions service quotas - AWS](https://docs.aws.amazon.com/step-functions/latest/dg/service-quotas.html)
65
+ - And RunTask api rate limit also (if you use Fargate) [AWS Fargate throttling quotas - AWS](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/throttling.html)
66
+
67
+ ## Development
68
+
69
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
70
+
71
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
72
+
73
+ ## Contributing
74
+
75
+ Bug reports and pull requests are welcome on GitHub at https://github.com/riseshia/sfn_job.
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveJob
4
+ module QueueAdapters
5
+ class SfnJobAdapter
6
+ def enqueue(job)
7
+ SfnJob.enqueue(job)
8
+ end
9
+
10
+ def enqueue_at(job, timestamp)
11
+ raise NotImplementedError, "enqueue_at is not supported by SfnJob"
12
+ end
13
+
14
+ def enqueue_all(jobs)
15
+ raise NotImplementedError, "enqueue_all is not supported by SfnJob"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SfnJob
4
+ class Configuration
5
+ attr_accessor :region, :account_id, :stub_sfn_client
6
+
7
+ def initialize
8
+ @stub_sfn_client = false
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ ActiveSupport.on_load(:active_job) do
2
+ require 'active_job/queue_adapters/sfn_job_adapter'
3
+ end
4
+
5
+ module BarbequeClient
6
+ class Railtie < Rails::Railtie
7
+ rake_tasks do
8
+ load 'tasks/sfn_job.rake'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SfnJob
4
+ class Runner
5
+ class << self
6
+ def run(serialized_job)
7
+ job_data = SfnJob.deserialize(serialized_job)
8
+ ActiveJob::Base.execute job_data
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SfnJob
4
+ VERSION = "0.1.2"
5
+ end
data/lib/sfn_job.rb ADDED
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "aws-sdk-states"
5
+
6
+ begin
7
+ require "rails"
8
+ rescue LoadError
9
+ else
10
+ require "sfn_job/railtie"
11
+ end
12
+
13
+ require_relative "sfn_job/version"
14
+ require_relative "sfn_job/configuration"
15
+ require_relative "sfn_job/runner"
16
+
17
+ module SfnJob
18
+ MAX_SERIALIZED_JOB_SIZE = 60_000
19
+
20
+ class << self
21
+ def configure
22
+ yield config
23
+ end
24
+
25
+ def config
26
+ @config ||= Configuration.new
27
+ end
28
+
29
+ def enqueue(job)
30
+ sfn_client.start_execution({
31
+ state_machine_arn: build_arn(job.queue_name),
32
+ name: "#{job.class.name}-#{job.job_id}",
33
+ input: serialize(job),
34
+ })
35
+ end
36
+
37
+ def sfn_client
38
+ @sfn_client ||= Aws::States::Client.new(region: config.region, stub_responses: config.stub_sfn_client)
39
+ end
40
+
41
+ private def build_arn(sfn_name)
42
+ "arn:aws:states:#{config.region}:#{config.account_id}:stateMachine:#{sfn_name}"
43
+ end
44
+
45
+ private def serialize(job)
46
+ JSON.dump({ serialized_job: JSON.dump(job.serialize) }).tap do |serialized_job|
47
+ raise "Job serialization is too large" if serialized_job.bytesize > MAX_SERIALIZED_JOB_SIZE
48
+ end
49
+ end
50
+
51
+ def deserialize(serialized_job)
52
+ JSON.parse(serialized_job)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :sfn_job do
4
+ desc 'Start worker to execute jobs'
5
+ task execute: :environment do
6
+ require 'sfn_job'
7
+
8
+ $stdout.sync = true
9
+
10
+ if ENV['SERIALIZED_JOB'].nil?
11
+ raise 'SERIALIZED_JOB environment variable is required'
12
+ end
13
+
14
+ serialized_job = ENV.fetch('SERIALIZED_JOB')
15
+
16
+ SfnJob::Runner.run(serialized_job)
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sfn_job
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Shia
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-11-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-states
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: ActiveJob on State Functions
42
+ email:
43
+ - rise.shia@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - README.md
49
+ - lib/active_job/queue_adapters/sfn_job_adapter.rb
50
+ - lib/sfn_job.rb
51
+ - lib/sfn_job/configuration.rb
52
+ - lib/sfn_job/railtie.rb
53
+ - lib/sfn_job/runner.rb
54
+ - lib/sfn_job/version.rb
55
+ - lib/tasks/sfn_job.rake
56
+ homepage: https://github.com/riseshia/sfn_job
57
+ licenses: []
58
+ metadata:
59
+ homepage_uri: https://github.com/riseshia/sfn_job
60
+ source_code_uri: https://github.com/riseshia/sfn_job
61
+ changelog_uri: https://github.com/riseshia/sfn_job
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: 3.2.0
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubygems_version: 3.5.16
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: ActiveJob on State Functions
81
+ test_files: []