async-job-adapter-active_job 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 819137db78b9172ca892bba8fd35a930f1a27b50e41ff316c3d110eb8550fe2e
4
- data.tar.gz: 5fd3c2be9e29c70d298026c491656f355d032fdc093e24596df733daa2ba99dc
3
+ metadata.gz: 9963783ca059ac1a3572fdbcca27ecfb6b0e2512e8994603ba1e1191d77ece61
4
+ data.tar.gz: f4be3f33865cf8a1d5aeec993b518418c9f422090ed0de4c5ff16aef5a02a276
5
5
  SHA512:
6
- metadata.gz: 1d723052fb8220f8e3c97068b6347f71ef91054f04c4ca3b24f2a4ae4096a24abb813c5820b7005b992d98737f22b4fef03fc715c058147a5fe6935e22175ea1
7
- data.tar.gz: 263bde81f472085a1098ff37c2e6e1456d8b0196e4d16b62acf5a5d9673a2bf26a05d647817685210c75af20819053398afa83f29b67382aa93b26cc629e294a
6
+ metadata.gz: bc94ed3bad8be7871793b65a36cec6da478515df5cec6f0c733c842fd9af2f3024174314f7f2bab308d4bb7175dbec65b4c62934dae4578b9c9f97d7021108f7
7
+ data.tar.gz: c232453580b7ee21760449b7e31f69b06cc4f7ee862c885a7eb61e0bc90057fd9e27d9c38bd93e00c94af4e7ede932204fb8a3a3804850c61ae3e619bdb25e28
checksums.yaml.gz.sig CHANGED
Binary file
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
5
+
6
+ require_relative 'queue_adapter'
7
+ require_relative 'queue_handler'
8
+
9
+ module Async
10
+ module Job
11
+ module Adapter
12
+ module ActiveJob
13
+ class Builder
14
+ Pipeline = Struct.new(:adapter, :queue)
15
+
16
+ def initialize
17
+ @enqueue = []
18
+ @dequeue = []
19
+ @handler = QueueHandler::DEFAULT
20
+
21
+ @queue = nil
22
+ end
23
+
24
+ def enqueue(middleware)
25
+ @enqueue << middleware
26
+ end
27
+
28
+ def queue(queue, *arguments, **options)
29
+ # The handler is the output side of the queue, e.g. a QueueHandler or similar wrapper.
30
+ # The queue itself is instantiated with the handler.
31
+ @queue = ->(handler){queue.new(handler, *arguments, **options)}
32
+ end
33
+
34
+ def dequeue(middleware)
35
+ @dequeue << middleware
36
+ end
37
+
38
+ def handler(handler)
39
+ @handler = handler
40
+ end
41
+
42
+ def build
43
+ # To construct the queue, we need the handler.
44
+ handler = @handler
45
+
46
+ # We then wrap the handler with the middleware in reverse order:
47
+ @dequeue.reverse_each do |middleware|
48
+ handler = middleware.new(handler)
49
+ end
50
+
51
+ # We can now construct the queue with the handler:
52
+ queue = @queue.call(handler)
53
+
54
+ adapter = queue
55
+
56
+ # We now construct the queue adapter:
57
+ adapter = @enqueue.reverse_each do |middleware|
58
+ adapter = middleware.new(queue)
59
+ end
60
+
61
+ unless adapter.is_a?(QueueAdapter)
62
+ adapter = QueueAdapter.new(adapter)
63
+ end
64
+
65
+ # The adapter is the part we provide to ActiveJob, and the handler is the part that actually executes the job:
66
+ return Pipeline.new(adapter, queue)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
5
+
6
+ require 'async/job'
7
+ require 'thread/local'
8
+
9
+ require_relative 'builder'
10
+
11
+ module Async
12
+ module Job
13
+ module Adapter
14
+ module ActiveJob
15
+ class Dispatcher
16
+ def initialize(backends, aliases = {})
17
+ @backends = backends
18
+ @aliases = aliases
19
+
20
+ @pipelines = {}
21
+ end
22
+
23
+ attr :backends
24
+
25
+ attr :aliases
26
+
27
+ def [](name)
28
+ @pipelines.fetch(name) do
29
+ backend = @backends.fetch(name)
30
+ @pipelines[name] = build(backend)
31
+ end
32
+ end
33
+
34
+ def enqueue(job)
35
+ name = @aliases.fetch(job.queue_name, job.queue_name)
36
+
37
+ self[name].adapter.enqueue(job)
38
+ end
39
+
40
+ def enqueue_at(job, timestamp)
41
+ name = @aliases.fetch(job.queue_name, job.queue_name)
42
+
43
+ self[name].adapter.enqueue_at(job, timestamp)
44
+ end
45
+
46
+ def start(name)
47
+ self[name].queue.start
48
+ end
49
+
50
+ private def build(backend)
51
+ builder = Builder.new
52
+
53
+ builder.instance_eval(&backend)
54
+
55
+ builder.build
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -22,17 +22,6 @@ module Async
22
22
  Console.info(self, "Enqueueing job at...", id: job.job_id, timestamp: timestamp)
23
23
  @server.schedule(@coder.dump(job.serialize), timestamp)
24
24
  end
25
-
26
- def start
27
- Async do
28
- @server.start
29
-
30
- @server.each do |id, data|
31
- job = @coder.parse(data)
32
- ::ActiveJob::Base.execute(job)
33
- end
34
- end
35
- end
36
25
  end
37
26
  end
38
27
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
5
+
6
+ require 'json'
7
+
8
+ module Async
9
+ module Job
10
+ module Adapter
11
+ module ActiveJob
12
+ class QueueHandler
13
+ def initialize(coder = JSON)
14
+ @coder = coder
15
+ end
16
+
17
+ def call(job)
18
+ job = @coder.load(job)
19
+ Console.info(self, "Calling job...", id: job[:job_id])
20
+ ::ActiveJob::Base.execute(job)
21
+ end
22
+
23
+ DEFAULT = self.new.freeze
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -4,38 +4,76 @@
4
4
  # Copyright, 2024, by Samuel Williams.
5
5
 
6
6
  require 'async/job'
7
-
8
7
  require 'thread/local'
9
8
 
9
+ require_relative 'dispatcher'
10
+
11
+ class Thread
12
+ attr_accessor :async_job_adapter_active_job_dispatcher
13
+ end
10
14
 
11
15
  module Async
12
16
  module Job
13
17
  module Adapter
14
18
  module ActiveJob
15
19
  class Railtie < ::Rails::Railtie
16
- config.async_job = ActiveSupport::OrderedOptions.new
20
+ DEFAULT_REDIS = proc do
21
+ queue Async::Job::Backend::Redis
22
+ end
23
+
24
+ def initialize
25
+ @backends = {default: DEFAULT_REDIS}
26
+ @aliases = {}
27
+ end
28
+
29
+ attr :backends
30
+
31
+ attr :aliases
32
+
33
+ def backend_for(name, *aliases, &block)
34
+ @backends[name] ||= block
35
+
36
+ if aliases.any?
37
+ alias_for(name, *aliases)
38
+ end
39
+ end
40
+
41
+ def alias_for(name, *aliases)
42
+ aliases.each do |alias_name|
43
+ @aliases[alias_name] = name
44
+ end
45
+ end
17
46
 
18
- module Dispatcher
19
- extend Thread::Local
47
+ # Used for dispatching jobs to a thread-local backend to avoid thread-safety issues.
48
+ class ThreadLocalDispatcher
49
+ def initialize(backends, aliases)
50
+ @backends = backends
51
+ @aliases = aliases
52
+ end
53
+
54
+ def dispatcher
55
+ Thread.current.async_job_adapter_active_job_dispatcher ||= Dispatcher.new(@backends)
56
+ end
20
57
 
21
- def self.local
22
- server = Async::Job::Backend.new(
23
- **Railtie.config.async_job
24
- )
25
-
26
- return QueueAdapter.new(server)
58
+ def enqueue_at(job, timestamp)
59
+ dispatcher.enqueue_at(job, timestamp)
27
60
  end
28
61
 
29
- def self.enqueue(job)
30
- self.instance.enqueue(job)
62
+ def enqueue(job)
63
+ dispatcher.enqueue(job)
31
64
  end
32
65
 
33
- def self.enqueue_at(job, timestamp)
34
- self.instance.enqueue_at(job, timestamp)
66
+ def start(name)
67
+ dispatcher.start(name)
35
68
  end
36
69
  end
37
70
 
38
- config.active_job.queue_adapter = Dispatcher
71
+ def start(name = :default)
72
+ config.active_job.queue_adapter.start(name)
73
+ end
74
+
75
+ config.async_job = self
76
+ config.active_job.queue_adapter = ThreadLocalDispatcher.new(self.backends, self.aliases)
39
77
  end
40
78
  end
41
79
  end
@@ -7,7 +7,7 @@ module Async
7
7
  module Job
8
8
  module Adapter
9
9
  module ActiveJob
10
- VERSION = "0.2.1"
10
+ VERSION = "0.3.0"
11
11
  end
12
12
  end
13
13
  end
data/readme.md CHANGED
@@ -30,6 +30,22 @@ Then run it:
30
30
  $ bundle exec ./job-server.rb
31
31
  ```
32
32
 
33
+ ### Configuration
34
+
35
+ ```ruby
36
+ Rails.application.configure do
37
+ config.async_job.backend_for :default, :critical do
38
+ queue Async::Job::Backend::Redis, endpoint: Async::IO::Endpoint.tcp('redis.local')
39
+ end
40
+
41
+ config.async_job.aliases_for :default, :email
42
+
43
+ config.async_job.backend_for :local do
44
+ queue Async::Job::Backend::Inline
45
+ end
46
+ end
47
+ ```
48
+
33
49
  ## Contributing
34
50
 
35
51
  We welcome contributions to this project.
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-job-adapter-active_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -37,7 +37,7 @@ cert_chain:
37
37
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
38
38
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
39
39
  -----END CERTIFICATE-----
40
- date: 2024-02-24 00:00:00.000000000 Z
40
+ date: 2024-02-25 00:00:00.000000000 Z
41
41
  dependencies:
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: async-job
@@ -74,7 +74,10 @@ extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
76
  - lib/async/job/adapter/active_job.rb
77
+ - lib/async/job/adapter/active_job/builder.rb
78
+ - lib/async/job/adapter/active_job/dispatcher.rb
77
79
  - lib/async/job/adapter/active_job/queue_adapter.rb
80
+ - lib/async/job/adapter/active_job/queue_handler.rb
78
81
  - lib/async/job/adapter/active_job/railtie.rb
79
82
  - lib/async/job/adapter/active_job/service.rb
80
83
  - lib/async/job/adapter/active_job/version.rb
metadata.gz.sig CHANGED
Binary file