sfn_job 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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: []