cosmonats 0.2.0 → 0.4.0

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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +300 -187
  3. data/lib/cosmo/active_job/adapter.rb +46 -0
  4. data/lib/cosmo/active_job/executor.rb +16 -0
  5. data/lib/cosmo/active_job/options.rb +50 -0
  6. data/lib/cosmo/active_job.rb +29 -0
  7. data/lib/cosmo/api/busy.rb +2 -2
  8. data/lib/cosmo/api/counter.rb +2 -2
  9. data/lib/cosmo/api/cron/entry.rb +99 -0
  10. data/lib/cosmo/api/cron.rb +118 -0
  11. data/lib/cosmo/api/kv.rb +36 -14
  12. data/lib/cosmo/api/stream.rb +27 -9
  13. data/lib/cosmo/api.rb +1 -0
  14. data/lib/cosmo/cli.rb +27 -9
  15. data/lib/cosmo/client.rb +75 -5
  16. data/lib/cosmo/config.rb +14 -32
  17. data/lib/cosmo/engine.rb +1 -1
  18. data/lib/cosmo/job/data.rb +1 -1
  19. data/lib/cosmo/job/limit.rb +51 -0
  20. data/lib/cosmo/job/processor.rb +82 -63
  21. data/lib/cosmo/job.rb +51 -2
  22. data/lib/cosmo/logger.rb +4 -1
  23. data/lib/cosmo/processor.rb +108 -0
  24. data/lib/cosmo/railtie.rb +21 -0
  25. data/lib/cosmo/stream/processor.rb +24 -60
  26. data/lib/cosmo/stream.rb +4 -3
  27. data/lib/cosmo/utils/hash.rb +13 -24
  28. data/lib/cosmo/utils/overrides.rb +1 -1
  29. data/lib/cosmo/utils/ttl_cache.rb +44 -0
  30. data/lib/cosmo/utils.rb +1 -0
  31. data/lib/cosmo/version.rb +1 -1
  32. data/lib/cosmo/web/assets/app.css +88 -0
  33. data/lib/cosmo/web/controllers/crons.rb +41 -0
  34. data/lib/cosmo/web/controllers/jobs.rb +7 -3
  35. data/lib/cosmo/web/controllers/streams.rb +36 -10
  36. data/lib/cosmo/web/helpers/application.rb +17 -2
  37. data/lib/cosmo/web/views/actions/index.erb +1 -1
  38. data/lib/cosmo/web/views/crons/_table.erb +58 -0
  39. data/lib/cosmo/web/views/crons/index.erb +10 -0
  40. data/lib/cosmo/web/views/jobs/_busy.erb +54 -49
  41. data/lib/cosmo/web/views/jobs/_dead.erb +70 -65
  42. data/lib/cosmo/web/views/jobs/_enqueued.erb +82 -56
  43. data/lib/cosmo/web/views/jobs/_scheduled.erb +53 -48
  44. data/lib/cosmo/web/views/jobs/_tabs.erb +6 -0
  45. data/lib/cosmo/web/views/jobs/busy.erb +8 -6
  46. data/lib/cosmo/web/views/jobs/dead.erb +6 -5
  47. data/lib/cosmo/web/views/jobs/enqueued.erb +8 -6
  48. data/lib/cosmo/web/views/jobs/index.erb +1 -1
  49. data/lib/cosmo/web/views/jobs/scheduled.erb +6 -5
  50. data/lib/cosmo/web/views/layout.erb +1 -1
  51. data/lib/cosmo/web/views/streams/_info.erb +3 -0
  52. data/lib/cosmo/web/views/streams/_pause_banner.erb +17 -0
  53. data/lib/cosmo/web/views/streams/_stream_row.erb +42 -0
  54. data/lib/cosmo/web/views/streams/_table.erb +4 -21
  55. data/lib/cosmo/web.rb +7 -0
  56. data/lib/cosmo.rb +1 -0
  57. data/sig/cosmo/active_job/adapter.rbs +13 -0
  58. data/sig/cosmo/active_job/executor.rbs +9 -0
  59. data/sig/cosmo/active_job/options.rbs +14 -0
  60. data/sig/cosmo/api/cron/entry.rbs +30 -0
  61. data/sig/cosmo/api/cron.rbs +25 -0
  62. data/sig/cosmo/api/kv.rbs +4 -6
  63. data/sig/cosmo/api/stream.rbs +7 -1
  64. data/sig/cosmo/client.rbs +20 -4
  65. data/sig/cosmo/config.rbs +3 -15
  66. data/sig/cosmo/job/data.rbs +1 -1
  67. data/sig/cosmo/job/limit.rbs +18 -0
  68. data/sig/cosmo/job/processor.rbs +19 -9
  69. data/sig/cosmo/job.rbs +9 -4
  70. data/sig/cosmo/processor.rbs +26 -0
  71. data/sig/cosmo/railtie.rbs +4 -0
  72. data/sig/cosmo/stream/processor.rbs +4 -10
  73. data/sig/cosmo/utils/hash.rbs +4 -8
  74. data/sig/cosmo/utils/ttl_cache.rbs +20 -0
  75. metadata +25 -3
  76. data/lib/cosmo/defaults.yml +0 -70
@@ -1,5 +1,5 @@
1
1
  <section>
2
- <header></header>
2
+ <header><%= render('jobs/_tabs') %></header>
3
3
 
4
4
  <div hx-get="<%= url_for('/jobs/_stats') %>"
5
5
  hx-trigger="load, every 5s"
@@ -7,10 +7,12 @@
7
7
  <div class="alert alert-info">Loading statistics…</div>
8
8
  </div>
9
9
 
10
- <div id="content"
11
- hx-get="<%= url_for('/jobs/_enqueued', stream_name: @stream_name) %>"
12
- hx-trigger="load"
13
- hx-swap="innerHTML">
14
- <div class="alert alert-info">Loading enqueued jobs&hellip;</div>
10
+ <div id="content">
11
+ <div id="enqueued-poller"
12
+ hx-get="<%= url_for('/jobs/_enqueued', stream_name: @stream_name) %>"
13
+ hx-trigger="load"
14
+ hx-swap="outerHTML">
15
+ <div class="alert alert-info">Loading enqueued jobs&hellip;</div>
16
+ </div>
15
17
  </div>
16
18
  </section>
@@ -1,5 +1,5 @@
1
1
  <section>
2
- <header></header>
2
+ <header><%= render('jobs/_tabs') %></header>
3
3
 
4
4
  <div hx-get="<%= url_for('/jobs/_stats') %>"
5
5
  hx-trigger="load, every 5s"
@@ -1,5 +1,5 @@
1
1
  <section>
2
- <header></header>
2
+ <header><%= render('jobs/_tabs') %></header>
3
3
 
4
4
  <div hx-get="<%= url_for('/jobs/_stats') %>"
5
5
  hx-trigger="load, every 5s"
@@ -8,10 +8,11 @@
8
8
  </div>
9
9
 
10
10
  <div id="content">
11
- <div hx-get="<%= url_for('/jobs/_scheduled') %>"
12
- hx-trigger="load, every 5s"
13
- hx-swap="innerHTML">
14
- <div class="alert alert-info">Loading scheduled jobs…</div>
11
+ <div id="scheduled-poller"
12
+ hx-get="<%= url_for('/jobs/_scheduled') %>"
13
+ hx-trigger="load"
14
+ hx-swap="outerHTML">
15
+ <div class="alert alert-info">Loading scheduled jobs&hellip;</div>
15
16
  </div>
16
17
  </div>
17
18
  </section>
@@ -14,7 +14,7 @@
14
14
  <a href="<%= url_for('/jobs') %>" class="navbar-brand">🚀 Cosmo</a>
15
15
  <ul class="nav-list">
16
16
  <li>
17
- <a href="<%= url_for('/jobs') %>" class="<%= "active" if current_page?('/jobs') %>">Jobs</a>
17
+ <a href="<%= url_for('/jobs') %>" class="<%= "active" if path_prefix?('/jobs', '/crons') %>">Jobs</a>
18
18
  </li>
19
19
  <li>
20
20
  <a href="<%= url_for('/streams') %>" class="<%= "active" if current_page?('/streams') %>">Streams</a>
@@ -17,6 +17,8 @@
17
17
  </article>
18
18
  </div>
19
19
 
20
+ <%= render("streams/_pause_banner", { name: @name, paused: @paused }) %>
21
+
20
22
  <div class="nav">
21
23
  <a href="<%= url_for('/streams') %>"
22
24
  hx-get="<%= url_for('/streams') %>"
@@ -87,3 +89,4 @@
87
89
  <div class="subject-tag" style="padding: var(--space) var(--space-2x); font-size: 1rem;"><%= h(sub) %></div>
88
90
  <% end -%>
89
91
  </div>
92
+
@@ -0,0 +1,17 @@
1
+ <% if @paused -%>
2
+ <div id="pause-banner-<%= h(@name) %>" class="alert alert-warning" style="display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:var(--space-2x);">
3
+ <span>&#9208; <strong>Stream is paused</strong> — consumers are not fetching new messages.</span>
4
+ <a hx-patch="<%= url_for('/streams/unpause', { name: u(@name), banner: 1 }) %>"
5
+ hx-target="#pause-banner-<%= h(@name) %>"
6
+ hx-swap="outerHTML"
7
+ class="btn btn-success">&#9654; Resume Stream</a>
8
+ </div>
9
+ <% else -%>
10
+ <div id="pause-banner-<%= h(@name) %>" class="alert alert-success" style="display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:var(--space-2x);">
11
+ <span>&#9654; <strong>Stream is active</strong> — consumers are fetching new messages.</span>
12
+ <a hx-patch="<%= url_for('/streams/pause', { name: u(@name), banner: 1 }) %>"
13
+ hx-target="#pause-banner-<%= h(@name) %>"
14
+ hx-swap="outerHTML"
15
+ class="btn btn-warning">&#9208; Pause Stream</a>
16
+ </div>
17
+ <% end -%>
@@ -0,0 +1,42 @@
1
+ <tr id="stream-row-<%= h(@stream[:name]) %>">
2
+ <td>
3
+ <a href="<%= url_for('/streams/info', { name: u(@stream[:name]) }) %>"
4
+ hx-get="<%= url_for('/streams/info', { name: u(@stream[:name]) }) %>"
5
+ hx-target="#content"
6
+ hx-push-url="true"
7
+ class="stream-link"><%= h(@stream[:name]) %></a>
8
+ </td>
9
+ <td><%= format_numbers(@stream[:messages]) %></td>
10
+ <td><%= format_bytes(@stream[:bytes]) %></td>
11
+ <td><%= @stream[:consumer_count] %></td>
12
+ <td>
13
+ <div class="subjects">
14
+ <% Array(@stream[:subjects]).each do |subject| -%>
15
+ <span class="subject-tag"><%= h(subject) %></span>
16
+ <% end -%>
17
+ </div>
18
+ </td>
19
+ <td><code><%= format_numbers(@stream[:first_seq]) %> &rarr; <%= format_numbers(@stream[:last_seq]) %></code></td>
20
+ <td>
21
+ <% if @stream[:paused] -%>
22
+ <span class="badge badge-warning">&#9208; Paused</span>
23
+ <% elsif @stream[:consumer_count].to_i > 0 -%>
24
+ <span class="badge badge-success">&#9654; Active</span>
25
+ <% else -%>
26
+ <span class="badge">No consumers</span>
27
+ <% end -%>
28
+ </td>
29
+ <td>
30
+ <% if @stream[:paused] -%>
31
+ <a hx-patch="<%= url_for('/streams/unpause', { name: u(@stream[:name]) }) %>"
32
+ hx-target="#stream-row-<%= h(@stream[:name]) %>"
33
+ hx-swap="outerHTML"
34
+ class="btn btn-success">&#9654; Resume</a>
35
+ <% else -%>
36
+ <a hx-patch="<%= url_for('/streams/pause', { name: u(@stream[:name]) }) %>"
37
+ hx-target="#stream-row-<%= h(@stream[:name]) %>"
38
+ hx-swap="outerHTML"
39
+ class="btn btn-warning">&#9208; Pause</a>
40
+ <% end -%>
41
+ </td>
42
+ </tr>
@@ -11,30 +11,13 @@
11
11
  <th>Consumers</th>
12
12
  <th>Subjects</th>
13
13
  <th>Sequence</th>
14
+ <th>Status</th>
15
+ <th>Actions</th>
14
16
  </tr>
15
17
  </thead>
16
18
  <tbody>
17
- <% @streams.each do |s| -%>
18
- <tr>
19
- <td>
20
- <a href="<%= url_for('/streams/info', { name: u(s[:name]) }) %>"
21
- hx-get="<%= url_for('/streams/info', { name: u(s[:name]) }) %>"
22
- hx-target="#content"
23
- hx-push-url="true"
24
- class="stream-link"><%= h(s[:name]) %></a>
25
- </td>
26
- <td><%= format_numbers(s[:messages]) %></td>
27
- <td><%= format_bytes(s[:bytes]) %></td>
28
- <td><%= s[:consumer_count] %></td>
29
- <td>
30
- <div class="subjects">
31
- <% (s[:subjects] || []).each do |sub| -%>
32
- <span class="subject-tag"><%= h(sub) %></span>
33
- <% end -%>
34
- </div>
35
- </td>
36
- <td><code><%= format_numbers(s[:first_seq]) %> &rarr; <%= format_numbers(s[:last_seq]) %></code></td>
37
- </tr>
19
+ <% @streams.each do |stream| -%>
20
+ <%= render("streams/_stream_row", { stream: stream }) %>
38
21
  <% end -%>
39
22
  </tbody>
40
23
  </table>
data/lib/cosmo/web.rb CHANGED
@@ -9,6 +9,7 @@ require "cosmo/web/controllers/application"
9
9
  require "cosmo/web/controllers/jobs"
10
10
  require "cosmo/web/controllers/streams"
11
11
  require "cosmo/web/controllers/actions"
12
+ require "cosmo/web/controllers/crons"
12
13
 
13
14
  module Cosmo
14
15
  class Web
@@ -41,6 +42,12 @@ module Cosmo
41
42
  in [:get, "/streams/info"] then [Controllers::Streams, :info]
42
43
  in [:get, "/streams/_table"] then [Controllers::Streams, :_table]
43
44
  in [:get, "/streams/_info"] then [Controllers::Streams, :_info]
45
+ in [:patch, "/streams/pause"] then [Controllers::Streams, :pause]
46
+ in [:patch, "/streams/unpause"] then [Controllers::Streams, :unpause]
47
+ in [:get, "/crons"] then [Controllers::Crons, :index]
48
+ in [:get, "/crons/_table"] then [Controllers::Crons, :_table]
49
+ in [:delete, "/crons/delete"] then [Controllers::Crons, :delete]
50
+ in [:post, "/crons/run"] then [Controllers::Crons, :run_now]
44
51
  in [:get, "/actions"] then [Controllers::Actions, :index]
45
52
  in [:get, "/assets/htmx.min.js.gz"] then serve("htmx.2.0.8.min.js.gz",
46
53
  "application/javascript",
data/lib/cosmo.rb CHANGED
@@ -12,6 +12,7 @@ require "cosmo/stream"
12
12
  require "cosmo/cli"
13
13
  require "cosmo/engine"
14
14
  require "cosmo/api"
15
+ require "cosmo/railtie" if defined?(Rails::Railtie)
15
16
 
16
17
  module Cosmo
17
18
  class Error < StandardError; end
@@ -0,0 +1,13 @@
1
+ module Cosmo
2
+ module ActiveJobAdapter
3
+ class Adapter
4
+ def enqueue: (untyped job) -> String
5
+ def enqueue_at: (untyped job, Numeric timestamp) -> String
6
+
7
+ private
8
+
9
+ def publish: (untyped job, Numeric? timestamp) -> String
10
+ def job_cosmo_options: (untyped job) -> Hash[Symbol, untyped]
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ module Cosmo
2
+ module ActiveJobAdapter
3
+ class Executor
4
+ include Cosmo::Job
5
+
6
+ def perform: (Hash[Symbol, untyped] job_data) -> void
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ module Cosmo
2
+ module ActiveJobAdapter
3
+ VALID_OPTIONS: ::Array[::Symbol]
4
+
5
+ module Options
6
+ def self.included: (::Module base) -> void
7
+
8
+ module ClassMethods
9
+ def cosmo_options: (**untyped opts) -> ::Hash[::Symbol, untyped]
10
+ def get_cosmo_options: () -> ::Hash[::Symbol, untyped]
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,30 @@
1
+ module Cosmo
2
+ module API
3
+ class Cron
4
+ class Entry
5
+ SUBJECT_PREFIX: ::String
6
+
7
+ attr_reader class_name: ::String
8
+ attr_reader stream: ::String
9
+ attr_reader expression: ::String
10
+ attr_reader args: ::Array[untyped]
11
+ attr_reader timezone: ::String?
12
+ attr_reader name: ::String?
13
+
14
+ def self.normalize_expression: (untyped expr) -> ::String
15
+
16
+ def initialize: (class_name: ::String, stream: ::String, expression: ::String,
17
+ ?args: ::Array[untyped], ?timezone: ::String?, ?name: (::String | ::Symbol)?) -> void
18
+
19
+ def schedule_subject: () -> ::String
20
+ def target_subject: () -> ::String
21
+ def job_name: () -> ::String
22
+ def job_payload: () -> ::String
23
+ def as_json: () -> Hash[Symbol, untyped]
24
+ def to_s: () -> ::String
25
+ alias inspect to_s
26
+ end
27
+ end
28
+ end
29
+ end
30
+
@@ -0,0 +1,25 @@
1
+ module Cosmo
2
+ module API
3
+ class Cron
4
+ def all: () -> ::Array[Hash[Symbol, untyped]]
5
+
6
+ def upsert!: (?Cosmo::API::Cron::Entry schedule_obj,
7
+ ?class_name: ::String?,
8
+ ?stream: ::String?,
9
+ ?expression: ::String?,
10
+ ?args: ::Array[untyped],
11
+ ?timezone: ::String?,
12
+ ?name: ::String?) -> Hash[Symbol, untyped]?
13
+
14
+ def delete!: (::String subject) -> void
15
+
16
+ def run_now!: (::String schedule_subject) -> void
17
+
18
+ private
19
+
20
+ def schedules_from_stream: (::String stream_name) -> ::Array[Hash[Symbol, untyped]]
21
+ def build_from_nats: (::String stream_name, ::String subject) -> Hash[Symbol, untyped]?
22
+ def name_from_subject: (::String subject) -> ::String?
23
+ end
24
+ end
25
+ end
data/sig/cosmo/api/kv.rbs CHANGED
@@ -5,11 +5,13 @@ module Cosmo
5
5
  @options: Hash[Symbol, untyped]
6
6
  @kv: untyped
7
7
 
8
+ attr_reader kv: untyped
9
+
8
10
  def initialize: (::String name, ?Hash[Symbol, untyped]? options) -> void
9
11
 
10
- def set: (::String | ::Integer key, ::String value) -> untyped
12
+ def set: (::String | ::Integer key, untyped value, ?ttl: ::Integer?) -> untyped
11
13
 
12
- def get: (::String | ::Integer key) -> ::String?
14
+ def get: (::String | ::Integer key) -> untyped
13
15
 
14
16
  def delete: (::String | ::Integer key) -> untyped
15
17
 
@@ -21,10 +23,6 @@ module Cosmo
21
23
 
22
24
  def count: () -> ::Integer
23
25
  alias size count
24
-
25
- private
26
-
27
- def kv: () -> untyped
28
26
  end
29
27
  end
30
28
  end
@@ -26,7 +26,7 @@ module Cosmo
26
26
 
27
27
  def retries: () -> ::Integer
28
28
 
29
- def each: (?from: ::Integer?) { (Job) -> void } -> void
29
+ def each: () { (Job) -> void } -> void
30
30
 
31
31
  def messages: (?page: ::Integer?, ?limit: ::Integer?) -> Array[Job]
32
32
 
@@ -36,6 +36,12 @@ module Cosmo
36
36
 
37
37
  def delete: (::Integer seq) -> untyped
38
38
 
39
+ def pause!: () -> untyped
40
+
41
+ def unpause!: () -> untyped
42
+
43
+ def paused?: () -> bool
44
+
39
45
  private
40
46
 
41
47
  def client: () -> Client
data/sig/cosmo/client.rbs CHANGED
@@ -21,20 +21,36 @@ module Cosmo
21
21
 
22
22
  def delete_stream: (::String | Symbol name, ?Hash[Symbol, untyped] params) -> untyped
23
23
 
24
- def list_streams: () -> Array[::String]
24
+ def update_stream: (::String | Symbol name, Hash[Symbol, untyped] config) -> untyped
25
+
26
+ def setup_stream: (::String name, Hash[Symbol, untyped] config) -> untyped
27
+
28
+ def cron_subjects_in_stream: (::String stream_name, ::String filter) -> Array[::String]
29
+
30
+ def list_streams: () -> Array[Hash[::String, untyped]]
31
+
32
+ def pause_stream: (::String name) -> void
33
+
34
+ def unpause_stream: (::String name) -> void
35
+
36
+ def stream_paused?: (::String name) -> bool
25
37
 
26
38
  def list_consumers: (::String stream_name) -> Array[Hash[::String, untyped]]
27
39
 
40
+ def consumer_info: (::String stream_name, ::String consumer_name) -> NATS::JetStream::API::ConsumerInfo
41
+
28
42
  def get_message: (::String | Symbol name, **untyped options) -> NATS::JetStream::API::RawStreamMsg
29
43
 
30
44
  def delete_message: (::String name, ::Integer seq) -> Hash[::String, untyped]
31
45
 
32
46
  def purge: (::String stream_name, ::String? subject) -> ::Integer?
33
47
 
34
- def consumer_info: (::String stream_name, ::String consumer_name) -> NATS::JetStream::API::ConsumerInfo
35
-
36
- def kv: (::String name, **untyped opts) -> NATS::KeyValue
48
+ def kv: (::String name, ?allow_msg_ttl: bool, **untyped opts) -> untyped
37
49
 
38
50
  def close: -> void
51
+
52
+ private
53
+
54
+ def create_kv_with_msg_ttl: (::String name, **untyped opts) -> untyped
39
55
  end
40
56
  end
data/sig/cosmo/config.rbs CHANGED
@@ -1,17 +1,14 @@
1
1
  module Cosmo
2
- class Config
2
+ class Config < ::Hash[Symbol, untyped]
3
3
  NANO: Integer
4
4
  DEFAULT_PATH: ::String
5
5
 
6
6
  self.@instance: Config
7
- self.@system: Hash[Symbol, untyped]
8
- @config: Hash[Symbol, untyped]?
9
- @system: Hash[Symbol, untyped]
10
- @defaults: Hash[Symbol, untyped]
7
+ self.@internal: Hash[Symbol, untyped]
11
8
 
12
9
  def self.instance: () -> Config
13
10
 
14
- def self.system: () -> Hash[Symbol, untyped]
11
+ def self.internal: () -> Hash[Symbol, untyped]
15
12
 
16
13
  def self.parse_file: (::String path) -> Hash[Symbol, untyped]
17
14
 
@@ -31,15 +28,6 @@ module Cosmo
31
28
 
32
29
  def self.load: (?::String? path) -> void
33
30
 
34
- def initialize: () -> void
35
-
36
- def []: (Symbol key) -> untyped
37
-
38
- def fetch: (Symbol key, ?untyped default) -> untyped
39
-
40
- def dig: (*Symbol keys) -> untyped
41
-
42
- def to_h: () -> Hash[Symbol, untyped]
43
31
 
44
32
  def set: (*untyped) -> untyped
45
33
 
@@ -1,7 +1,7 @@
1
1
  module Cosmo
2
2
  module Job
3
3
  class Data
4
- DEFAULTS: { stream: Symbol, retry: Integer | bool, dead: bool }
4
+ DEFAULTS: { stream: Symbol, retry: Integer, dead: bool, limit: nil }
5
5
 
6
6
  @class_name: ::String
7
7
  @args: Array[untyped]
@@ -0,0 +1,18 @@
1
+ module Cosmo
2
+ module Job
3
+ class Limit
4
+ BUCKET: ::String
5
+
6
+ self.@instance: Limit
7
+
8
+ def self.instance: () -> Limit
9
+
10
+ def initialize: () -> void
11
+
12
+ def acquire: (::String key, jid: ::String, limit: ::Integer, duration: ::Integer) -> ::String?
13
+
14
+ def release: (::String slot) -> void
15
+ end
16
+ end
17
+ end
18
+
@@ -1,23 +1,33 @@
1
1
  module Cosmo
2
2
  module Job
3
3
  class Processor < ::Cosmo::Processor
4
- @weights: Array[Symbol]
4
+ private
5
5
 
6
- def initialize: (Utils::ThreadPool pool, untyped running, Hash[Symbol, untyped] options) -> void
6
+ def setup: () -> void
7
7
 
8
- private
8
+ def schedule_loop: () -> void
9
9
 
10
- def run_loop: () -> void
10
+ def scheduler?: () -> bool
11
11
 
12
- def setup: () -> void
12
+ def consumers: () -> Array[untyped]
13
13
 
14
- def work_loop: () -> void
14
+ def fetch_subjects: (Hash[Symbol, untyped] config) -> untyped
15
15
 
16
- def schedule_loop: () -> void
16
+ def fetch_timeout: (Hash[Symbol, untyped] config) -> Float
17
+
18
+ def process: (Array[untyped] messages, untyped processor) -> void
19
+
20
+ def handle_failure: (untyped message, Hash[Symbol, untyped] data) -> bool
21
+
22
+ def subscribe: (Symbol stream_name, Hash[Symbol, untyped] config) -> [untyped, Hash[Symbol, untyped], nil]
23
+
24
+ def drop_message: (untyped message, Hash[Symbol, untyped] data) -> void
25
+
26
+ def move_message: (untyped message, ?Hash[Symbol, untyped]? data) -> void
17
27
 
18
- def process: (Array[untyped] messages) -> void
28
+ def with_stats: (untyped message) { () -> untyped } -> void
19
29
 
20
- def handle_failure: (untyped message, Hash[Symbol, untyped] data) -> void
30
+ def acquire_concurrency_slot: (untyped worker_class, untyped message, Hash[Symbol, untyped] data) -> (::String | false)
21
31
  end
22
32
  end
23
33
  end
data/sig/cosmo/job.rbs CHANGED
@@ -5,7 +5,14 @@ module Cosmo
5
5
  module ClassMethods
6
6
  @default_options: Hash[Symbol, untyped]
7
7
 
8
- def options: (?stream: Symbol?, ?retry: Integer?, ?dead: bool?) -> Hash[Symbol, untyped]
8
+ def options: (**untyped config) -> Hash[Symbol, untyped]
9
+ alias cosmo_options options
10
+
11
+ def concurrency_options: () -> { limit: Integer, key: Proc?, duration: Integer }?
12
+
13
+ def concurrency_key: (Array[untyped] args) -> ::String?
14
+
15
+ def limits_concurrency?: () -> bool
9
16
 
10
17
  def perform: (*untyped args, ?async: bool, **untyped options) -> (::String | nil)
11
18
 
@@ -24,9 +31,7 @@ module Cosmo
24
31
  def client: () -> Client
25
32
  end
26
33
 
27
- attr_reader jid: ::String
28
-
29
- def jid=: (::String) -> ::String
34
+ attr_accessor jid: ::String
30
35
 
31
36
  def perform: (*untyped) -> untyped
32
37
 
@@ -1,24 +1,46 @@
1
1
  module Cosmo
2
2
  class Processor
3
+ STREAM_PAUSED_RECHECK_TTL: Float
4
+ STREAMS_PAUSED_IDLE_SLEEP: Float
5
+ STREAM_EMPTY_BACKOFF_MAX: Float
6
+
3
7
  @pool: Utils::ThreadPool
4
8
  @running: untyped
5
9
  @consumers: Array[untyped]
10
+ @threads: Array[Thread]
11
+ @cache: Utils::TTLCache
6
12
  @options: Hash[Symbol, untyped]
13
+ @locks: Hash[::String, Mutex]
14
+ @consumer_state: untyped
7
15
 
8
16
  def self.run: (*untyped) -> Processor
9
17
 
18
+ attr_reader consumers: Array[untyped]
19
+
10
20
  def initialize: (Utils::ThreadPool pool, untyped running, Hash[Symbol, untyped] options) -> void
11
21
 
12
22
  def run: () -> void
13
23
 
24
+ def stop: (?::Integer | ::Float timeout) -> void
25
+
14
26
  private
15
27
 
16
28
  def run_loop: () -> void
17
29
 
30
+ def work_loop: () -> void
31
+
32
+ def schedule_loop: () -> void
33
+
34
+ def scheduler?: () -> bool
35
+
18
36
  def setup: () -> void
19
37
 
20
38
  def process: (*untyped) -> void
21
39
 
40
+ def fetch_timeout: (Hash[Symbol, untyped] config) -> Float
41
+
42
+ def fetch_subjects: (Hash[Symbol, untyped] config) -> untyped
43
+
22
44
  def running?: () -> bool
23
45
 
24
46
  def fetch: (untyped subscription, batch_size: Integer, timeout: Float) ?{ (Array[untyped]) -> void } -> void
@@ -26,5 +48,9 @@ module Cosmo
26
48
  def client: () -> Client
27
49
 
28
50
  def stopwatch: () -> Utils::Stopwatch
51
+
52
+ def lock: (::String stream_name) { () -> void } -> void
53
+
54
+ def consumer_state: () -> untyped
29
55
  end
30
56
  end
@@ -0,0 +1,4 @@
1
+ module Cosmo
2
+ class Railtie < ::Rails::Railtie
3
+ end
4
+ end
@@ -3,27 +3,21 @@ module Cosmo
3
3
  class Processor < ::Cosmo::Processor
4
4
  @configs: Array[Hash[Symbol, untyped]]
5
5
 
6
- def initialize: (Utils::ThreadPool pool, untyped running, Hash[Symbol, untyped] options) -> void
7
-
8
6
  private
9
7
 
10
- def run_loop: () -> void
11
-
12
8
  def setup: () -> void
13
9
 
14
- def convert_timeout: (Numeric) -> Float
15
-
16
- def work_loop: () -> void
17
-
18
10
  def process: (Array[untyped] messages, untyped processor) -> void
19
11
 
20
- def setup_configs: () -> void
12
+ def fetch_subjects: (Hash[Symbol, untyped] config) -> untyped
21
13
 
22
- def setup_consumers: () -> void
14
+ def fetch_timeout: (Hash[Symbol, untyped] config) -> Float
23
15
 
24
16
  def static_config: -> Array[Hash[Symbol, untyped]]
25
17
 
26
18
  def dynamic_config: -> Array[Hash[Symbol, untyped]]
19
+
20
+ def subscribe: (Symbol? stream_name, Hash[Symbol, untyped] config) -> [untyped, Hash[Symbol, untyped], untyped]
27
21
  end
28
22
  end
29
23
  end
@@ -3,23 +3,19 @@ module Cosmo
3
3
  module Hash
4
4
  def self.symbolize_keys!: (untyped obj) -> (::Hash[Symbol, untyped] | Array[untyped] | untyped)
5
5
 
6
- def self.dup: [T] (T hash) -> T
6
+ def self.stringify_keys: (untyped obj) -> (::Hash[String, untyped] | Array[untyped] | untyped)
7
7
 
8
- def self.keys?: (::Hash[untyped, untyped] hash, *untyped keys) -> bool
8
+ def self.dup: [T] (T hash) -> T
9
9
 
10
10
  def self.set: (::Hash[untyped, untyped] hash, *untyped keys, value: untyped) -> untyped
11
11
 
12
- def self.merge: (::Hash[untyped, untyped] hash1, ::Hash[untyped, untyped]? hash2) -> ::Hash[untyped, untyped]
13
-
14
12
  def symbolize_keys!: (untyped obj) -> (::Hash[Symbol, untyped] | Array[untyped] | untyped)
15
13
 
16
- def dup: [T] (T hash) -> T
14
+ def stringify_keys: (untyped obj) -> (::Hash[String, untyped] | Array[untyped] | untyped)
17
15
 
18
- def keys?: (::Hash[untyped, untyped] hash, *untyped keys) -> bool
16
+ def dup: [T] (T hash) -> T
19
17
 
20
18
  def set: (::Hash[untyped, untyped] hash, *untyped keys, value: untyped) -> untyped
21
-
22
- def merge: (::Hash[untyped, untyped] hash1, ::Hash[untyped, untyped]? hash2) -> ::Hash[untyped, untyped]
23
19
  end
24
20
  end
25
21
  end