cosmonats 0.6.0 → 0.7.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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +21 -169
  3. data/README.md +101 -17
  4. data/lib/cosmo/api/counter.rb +14 -11
  5. data/lib/cosmo/api/cron/entry.rb +23 -3
  6. data/lib/cosmo/api/cron.rb +22 -26
  7. data/lib/cosmo/api/job.rb +30 -0
  8. data/lib/cosmo/api/kv.rb +31 -11
  9. data/lib/cosmo/api/registry.rb +68 -0
  10. data/lib/cosmo/api/stats/busy.rb +63 -0
  11. data/lib/cosmo/api/stats/processes.rb +37 -0
  12. data/lib/cosmo/api/stats/totals.rb +35 -0
  13. data/lib/cosmo/api/stats.rb +5 -4
  14. data/lib/cosmo/api/stream.rb +1 -1
  15. data/lib/cosmo/api.rb +3 -2
  16. data/lib/cosmo/batch.rb +9 -2
  17. data/lib/cosmo/cli.rb +27 -7
  18. data/lib/cosmo/client.rb +33 -5
  19. data/lib/cosmo/config.rb +6 -2
  20. data/lib/cosmo/engine.rb +103 -4
  21. data/lib/cosmo/heartbeat.rb +129 -0
  22. data/lib/cosmo/http_server/handler.rb +44 -0
  23. data/lib/cosmo/http_server/health.rb +39 -0
  24. data/lib/cosmo/http_server/ping.rb +23 -0
  25. data/lib/cosmo/http_server.rb +62 -0
  26. data/lib/cosmo/job/failure.rb +52 -0
  27. data/lib/cosmo/job/processor.rb +87 -25
  28. data/lib/cosmo/job/stream_filter.rb +54 -0
  29. data/lib/cosmo/job.rb +2 -0
  30. data/lib/cosmo/processor.rb +39 -4
  31. data/lib/cosmo/sentry/job_processor_middleware.rb +1 -2
  32. data/lib/cosmo/stream/message.rb +2 -1
  33. data/lib/cosmo/stream/processor.rb +5 -0
  34. data/lib/cosmo/utils/json.rb +1 -1
  35. data/lib/cosmo/utils/overrides.rb +16 -10
  36. data/lib/cosmo/utils/thread_pool.rb +5 -0
  37. data/lib/cosmo/version.rb +1 -1
  38. data/lib/cosmo/web/assets/app.css +21 -0
  39. data/lib/cosmo/web/controllers/jobs.rb +28 -4
  40. data/lib/cosmo/web/helpers/application.rb +10 -1
  41. data/lib/cosmo/web/views/batches/index.erb +1 -1
  42. data/lib/cosmo/web/views/jobs/_busy.erb +70 -4
  43. data/lib/cosmo/web/views/jobs/_dead.erb +29 -16
  44. data/lib/cosmo/web/views/jobs/_enqueued.erb +10 -0
  45. data/lib/cosmo/web/views/jobs/_processes.erb +131 -0
  46. data/lib/cosmo/web/views/jobs/_scheduled.erb +1 -1
  47. data/lib/cosmo/web/views/jobs/busy.erb +1 -1
  48. data/lib/cosmo/web/views/jobs/dead.erb +2 -2
  49. data/lib/cosmo/web/views/jobs/enqueued.erb +1 -1
  50. data/lib/cosmo/web/views/jobs/index.erb +7 -1
  51. data/lib/cosmo/web/views/jobs/scheduled.erb +1 -1
  52. data/lib/cosmo/web/views/streams/index.erb +1 -1
  53. data/lib/cosmo/web.rb +2 -0
  54. data/lib/cosmo.rb +13 -0
  55. data/sig/cosmo/api/counter.rbs +2 -4
  56. data/sig/cosmo/api/cron/entry.rbs +2 -0
  57. data/sig/cosmo/api/cron.rbs +4 -2
  58. data/sig/cosmo/api/job.rbs +12 -0
  59. data/sig/cosmo/api/kv.rbs +7 -1
  60. data/sig/cosmo/api/registry.rbs +30 -0
  61. data/sig/cosmo/api/stats/busy.rbs +31 -0
  62. data/sig/cosmo/api/stats/processes.rbs +16 -0
  63. data/sig/cosmo/api/stats/totals.rbs +17 -0
  64. data/sig/cosmo/cli.rbs +4 -0
  65. data/sig/cosmo/client.rbs +12 -1
  66. data/sig/cosmo/engine.rbs +29 -0
  67. data/sig/cosmo/heartbeat.rbs +36 -0
  68. data/sig/cosmo/http_server/handler.rbs +17 -0
  69. data/sig/cosmo/http_server/health.rbs +21 -0
  70. data/sig/cosmo/http_server/ping.rbs +14 -0
  71. data/sig/cosmo/http_server.rbs +22 -0
  72. data/sig/cosmo/job/failure.rbs +28 -0
  73. data/sig/cosmo/job/processor.rbs +17 -1
  74. data/sig/cosmo/job/stream_filter.rbs +25 -0
  75. data/sig/cosmo/processor.rbs +12 -1
  76. data/sig/cosmo/stream/message.rbs +3 -1
  77. data/sig/cosmo/stream/processor.rbs +2 -0
  78. data/sig/cosmo/utils/thread_pool.rbs +3 -0
  79. data/sig/cosmo.rbs +4 -0
  80. metadata +33 -20
  81. data/lib/cosmo/api/busy.rb +0 -66
  82. data/sig/cosmo/api/busy.rbs +0 -35
@@ -0,0 +1,131 @@
1
+ <% nav = @polling ? { limit: @limit } : { limit: @limit, poll: 0 } -%>
2
+ <% states = { "running" => "badge-success", "quiet" => "badge-warning", "stopping" => "badge-danger" } -%>
3
+ <div id="processes-poller"
4
+ <% if @polling -%>
5
+ hx-get="<%= url_for('/jobs/_processes', page: @page, limit: @limit) %>"
6
+ hx-trigger="every <%= poll_interval %>s"
7
+ hx-swap="outerHTML"
8
+ <% end -%>
9
+ >
10
+ <div class="pending">
11
+ <span></span>
12
+ <span class="poll-status">
13
+ <span class="text-muted"><%= @total %> process(es) alive</span>
14
+ <% if @polling -%>
15
+ <a class="btn btn-sm"
16
+ hx-get="<%= url_for('/jobs/_processes', nav.merge(page: @page, poll: 0)) %>"
17
+ hx-target="#processes-poller"
18
+ hx-swap="outerHTML"
19
+ hx-indicator="#global-spinner">&#9209; Stop Polling</a>
20
+ <% else -%>
21
+ <a class="btn btn-sm btn-primary"
22
+ hx-get="<%= url_for('/jobs/_processes', page: @page, limit: @limit) %>"
23
+ hx-target="#processes-poller"
24
+ hx-swap="outerHTML"
25
+ hx-indicator="#global-spinner">&#x25B6; Live Poll</a>
26
+ <% end -%>
27
+ </span>
28
+ </div>
29
+
30
+ <% if @processes.empty? -%>
31
+ <div class="alert alert-warning">No worker processes are running</div>
32
+ <% else -%>
33
+ <div class="table-container">
34
+ <table>
35
+ <thead>
36
+ <tr>
37
+ <th>Process</th>
38
+ <th>Command</th>
39
+ <th>Subscriptions</th>
40
+ <th>Busy</th>
41
+ <th>State</th>
42
+ <th>RTT</th>
43
+ <th>Reconnects</th>
44
+ <th>Memory</th>
45
+ <th>Uptime</th>
46
+ <th>Last beat</th>
47
+ </tr>
48
+ </thead>
49
+ <tbody>
50
+ <% @processes.each do |process| -%>
51
+ <% nats = Hash(process[:nats]) -%>
52
+ <tr>
53
+ <td>
54
+ <div class="job-class"><%= h(process[:hostname]) %>:<%= h(process[:pid]) %></div>
55
+ <div class="text-muted" style="font-size: var(--font-size-small);">
56
+ <%= h(nats[:ip] || "unknown IP") %>
57
+ <% if nats[:name] -%>&middot; <code><%= h(nats[:name]) %></code><% end -%>
58
+ </div>
59
+ </td>
60
+ <td>
61
+ <% cmdline = process[:cmdline].to_s -%>
62
+ <div class="job-id">
63
+ <details>
64
+ <summary>
65
+ <code><%= h(cmdline.length > 40 ? "#{cmdline[0, 40]}…" : cmdline) %></code>
66
+ </summary>
67
+ <code style="font-size: var(--font-size-small);"><%= h(cmdline) %></code>
68
+ <div class="text-muted" style="font-size: var(--font-size-small);">
69
+ cosmo <%= h(process[:version]) %> &middot; <%= h(process[:ruby]) %>
70
+ <% if process[:http_port] -%>&middot; http :<%= h(process[:http_port]) %><% end -%>
71
+ </div>
72
+ </details>
73
+ </div>
74
+ </td>
75
+ <td>
76
+ <% Hash(process[:subscriptions]).each do |type, names| -%>
77
+ <div><span class="text-muted"><%= h(type) %>:</span> <code><%= h(Array(names).join(", ")) %></code></div>
78
+ <% end -%>
79
+ </td>
80
+ <td><%= h(process[:busy]) %> / <%= h(process[:concurrency]) %></td>
81
+ <td><span class="badge <%= states.fetch(process[:state].to_s, 'badge-info') %>"><%= h(process[:state]) %></span></td>
82
+ <td><%= nats[:rtt] ? "#{h(nats[:rtt])}ms" : '&mdash;' %></td>
83
+ <td><%= h(nats[:reconnects].to_i) %></td>
84
+ <td><%= process[:rss] ? format_bytes(process[:rss].to_i * 1024) : '&mdash;' %></td>
85
+ <td><%= elapsed(process[:started_at]) %></td>
86
+ <td><%= elapsed(process[:beat_at]) %> ago</td>
87
+ </tr>
88
+ <% end -%>
89
+ </tbody>
90
+ </table>
91
+ </div>
92
+ <% end -%>
93
+
94
+ <% if @total_pages.to_i > 1 -%>
95
+ <div class="pagination">
96
+ <% if @page > 1 -%>
97
+ <a hx-get="<%= url_for('/jobs/_processes', nav.merge(page: @page - 1)) %>"
98
+ hx-target="#processes-poller"
99
+ hx-swap="outerHTML"
100
+ hx-indicator="#global-spinner"
101
+ class="btn">&#x2190; Prev</a>
102
+ <% else -%>
103
+ <span class="btn btn-disabled">&#x2190; Prev</span>
104
+ <% end -%>
105
+
106
+ <% pages(@page, @total_pages).each do |p| -%>
107
+ <% if p == :gap -%>
108
+ <span class="pagination-gap">&hellip;</span>
109
+ <% elsif p == @page -%>
110
+ <span class="btn btn-primary btn-disabled"><%= p %></span>
111
+ <% else -%>
112
+ <a hx-get="<%= url_for('/jobs/_processes', nav.merge(page: p)) %>"
113
+ hx-target="#processes-poller"
114
+ hx-swap="outerHTML"
115
+ hx-indicator="#global-spinner"
116
+ class="btn"><%= p %></a>
117
+ <% end -%>
118
+ <% end -%>
119
+
120
+ <% if @page < @total_pages -%>
121
+ <a hx-get="<%= url_for('/jobs/_processes', nav.merge(page: @page + 1)) %>"
122
+ hx-target="#processes-poller"
123
+ hx-swap="outerHTML"
124
+ hx-indicator="#global-spinner"
125
+ class="btn">Next &#x2192;</a>
126
+ <% else -%>
127
+ <span class="btn btn-disabled">Next &#x2192;</span>
128
+ <% end -%>
129
+ </div>
130
+ <% end -%>
131
+ </div>
@@ -1,6 +1,6 @@
1
1
  <div id="scheduled-poller"
2
2
  hx-get="<%= url_for('/jobs/_scheduled') %>"
3
- hx-trigger="every 5s"
3
+ hx-trigger="every <%= poll_interval %>s"
4
4
  hx-swap="outerHTML">
5
5
  <div class="pending">
6
6
  <span></span>
@@ -2,7 +2,7 @@
2
2
  <header><%= render('jobs/_tabs') %></header>
3
3
 
4
4
  <div hx-get="<%= url_for('/jobs/_stats') %>"
5
- hx-trigger="load, every 5s"
5
+ hx-trigger="load, every <%= poll_interval %>s"
6
6
  hx-swap="innerHTML">
7
7
  <div class="alert alert-info">Loading statistics…</div>
8
8
  </div>
@@ -2,13 +2,13 @@
2
2
  <header><%= render('jobs/_tabs') %></header>
3
3
 
4
4
  <div hx-get="<%= url_for('/jobs/_stats') %>"
5
- hx-trigger="load, every 5s"
5
+ hx-trigger="load, every <%= poll_interval %>s"
6
6
  hx-swap="innerHTML">
7
7
  <div class="alert alert-info">Loading statistics…</div>
8
8
  </div>
9
9
 
10
10
  <div id="content">
11
- <div id="dead-poller"
11
+ <div id="dead-jobs"
12
12
  hx-get="<%= url_for('/jobs/_dead') %>"
13
13
  hx-trigger="load"
14
14
  hx-swap="outerHTML">
@@ -2,7 +2,7 @@
2
2
  <header><%= render('jobs/_tabs') %></header>
3
3
 
4
4
  <div hx-get="<%= url_for('/jobs/_stats') %>"
5
- hx-trigger="load, every 5s"
5
+ hx-trigger="load, every <%= poll_interval %>s"
6
6
  hx-swap="innerHTML">
7
7
  <div class="alert alert-info">Loading statistics…</div>
8
8
  </div>
@@ -2,11 +2,17 @@
2
2
  <header><%= render('jobs/_tabs') %></header>
3
3
 
4
4
  <div hx-get="<%= url_for('/jobs/_stats') %>"
5
- hx-trigger="load, every 5s"
5
+ hx-trigger="load, every <%= poll_interval %>s"
6
6
  hx-swap="innerHTML">
7
7
  <div class="alert alert-info">Loading statistics…</div>
8
8
  </div>
9
9
 
10
10
  <div id="content">
11
+ <div id="processes-poller"
12
+ hx-get="<%= url_for('/jobs/_processes') %>"
13
+ hx-trigger="load"
14
+ hx-swap="outerHTML">
15
+ <div class="alert alert-info">Loading processes&hellip;</div>
16
+ </div>
11
17
  </div>
12
18
  </section>
@@ -2,7 +2,7 @@
2
2
  <header><%= render('jobs/_tabs') %></header>
3
3
 
4
4
  <div hx-get="<%= url_for('/jobs/_stats') %>"
5
- hx-trigger="load, every 5s"
5
+ hx-trigger="load, every <%= poll_interval %>s"
6
6
  hx-swap="innerHTML">
7
7
  <div class="alert alert-info">Loading statistics…</div>
8
8
  </div>
@@ -3,7 +3,7 @@
3
3
 
4
4
  <div id="content">
5
5
  <div hx-get="<%= url_for('/streams/_table') %>"
6
- hx-trigger="load, every 5s"
6
+ hx-trigger="load, every <%= poll_interval %>s"
7
7
  hx-swap="innerHTML">
8
8
  <div class="alert alert-info">Loading streams…</div>
9
9
  </div>
data/lib/cosmo/web.rb CHANGED
@@ -34,10 +34,12 @@ module Cosmo
34
34
  in [:get, "/jobs/enqueued"] then [Controllers::Jobs, :enqueued]
35
35
  in [:patch, %r{/jobs/retry/\d+}] then [Controllers::Jobs, :retry]
36
36
  in [:delete, %r{/jobs/delete/\d+}] then [Controllers::Jobs, :delete]
37
+ in [:delete, %r{/jobs/enqueued/\d+}] then [Controllers::Jobs, :delete_enqueued]
37
38
  in [:get, "/jobs/_stats"] then [Controllers::Jobs, :_stats]
38
39
  in [:get, "/jobs/_scheduled"] then [Controllers::Jobs, :_scheduled]
39
40
  in [:get, "/jobs/_dead"] then [Controllers::Jobs, :_dead]
40
41
  in [:get, "/jobs/_busy"] then [Controllers::Jobs, :_busy]
42
+ in [:get, "/jobs/_processes"] then [Controllers::Jobs, :_processes]
41
43
  in [:get, "/jobs/_enqueued"] then [Controllers::Jobs, :_enqueued]
42
44
  in [:get, "/streams"] then [Controllers::Streams, :index]
43
45
  in [:get, "/streams/info"] then [Controllers::Streams, :info]
data/lib/cosmo.rb CHANGED
@@ -11,11 +11,17 @@ require "cosmo/job"
11
11
  require "cosmo/batch"
12
12
  require "cosmo/stream"
13
13
  require "cosmo/cli"
14
+ require "cosmo/heartbeat"
14
15
  require "cosmo/engine"
15
16
  require "cosmo/api"
16
17
  require "cosmo/railtie" if defined?(Rails::Railtie)
17
18
 
18
19
  module Cosmo
20
+ # Optional, requires rack
21
+ autoload :Web, "cosmo/web"
22
+ # Optional, requires rack and webrick gems. Loaded only when an HTTP port is configured.
23
+ autoload :HTTPServer, "cosmo/http_server"
24
+
19
25
  class Error < StandardError; end
20
26
 
21
27
  class ArgumentError < Error; end
@@ -33,4 +39,11 @@ module Cosmo
33
39
  super("Missing stream `#{stream_name}`")
34
40
  end
35
41
  end
42
+
43
+ class UnknownJobStreamError < Error
44
+ def initialize(names, configured)
45
+ super("Unknown job stream#{"s" if names.size > 1} #{names.map { "`#{_1}`" }.join(", ")}; " \
46
+ "configured: #{configured.empty? ? "none" : configured.map { "`#{_1}`" }.join(", ")}")
47
+ end
48
+ end
36
49
  end
@@ -2,16 +2,14 @@ module Cosmo
2
2
  module API
3
3
  class Counter
4
4
  STREAM_NAME: ::String
5
+ STREAM_CONFIG: Hash[Symbol, untyped]
5
6
 
6
- self.@instance: Counter
7
7
  @namespace: ::String
8
8
 
9
- def self.instance: () -> Counter
9
+ def self.setup!: () -> void
10
10
 
11
11
  def initialize: (::String namespace) -> void
12
12
 
13
- def with: () { () -> bool } -> void
14
-
15
13
  def increment: (Symbol key, ?by: ::Integer) -> ::Integer
16
14
  alias incr increment
17
15
 
@@ -18,6 +18,8 @@ module Cosmo
18
18
 
19
19
  def schedule_subject: () -> ::String
20
20
  def target_subject: () -> ::String
21
+ def dispatch_subject: () -> ::String
22
+ def schedule_headers: () -> Hash[::String, ::String]
21
23
  def job_name: () -> ::String
22
24
  def job_payload: () -> ::String
23
25
  def as_json: () -> Hash[Symbol, untyped]
@@ -1,6 +1,8 @@
1
1
  module Cosmo
2
2
  module API
3
3
  class Cron
4
+ STREAM: ::String
5
+
4
6
  def all: () -> ::Array[Hash[Symbol, untyped]]
5
7
 
6
8
  def upsert!: (?Cosmo::API::Cron::Entry schedule_obj,
@@ -17,8 +19,8 @@ module Cosmo
17
19
 
18
20
  private
19
21
 
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 schedules: () -> ::Array[Hash[Symbol, untyped]]
23
+ def build_from_nats: (::String subject) -> Hash[Symbol, untyped]?
22
24
  def name_from_subject: (::String subject) -> ::String?
23
25
  end
24
26
  end
@@ -23,9 +23,21 @@ module Cosmo
23
23
 
24
24
  def subject: () -> ::String
25
25
 
26
+ def error_class: () -> ::String?
27
+
28
+ def error_message: () -> ::String?
29
+
30
+ def error_backtrace: () -> ::String?
31
+
32
+ def error_backtrace_lines: () -> Array[::String]
33
+
34
+ def error?: () -> bool
35
+
26
36
  def stream: () -> ::String
27
37
 
28
38
  def timestamp: () -> ::String?
39
+
40
+ def stored_at: () -> ::Time?
29
41
  end
30
42
  end
31
43
  end
data/sig/cosmo/api/kv.rbs CHANGED
@@ -1,6 +1,8 @@
1
1
  module Cosmo
2
2
  module API
3
3
  class KV
4
+ LIMIT: ::Integer
5
+
4
6
  @name: ::String
5
7
  @options: Hash[Symbol, untyped]
6
8
  @kv: untyped
@@ -15,7 +17,9 @@ module Cosmo
15
17
 
16
18
  def delete: (::String | ::Integer key) -> untyped
17
19
 
18
- def keys: (?::String? subject, ?limit: ::Integer) -> Array[::String]
20
+ def keys: (?::String? subject, ?limit: ::Integer?, ?offset: ::Integer) -> Array[::String]
21
+
22
+ def entries: (?::String? subject, ?limit: ::Integer?, ?offset: ::Integer) -> Array[[::String, ::String]]
19
23
 
20
24
  def purge: (::String | ::Integer key) -> untyped
21
25
 
@@ -28,6 +32,8 @@ module Cosmo
28
32
 
29
33
  private
30
34
 
35
+ def walk: (::String? subject, limit: ::Integer?, offset: ::Integer, meta_only: bool) -> Array[[::String, ::String]]
36
+
31
37
  def publish_cas: (::String | ::Integer key, ::String value, ::Integer? ttl, last_seq: ::Integer) -> untyped
32
38
 
33
39
  def client: () -> Client
@@ -0,0 +1,30 @@
1
+ module Cosmo
2
+ module API
3
+ class Registry
4
+ LIMIT: ::Integer
5
+
6
+ self.@instance: Registry
7
+ @kv: KV
8
+
9
+ def self.instance: () -> instance
10
+
11
+ def initialize: () -> void
12
+
13
+ def put: (::String | ::Integer key, Hash[Symbol, untyped] value) -> void
14
+
15
+ def remove: (::String | ::Integer key) -> void
16
+
17
+ def list: (?page: ::Integer?, ?limit: ::Integer) -> Array[Hash[Symbol, untyped]]
18
+
19
+ def all: () -> Array[Hash[Symbol, untyped]]
20
+
21
+ def size: () -> ::Integer
22
+
23
+ private
24
+
25
+ def bucket: () -> KV
26
+
27
+ def sanitize: (::String | ::Integer key) -> ::String
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ module Cosmo
2
+ module API
3
+ module Stats
4
+ class Busy < Registry
5
+ TTL: ::Integer
6
+ HEARTBEAT: ::Integer
7
+ BUCKET: ::String
8
+
9
+ @messages: Hash[::Integer, Hash[Symbol, untyped]]
10
+ @thread: Thread?
11
+ @worker_id: ::String
12
+
13
+ def initialize: () -> void
14
+
15
+ def with: (untyped message) { () -> void } -> void
16
+
17
+ def add: (untyped message) -> void
18
+
19
+ def delete: (untyped message) -> void
20
+
21
+ def list: (?page: ::Integer?, ?limit: ::Integer) -> Array[Hash[Symbol, untyped]]
22
+
23
+ private
24
+
25
+ def heartbeat_loop: () -> void
26
+
27
+ def worker_id: () -> ::String
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,16 @@
1
+ module Cosmo
2
+ module API
3
+ module Stats
4
+ class Processes < Registry
5
+ TTL: ::Integer
6
+ BUCKET: ::String
7
+
8
+ def list: (?page: ::Integer?, ?limit: ::Integer) -> Array[Hash[Symbol, untyped]]
9
+
10
+ def register: (::String identity, Hash[Symbol, untyped] info) -> void
11
+
12
+ def unregister: (::String identity) -> void
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module Cosmo
2
+ module API
3
+ module Stats
4
+ class Totals < Counter
5
+ self.@instance: Totals
6
+
7
+ def self.instance: () -> Totals
8
+
9
+ def with: () { () -> bool } -> void
10
+
11
+ def processed: () -> ::Integer
12
+
13
+ def failed: () -> ::Integer
14
+ end
15
+ end
16
+ end
17
+ end
data/sig/cosmo/cli.rbs CHANGED
@@ -8,6 +8,10 @@ module Cosmo
8
8
 
9
9
  def self.banner: () -> ::String
10
10
 
11
+ @argv: Array[::String]?
12
+
13
+ attr_reader argv: Array[::String]?
14
+
11
15
  def run: () -> void
12
16
 
13
17
  private
data/sig/cosmo/client.rbs CHANGED
@@ -1,15 +1,26 @@
1
1
  module Cosmo
2
2
  class Client
3
+ JS_TIMEOUT: ::Integer
4
+ CONNECT_TIMEOUT: ::Integer
5
+
6
+ attr_reader name: ::String
7
+
8
+ def self.default_name: () -> ::String
9
+ def self.js_timeout: () -> ::Integer
10
+ def self.connect_timeout: () -> ::Integer
11
+ def self.program_name: () -> ::String
12
+
3
13
  self.@instance: Client
4
14
  @nc: untyped
5
15
  @js: untyped
16
+ @name: ::String
6
17
 
7
18
  def self.instance: () -> Client
8
19
 
9
20
  attr_reader nc: untyped
10
21
  attr_reader js: untyped
11
22
 
12
- def initialize: (?nats_url: ::String) -> void
23
+ def initialize: (?nats_url: ::String, ?name: ::String) -> void
13
24
 
14
25
  def publish: (::String subject, ::String payload, **untyped params) -> untyped
15
26
 
data/sig/cosmo/engine.rbs CHANGED
@@ -6,16 +6,45 @@ module Cosmo
6
6
  @concurrency: Integer
7
7
  @pool: Utils::ThreadPool
8
8
  @running: untyped
9
+ @quiet: untyped
9
10
  @processors: Array[Processor]
11
+ @http_server: HTTPServer?
12
+ @heartbeat: Heartbeat?
10
13
 
11
14
  def self.run: (*untyped) -> void
12
15
 
16
+ def self.processors_for: ((::String | Symbol)? type) -> Array[Class]
17
+
13
18
  def self.instance: () -> Engine
14
19
 
20
+ attr_reader concurrency: Integer
21
+
15
22
  def initialize: () -> void
16
23
 
17
24
  def run: (::String? type, Hash[Symbol, untyped] options) -> void
18
25
 
26
+ def running?: () -> bool
27
+
28
+ def state: () -> ::String
29
+
30
+ def busy: () -> Integer
31
+
32
+ def subscriptions: () -> Hash[Symbol, Array[::String]]
33
+
19
34
  def shutdown: () -> void
35
+
36
+ private
37
+
38
+ def start_http_server: () -> void
39
+
40
+ def handle_shutdown: (Utils::Signal handler) -> Symbol
41
+
42
+ def quiet: () -> void
43
+
44
+ def unquiet: () -> void
45
+
46
+ def drain_and_exit: (Utils::Signal handler) -> void
47
+
48
+ def dump_threads: () -> void
20
49
  end
21
50
  end
@@ -0,0 +1,36 @@
1
+ module Cosmo
2
+ class Heartbeat
3
+ INTERVAL: ::Integer
4
+
5
+ @engine: Engine
6
+ @options: Hash[Symbol, untyped]
7
+ @started_at: ::Integer
8
+ @thread: Thread?
9
+ @identity: ::String
10
+ @static_info: Hash[Symbol, untyped]
11
+
12
+ def initialize: (Engine engine, ?options: Hash[Symbol, untyped]) -> void
13
+
14
+ def start: () -> self
15
+
16
+ def stop: () -> void
17
+
18
+ def beat: () -> void
19
+
20
+ def identity: () -> ::String
21
+
22
+ def info: () -> Hash[Symbol, untyped]
23
+
24
+ private
25
+
26
+ def static_info: () -> Hash[Symbol, untyped]
27
+
28
+ def nats_info: () -> Hash[Symbol, untyped]
29
+
30
+ def rtt: (untyped connection) -> ::Float?
31
+
32
+ def rss: () -> ::Integer?
33
+
34
+ def processes: () -> API::Stats::Processes
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ module Cosmo
2
+ class HTTPServer
3
+ class Handler < ::WEBrick::HTTPServlet::AbstractServlet
4
+ @app: untyped
5
+
6
+ def initialize: (untyped server, untyped app) -> void
7
+
8
+ def service: (untyped req, untyped res) -> void
9
+
10
+ private
11
+
12
+ def env_for: (untyped req) -> Hash[String, untyped]
13
+
14
+ def write_headers: (untyped res, Hash[String, untyped] headers) -> void
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module Cosmo
2
+ class HTTPServer
3
+ class Health
4
+ PATH: String
5
+ HEADERS: Hash[String, String]
6
+
7
+ @app: untyped
8
+ @check: ^() -> Hash[Symbol, bool]
9
+
10
+ def initialize: (untyped app, ?check: (^() -> Hash[Symbol, bool])?) -> void
11
+
12
+ def call: (Hash[String, untyped] env) -> [Integer, Hash[String, String], Array[String]]
13
+
14
+ private
15
+
16
+ def default_check: () -> Hash[Symbol, bool]
17
+
18
+ def nats_connected?: () -> bool
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ module Cosmo
2
+ class HTTPServer
3
+ class Ping
4
+ PATH: String
5
+ HEADERS: Hash[String, String]
6
+
7
+ @app: untyped
8
+
9
+ def initialize: (untyped app) -> void
10
+
11
+ def call: (Hash[String, untyped] env) -> [Integer, Hash[String, String], Array[String]]
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ module Cosmo
2
+ class HTTPServer
3
+ DEFAULT_HOST: String
4
+ NOT_FOUND: [Integer, Hash[String, String], Array[String]]
5
+
6
+ @app: untyped
7
+ @host: String
8
+ @port: Integer
9
+ @server: untyped
10
+ @thread: Thread?
11
+
12
+ def self.app: () -> untyped
13
+
14
+ def initialize: (?untyped app, port: Integer, ?host: String) -> void
15
+
16
+ def start: () -> self
17
+
18
+ def stop: () -> void
19
+
20
+ def port: () -> Integer
21
+ end
22
+ end