autoscale-agent 0.1.0 → 0.2.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: fc5fb7bd79bb436a7f36d9c95b3f27f8a1437cc269da86c275cc00b434784ed2
4
- data.tar.gz: 69057429ec9c74443d3b23a8fbe5ef2fd7b716fe414393d4e59eef5944b533d2
3
+ metadata.gz: 8eee5bfe7779587148bf96e20f474069cdc159921964a15c793032aacc1c5a8b
4
+ data.tar.gz: 31973d0ed5d7e483447d4eb8361ccb83491873832f0ed7a62d2eeaf34cd3cca8
5
5
  SHA512:
6
- metadata.gz: 5379183c0664bb43b528c11d229f607328a1ce99a88865f4da0d4e955751c083bed3b57884bc85b915ed902c877199c853cd112214661dcd58e6a6e86596f2a7
7
- data.tar.gz: 493b64a3a84714e14b840a24ccb0a3197c6f6d8adf17ca4802a49cd3692ec3448216a49047df321eba5b2e9b7e9148b3702378d1290817f53be55d2ae1ccd15f
6
+ metadata.gz: 7ec5e6defbb72526b04401ec95c9e548e5b7102e3d3df923ea25eac1b8d268bbb02d17ed03196e93c480401aed71ca1df7dcdb54b8f909ddb40301eb0fb93804
7
+ data.tar.gz: 2e18fe0276aa512f1446533990c4e083fa68874b5826d4ab0adec9245d0020cb7ba77a437692a3e088707278e02c53b0f2fccf397daf3aec3c62a0757413a393
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.0] - 2023-04-24
4
+
5
+ - Change when and where dispatchers are run
6
+
7
+ The WebDispatcher now runs in either the primary (sole) process, and
8
+ otherwise one in each forked (worker) process.
9
+
10
+ The WorkerDispatchers no longer automatically run
11
+ post-configuration. Instead, they must be manually started.
12
+
13
+ Note: WebDispatchers has been removed in favor of a single
14
+ WebDispatcher.
15
+
3
16
  ## [0.1.0] - 2023-03-03
4
17
 
5
18
  - Initial release
@@ -7,21 +7,8 @@ module Autoscale
7
7
 
8
8
  class InvalidPlatformError < StandardError; end
9
9
 
10
- class << self
11
- attr_writer :run
12
-
13
- def run?
14
- !defined?(@run) || @run == true
15
- end
16
- end
17
-
18
10
  def initialize(&block)
19
11
  instance_eval(&block)
20
-
21
- if Configuration.run?
22
- web_dispatchers.run
23
- worker_dispatchers.run
24
- end
25
12
  end
26
13
 
27
14
  def platform(value = nil)
@@ -32,9 +19,7 @@ module Autoscale
32
19
  end
33
20
  end
34
21
 
35
- def web_dispatchers
36
- @web_dispatchers ||= WebDispatchers.new
37
- end
22
+ attr_reader :web_dispatcher
38
23
 
39
24
  def worker_dispatchers
40
25
  @worker_dispatchers ||= WorkerDispatchers.new
@@ -60,7 +45,7 @@ module Autoscale
60
45
  private
61
46
 
62
47
  def dispatch_web(token)
63
- web_dispatchers.queue_time = WebDispatcher.new(token)
48
+ @web_dispatcher = WebDispatcher.new(token)
64
49
  end
65
50
 
66
51
  def dispatch_worker(token, &block)
@@ -28,12 +28,13 @@ module Autoscale
28
28
 
29
29
  def record_queue_time(env)
30
30
  return unless request_start_header(env)
31
- return unless (dispatcher = Autoscale::Agent.configuration.web_dispatchers.queue_time)
31
+ return unless (dispatcher = Autoscale::Agent.configuration.web_dispatcher)
32
32
  current_time = (Time.now.to_f * 1000).to_i
33
33
  request_start_time = to_ms(request_start_header(env))
34
34
  elapsed_ms = current_time - request_start_time
35
35
  elapsed = (elapsed_ms < 0) ? 0 : elapsed_ms
36
36
  dispatcher.add(elapsed)
37
+ dispatcher.run
37
38
  end
38
39
 
39
40
  def request_start_header(env)
@@ -1,5 +1,5 @@
1
1
  module Autoscale
2
2
  module Agent
3
- VERSION = "0.1.0".freeze
3
+ VERSION = "0.2.0".freeze
4
4
  end
5
5
  end
@@ -1,6 +1,7 @@
1
1
  module Autoscale
2
2
  module Agent
3
3
  class WebDispatcher
4
+ DISPATCH_INTERVAL = 15
4
5
  TTL = 30
5
6
 
6
7
  attr_reader :token
@@ -10,49 +11,68 @@ module Autoscale
10
11
  @token = token
11
12
  @buffer = {}
12
13
  @mutex = Mutex.new
14
+ @running = false
15
+ @running_lock = Mutex.new
13
16
  end
14
17
 
15
18
  def add(value, timestamp: Time.now.to_i)
16
19
  @mutex.synchronize do
17
- @buffer[timestamp] ||= 0
18
- @buffer[timestamp] = value if value > @buffer[timestamp]
19
- end
20
- end
21
-
22
- def prune
23
- @mutex.synchronize do
24
- max_age = Time.now.to_i - TTL
25
- @buffer.delete_if { |timestamp, _| timestamp < max_age }
20
+ add_unsafe(value, timestamp: timestamp)
26
21
  end
27
22
  end
28
23
 
29
24
  def dispatch
30
- return unless (payload = build_payload)
25
+ payload = flush
26
+
27
+ return if payload.empty?
31
28
 
32
29
  body = MultiJson.dump(payload)
33
30
  response = Request.dispatch(body, token: token)
34
31
 
35
32
  unless response.is_a?(Net::HTTPOK)
36
- revert_payload(payload)
33
+ revert(payload)
37
34
  error "Failed to dispatch (#{response.code}) #{response.body}"
38
35
  end
36
+ rescue => err
37
+ puts "Autoscale::Agent/WebDispatcher: #{err}\n#{err.backtrace.join("\n")}"
38
+ end
39
+
40
+ def run
41
+ @running_lock.synchronize do
42
+ return if @running
43
+ @running = true
44
+ end
45
+
46
+ Thread.new do
47
+ loop do
48
+ dispatch
49
+ sleep DISPATCH_INTERVAL
50
+ end
51
+ end
39
52
  end
40
53
 
41
54
  private
42
55
 
43
- def build_payload
56
+ def add_unsafe(value, timestamp: Time.now.to_i)
57
+ if timestamp > Time.now.to_i - TTL
58
+ @buffer[timestamp] ||= 0
59
+ @buffer[timestamp] = value if value > @buffer[timestamp]
60
+ end
61
+ end
62
+
63
+ def flush
44
64
  @mutex.synchronize do
45
- now = Time.now.to_i
46
- keys = @buffer.each_key.select { |key| key < now }
47
- payload = @buffer.slice(*keys)
48
- keys.each { |key| @buffer.delete(key) }
49
- payload if payload.any?
65
+ buffer = @buffer
66
+ @buffer = {}
67
+ buffer
50
68
  end
51
69
  end
52
70
 
53
- def revert_payload(payload)
54
- payload.each do |timestamp, value|
55
- add(value, timestamp: timestamp)
71
+ def revert(payload)
72
+ @mutex.synchronize do
73
+ payload.each do |timestamp, value|
74
+ add_unsafe(value, timestamp: timestamp)
75
+ end
56
76
  end
57
77
  end
58
78
 
@@ -7,6 +7,8 @@ module Autoscale
7
7
 
8
8
  def initialize
9
9
  @dispatchers = []
10
+ @running = false
11
+ @running_lock = Mutex.new
10
12
  end
11
13
 
12
14
  def each(&block)
@@ -26,6 +28,11 @@ module Autoscale
26
28
  end
27
29
 
28
30
  def run
31
+ @running_lock.synchronize do
32
+ return if @running
33
+ @running = true
34
+ end
35
+
29
36
  Thread.new do
30
37
  loop do
31
38
  dispatch
@@ -7,7 +7,6 @@ require_relative "agent/middleware"
7
7
  require_relative "agent/request"
8
8
  require_relative "agent/version"
9
9
  require_relative "agent/web_dispatcher"
10
- require_relative "agent/web_dispatchers"
11
10
  require_relative "agent/worker_dispatcher"
12
11
  require_relative "agent/worker_dispatchers"
13
12
  require_relative "agent/worker_server"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autoscale-agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael R. van Rooijen
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-03 00:00:00.000000000 Z
11
+ date: 2023-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json
@@ -24,7 +24,7 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1'
27
- description:
27
+ description:
28
28
  email:
29
29
  - support@autoscale.app
30
30
  executables: []
@@ -42,7 +42,6 @@ files:
42
42
  - lib/autoscale/agent/request.rb
43
43
  - lib/autoscale/agent/version.rb
44
44
  - lib/autoscale/agent/web_dispatcher.rb
45
- - lib/autoscale/agent/web_dispatchers.rb
46
45
  - lib/autoscale/agent/worker_dispatcher.rb
47
46
  - lib/autoscale/agent/worker_dispatchers.rb
48
47
  - lib/autoscale/agent/worker_server.rb
@@ -57,7 +56,7 @@ metadata:
57
56
  changelog_uri: https://github.com/autoscale-app/ruby-agent/blob/master/CHANGELOG.md
58
57
  bug_tracker_uri: https://github.com/autoscale-app/ruby-agent/issues
59
58
  rubygems_mfa_required: 'true'
60
- post_install_message:
59
+ post_install_message:
61
60
  rdoc_options: []
62
61
  require_paths:
63
62
  - lib
@@ -72,8 +71,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
71
  - !ruby/object:Gem::Version
73
72
  version: '0'
74
73
  requirements: []
75
- rubygems_version: 3.4.6
76
- signing_key:
74
+ rubygems_version: 3.4.10
75
+ signing_key:
77
76
  specification_version: 4
78
77
  summary: Provides Autoscale.app with the necessary metrics for autoscaling web and
79
78
  worker processes
@@ -1,47 +0,0 @@
1
- module Autoscale
2
- module Agent
3
- class WebDispatchers
4
- class AlreadySetError < StandardError
5
- end
6
-
7
- include Enumerable
8
-
9
- DISPATCH_INTERVAL = 15
10
-
11
- attr_reader :queue_time
12
-
13
- def initialize
14
- @dispatchers = []
15
- end
16
-
17
- def queue_time=(dispatcher)
18
- raise AlreadySetError if defined?(@queue_time)
19
- @dispatchers << (@queue_time = dispatcher)
20
- end
21
-
22
- def each(&block)
23
- @dispatchers.each(&block)
24
- end
25
-
26
- def prune
27
- each(&:prune)
28
- end
29
-
30
- def dispatch
31
- each(&:dispatch)
32
- rescue => err
33
- puts "Autoscale::Agent/WebDispatcher: #{err}\n#{err.backtrace.join("\n")}"
34
- end
35
-
36
- def run
37
- Thread.new do
38
- loop do
39
- prune
40
- dispatch
41
- sleep DISPATCH_INTERVAL
42
- end
43
- end
44
- end
45
- end
46
- end
47
- end