galactic-senate 0.1.0.4

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0bd70552807ba6a4a396837418ef7aaf5c32ee7b
4
+ data.tar.gz: 4eae80ac0b97aa27108b690c686789698bbab5c5
5
+ SHA512:
6
+ metadata.gz: 3d7df3130c4b825c83b9e2bb08726059d35419499bbc670464ddb3e5506382125a1de604b2d9656df84e114c71253d913d18bf7f554c7af0bae72d9ad782ce7c
7
+ data.tar.gz: 25a0a75e36535949ee936a36ec79350911ab01e7acbdf3111af0c681c59d2c7c635dc1af479ca2453e8af75c6690223f05131246138dd94c9fda37c4c3a7a016
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "galactic-senate/version"
4
+ require "galactic-senate/configuration"
5
+ require "galactic-senate/delegation"
6
+
7
+ module GalacticSenate
8
+ class << self
9
+ attr_accessor :config, :whoami
10
+ end
11
+
12
+ def self.config
13
+ @config ||= GalacticSenate::Configuration.new
14
+ end
15
+
16
+ def self.reset
17
+ @config = GalacticSenate::Configuration.new
18
+ end
19
+
20
+ def self.configure
21
+ yield(config)
22
+ end
23
+
24
+ def self.whoami
25
+ @whoami ||= "#{Socket.gethostname}:#{$$}:#{SecureRandom.hex(3)}"
26
+ end
27
+ end
28
+
29
+
30
+
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GalacticSenate
4
+ class Configuration
5
+
6
+ attr_accessor :redis, :logger, :events
7
+
8
+ def initialize
9
+ @redis = nil
10
+ @logger = Logger.new(STDOUT)
11
+ @logger.level = Logger::WARN
12
+ @events = {
13
+ elected: [],
14
+ ousted: [],
15
+ supreme_chancellor_changed: []
16
+ }
17
+ end
18
+
19
+
20
+ def on(event, &block)
21
+ raise ArgumentError, "Invalid event: #{event}" unless @events.key?(event) && event.is_a?(Symbol)
22
+ @events[event] << block
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GalacticSenate
4
+ class Delegation
5
+
6
+ SUPREME_CHANCELLOR_INTERVAL = 10
7
+ SENATOR_INTERVAL = 30
8
+ RAND_INTERVAL = 15
9
+ KEY = "galactic-senate-supreme-chancellor"
10
+
11
+ def initialize
12
+ @running = true
13
+ @supreme_chancellor_timeout = 0
14
+ end
15
+
16
+ def self.instance
17
+ @galactic_senate ||= GalacticSenate::Delegation.new
18
+ end
19
+
20
+
21
+ def self.supreme_chancellor?
22
+ instance.supreme_chancellor?
23
+ end
24
+
25
+ def supreme_chancellor?
26
+ ( @supreme_chancellor_timeout > Time.now.to_f )
27
+ end
28
+
29
+ alias_method :leader?, :supreme_chancellor?
30
+ class << self
31
+ alias_method :leader?, :supreme_chancellor?
32
+ end
33
+
34
+ def debate
35
+
36
+ vote_of_no_confidence
37
+
38
+ timer_task = Concurrent::TimerTask.new(execution_interval: interval) do |task|
39
+
40
+ begin
41
+ vote_now
42
+ task.execution_interval = interval
43
+ rescue => e
44
+ GalacticSenate.config.logger.error "GalacticSenate::Delegation.debate - #{e.message}"
45
+ GalacticSenate.config.logger.error "GalacticSenate::Delegation.debate - #{e.backtrace.inspect}"
46
+ end
47
+ end
48
+
49
+ timer_task.execute
50
+
51
+ end
52
+
53
+ def vote_now
54
+ if supreme_chancellor?
55
+ if update_supreme_chancellor
56
+ @supreme_chancellor_timeout = Time.now.to_f + SENATOR_INTERVAL
57
+ else
58
+ @supreme_chancellor_timeout = 0
59
+ fire_event(:ousted)
60
+ end
61
+ else
62
+ vote_of_no_confidence
63
+ end
64
+ end
65
+
66
+ def vote_of_no_confidence
67
+ if elect_me_supreme_chancellor?
68
+ @supreme_chancellor_timeout = Time.now.to_f + SENATOR_INTERVAL
69
+ fire_event(:elected)
70
+ else
71
+ @supreme_chancellor_timeout = 0
72
+ end
73
+ end
74
+
75
+ def fire_event(event, val = nil)
76
+ GalacticSenate.config.events[event].each do |block|
77
+ begin
78
+ block.call(val)
79
+ rescue => e
80
+ GalacticSenate.config.logger.error "GalacticSenate::Delegation.fire_event - #{e.message}"
81
+ GalacticSenate.config.logger.error "GalacticSenate::Delegation.fire_event - #{e.backtrace.inspect}"
82
+ end
83
+ end
84
+ end
85
+
86
+ def interval
87
+ supreme_chancellor? ? SUPREME_CHANCELLOR_INTERVAL : SENATOR_INTERVAL
88
+ end
89
+
90
+ private
91
+
92
+ def get_supreme_chancellor
93
+ GalacticSenate.config.redis.call("get",KEY)
94
+ end
95
+
96
+ def delete_supreme_chancellor
97
+ GalacticSenate.config.redis.call("del",KEY)
98
+ end
99
+
100
+ def expire_supreme_chancellor
101
+ GalacticSenate.config.redis.call("expire",KEY, SENATOR_INTERVAL)
102
+ end
103
+
104
+ def elect_me_supreme_chancellor?
105
+ val = GalacticSenate.config.redis.set(KEY, GalacticSenate.whoami, ex: SENATOR_INTERVAL, nx: true)
106
+ val
107
+ end
108
+
109
+ def update_supreme_chancellor
110
+ ( get_supreme_chancellor == GalacticSenate.whoami ? expire_supreme_chancellor : 0 ) != 0
111
+ end
112
+
113
+ end
114
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GalacticSenate
4
+ VERSION = "0.1.0.4"
5
+ end
@@ -0,0 +1,9 @@
1
+ RSpec.describe Galactic::Senate do
2
+ it "has a version number" do
3
+ expect(Galactic::Senate::VERSION).not_to be nil
4
+ end
5
+
6
+ it "does something useful" do
7
+ expect(false).to eq(true)
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ require "bundler/setup"
2
+ require "galactic/senate"
3
+
4
+ RSpec.configure do |config|
5
+ # Enable flags like --only-failures and --next-failure
6
+ config.example_status_persistence_file_path = ".rspec_status"
7
+
8
+ # Disable RSpec exposing methods globally on `Module` and `main`
9
+ config.disable_monkey_patching!
10
+
11
+ config.expect_with :rspec do |c|
12
+ c.syntax = :expect
13
+ end
14
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: galactic-senate
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Jonathan De Jong
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-09-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: concurrent-ruby
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '1.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: redis
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 3.3.0
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '5.0'
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 3.3.0
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '5.0'
53
+ - !ruby/object:Gem::Dependency
54
+ name: bundler
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '1.16'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '1.16'
67
+ - !ruby/object:Gem::Dependency
68
+ name: rake
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '10.0'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '10.0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: rspec
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '3.0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '3.0'
95
+ description:
96
+ email:
97
+ - jonathan@helloglobo.com
98
+ executables: []
99
+ extensions: []
100
+ extra_rdoc_files: []
101
+ files:
102
+ - lib/galactic-senate.rb
103
+ - lib/galactic-senate/configuration.rb
104
+ - lib/galactic-senate/delegation.rb
105
+ - lib/galactic-senate/version.rb
106
+ - spec/galactic/senate_spec.rb
107
+ - spec/spec_helper.rb
108
+ homepage: https://github.com/jdejong/galactic-senate
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: 2.2.0
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 2.4.8
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: galactic-senate provides a framework backed by redis to identify 1 leader
132
+ for a set of processes.
133
+ test_files: []