shatter-rb 0.0.1
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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +20 -0
- data/.ruby-version +1 -0
- data/.tool-versions +1 -0
- data/ApacheJMeter.jar +0 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +94 -0
- data/LICENSE.txt +21 -0
- data/Procfile +5 -0
- data/README.md +39 -0
- data/Rakefile +12 -0
- data/example_app/Gemfile +5 -0
- data/example_app/Gemfile.lock +50 -0
- data/example_app/app/functions/hello_world_function.rb +19 -0
- data/example_app/app/service_definition.rb +9 -0
- data/example_app/application.rb +6 -0
- data/example_app/bin/console +11 -0
- data/example_app/bin/server +4 -0
- data/example_app/bin/service +16 -0
- data/example_app/config/environment.rb +9 -0
- data/example_app/config.ru +9 -0
- data/example_app/docker-compose.yml +32 -0
- data/exe/console +12 -0
- data/exe/shatter +64 -0
- data/lib/shatter/config.rb +12 -0
- data/lib/shatter/service/base.rb +93 -0
- data/lib/shatter/service/discovery.rb +49 -0
- data/lib/shatter/service/function.rb +56 -0
- data/lib/shatter/service/function_params.rb +21 -0
- data/lib/shatter/service/response_pool.rb +10 -0
- data/lib/shatter/service/service_definition.rb +21 -0
- data/lib/shatter/util.rb +19 -0
- data/lib/shatter/version.rb +5 -0
- data/lib/shatter/web/application.rb +50 -0
- data/lib/shatter/web/server.rb +45 -0
- data/lib/shatter.rb +21 -0
- data/shatter.gemspec +54 -0
- data/sig/shatter.rbs +4 -0
- data/templates/Gemfile.template +5 -0
- data/templates/application.erb +6 -0
- data/templates/config.ru +9 -0
- data/templates/docker-compose.yml +32 -0
- data/templates/docker-compose.yml.example +32 -0
- data/templates/environment.rb.erb +9 -0
- data/templates/hello_world_function.rb.erb +17 -0
- data/templates/service_definition.rb.erb +9 -0
- metadata +278 -0
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'singleton'
|
3
|
+
require 'benchmark'
|
4
|
+
require "drb/drb"
|
5
|
+
require "zk"
|
6
|
+
require "concurrent-ruby"
|
7
|
+
|
8
|
+
# Server Side of the drb
|
9
|
+
module Shatter
|
10
|
+
module Service
|
11
|
+
class Base
|
12
|
+
include Concurrent::Async
|
13
|
+
|
14
|
+
class ZooKeeperConnection
|
15
|
+
include Singleton
|
16
|
+
attr_reader :client
|
17
|
+
def initialize
|
18
|
+
@client = ZK.new(Shatter::Config.zookeeper_host)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
attr_reader :service_definition
|
24
|
+
attr_writer :service_definition
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.response_for(uuid)
|
28
|
+
ResponsePool.instance.pool[uuid]
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.respond_to_missing?(method)
|
32
|
+
@service_definition.instance_methods.include?(method.to_sym)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.set_static_result_for(uuid, result)
|
36
|
+
puts "Setting static content"
|
37
|
+
populate_pool_with_result(Time.now, {uuid:, result:}, nil)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.method_missing(method, *args, &)
|
41
|
+
Shatter.logger.info "Mapping #{method}"
|
42
|
+
uuid = args[0].is_a?(Hash) ? args[0][:uuid] : args[0].uuid
|
43
|
+
return {error: 'missing uuid'} if uuid.nil?
|
44
|
+
future = @service_definition.new.async.send(method, *args, &)
|
45
|
+
future.add_observer(self, :populate_pool_with_result)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.populate_pool_with_result(time, value, err)
|
49
|
+
if err
|
50
|
+
Shatter.logger.info err
|
51
|
+
end
|
52
|
+
ResponsePool.instance.pool[value[:uuid]] = value
|
53
|
+
zk = ZooKeeperConnection.instance.client
|
54
|
+
key = nil
|
55
|
+
key = Util.zookeeper_response_key(value[:uuid])
|
56
|
+
my_ip = ENV["HOST_NAME"] || "localhost"
|
57
|
+
host = "#{my_ip}:#{Shatter::Config.service_port}"
|
58
|
+
Shatter.logger.info "Recording location of #{value[:uuid]} at #{host} #{value}"
|
59
|
+
zk.create(key, host)
|
60
|
+
my_ip
|
61
|
+
rescue Exception => e
|
62
|
+
Shatter.logger.error e
|
63
|
+
raise e
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.close
|
67
|
+
logger = Shatter.logger
|
68
|
+
logger.info "Closing down DRb service"
|
69
|
+
port = Shatter::Config.service_port
|
70
|
+
uri = "localhost:#{port}"
|
71
|
+
logger.info "Removing my existnce at #{port} to zookeeper"
|
72
|
+
Shatter::Service::Discovery.deregister_service(uri)
|
73
|
+
logger.info "Closed DRb service"
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.init
|
77
|
+
logger.info "Initing DRb service"
|
78
|
+
port = Shatter::Config.service_port
|
79
|
+
uri = "localhost:#{port}"
|
80
|
+
logger.info "Logging my existnce at #{uri} to zookeeper"
|
81
|
+
Shatter::Service::Discovery.register_service(uri)
|
82
|
+
logger.info "Starting DRb service"
|
83
|
+
DRb.start_service("druby://#{uri}", self)
|
84
|
+
logger.info "DRb service started"
|
85
|
+
DRb.thread.join
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.logger
|
89
|
+
Shatter.logger
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Shatter
|
2
|
+
module Service
|
3
|
+
class Discovery
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def deregister_service(service_url)
|
7
|
+
zk = ZK.new (Shatter::Config.zookeeper_host)
|
8
|
+
if zk.exists?("/shater_service_instances/#{service_url}")
|
9
|
+
zk.delete("/shater_service_instances/#{service_url}")
|
10
|
+
end
|
11
|
+
zk.close
|
12
|
+
end
|
13
|
+
|
14
|
+
def register_service(service_url)
|
15
|
+
Shatter.logger.info "Registering #{service_url} to zookeeper"
|
16
|
+
zk = ZK.new (Shatter::Config.zookeeper_host)
|
17
|
+
unless zk.exists?("/shater_service_instances/#{service_url}")
|
18
|
+
created = zk.create("/shater_service_instances/#{service_url}")
|
19
|
+
Shatter.logger.info "Registered #{created}"
|
20
|
+
end
|
21
|
+
puts zk.children("/shater_service_instances")
|
22
|
+
zk.close
|
23
|
+
end
|
24
|
+
|
25
|
+
def service_instance_url
|
26
|
+
service_instance_urls.sample
|
27
|
+
end
|
28
|
+
|
29
|
+
def service_instance_urls
|
30
|
+
zk = ZK.new (Shatter::Config.zookeeper_host)
|
31
|
+
urls = zk.children("/shater_service_instances")
|
32
|
+
zk.close
|
33
|
+
urls
|
34
|
+
end
|
35
|
+
|
36
|
+
def service_instance_url_for_uuid(uuid)
|
37
|
+
druby_instance_url = nil
|
38
|
+
key = Util.zookeeper_response_key(uuid)
|
39
|
+
zk = ZK.new(Shatter::Config.zookeeper_host)
|
40
|
+
druby_instance_url = zk.get(key)[0] if zk.exists?(key)
|
41
|
+
zk.close
|
42
|
+
Shatter.logger.debug "Service instance url for #{uuid} - #{druby_instance_url}"
|
43
|
+
|
44
|
+
druby_instance_url
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Shatter
|
2
|
+
module Service
|
3
|
+
class Function
|
4
|
+
|
5
|
+
def self.define_param(name, type:, nullable: true)
|
6
|
+
@@param_meta ||= {}
|
7
|
+
@@param_meta[name] = {name:, type:, nullable:}
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.meta
|
11
|
+
@@param_meta
|
12
|
+
end
|
13
|
+
|
14
|
+
define_param :uuid, nullable: false, type: 'string'
|
15
|
+
|
16
|
+
def initialize(function_params)
|
17
|
+
@params = function_params
|
18
|
+
end
|
19
|
+
|
20
|
+
def params
|
21
|
+
Hash[@@param_meta.keys.map { |k| [k]}].merge(@params)
|
22
|
+
end
|
23
|
+
|
24
|
+
def call
|
25
|
+
raise 'Invalid Args' unless valid_params?
|
26
|
+
valid_keys = @@param_meta.keys
|
27
|
+
{result: nil, error:nil}.merge(self.invoke.merge(uuid: params[:uuid]))
|
28
|
+
rescue Exception => e
|
29
|
+
{result: nil, error: e.message, uuid: params[:uuid]}
|
30
|
+
end
|
31
|
+
|
32
|
+
def valid_params?
|
33
|
+
self.class.meta.keys.each do |arg|
|
34
|
+
meta = self.class.meta[arg]
|
35
|
+
val = @params[arg]
|
36
|
+
puts meta
|
37
|
+
raise "#{arg} cannot be nil" if !meta[:nullable] && val.nil?
|
38
|
+
raise "expected #{arg} to be a string" if meta[:type] == 'string' && !val.is_a?(String)
|
39
|
+
|
40
|
+
if meta[:type] == 'integer'
|
41
|
+
if !meta[:nullable] && val.nil?
|
42
|
+
raise 'value cannot be nil'
|
43
|
+
end
|
44
|
+
if !val.nil? && !val.is_a?(Integer)
|
45
|
+
raise "expected #{arg} to be an integer"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.invoke
|
52
|
+
raise 'cant invoke for base function'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Shatter
|
2
|
+
module Service
|
3
|
+
class FunctionParams < Data
|
4
|
+
|
5
|
+
def self.generate(*args, &block)
|
6
|
+
args << :uuid
|
7
|
+
|
8
|
+
Data.define(*args) do
|
9
|
+
def to_typescript
|
10
|
+
typescript_name = self.class.to_s.split("::").last(2).join
|
11
|
+
out = <<-HEREDOC.gsub(/^\s+/, "")
|
12
|
+
type #{typescript_name} {
|
13
|
+
};
|
14
|
+
export default #{typescript_name}
|
15
|
+
HEREDOC
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "concurrent-ruby"
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
module Shatter
|
5
|
+
module Service
|
6
|
+
class ServiceDefinition
|
7
|
+
include Concurrent::Async
|
8
|
+
class << self
|
9
|
+
attr_reader :function_collection
|
10
|
+
end
|
11
|
+
def self.register_function(identifier, function)
|
12
|
+
Shatter.logger.info "Registering function - #{identifier} for #{self}"
|
13
|
+
@function_collection ||= {}
|
14
|
+
@function_collection[identifier.to_s] = function
|
15
|
+
define_method identifier do |params|
|
16
|
+
function.new(params).call
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/shatter/util.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'logger'
|
3
|
+
require 'singleton'
|
4
|
+
|
5
|
+
module Shatter
|
6
|
+
module Util
|
7
|
+
class Logger < ::Logger
|
8
|
+
include Singleton
|
9
|
+
def initialize
|
10
|
+
super(STDOUT, datetime_format: '%Y-%m-%d %H:%M:%S')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.zookeeper_response_key(uuid)
|
15
|
+
raise 'Cant produce key without uuid' if uuid.nil?
|
16
|
+
"/shatter::response_data_locations/#{uuid}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "drb/drb"
|
4
|
+
require "concurrent-ruby"
|
5
|
+
|
6
|
+
require_relative "./application"
|
7
|
+
|
8
|
+
module Shatter
|
9
|
+
module Web
|
10
|
+
class Application
|
11
|
+
include Concurrent::Async
|
12
|
+
|
13
|
+
def response_for(uuid)
|
14
|
+
druby_instance_url = Shatter::Service::Discovery.service_instance_url_for_uuid(uuid)
|
15
|
+
return unless druby_instance_url
|
16
|
+
DRbObject.new_with_uri("druby://#{druby_instance_url}").response_for(uuid)
|
17
|
+
end
|
18
|
+
|
19
|
+
def route(uuid, path, params)
|
20
|
+
operation = path.scan(/\/(.+)$/).first&.first
|
21
|
+
raise 'failed to route' if operation.nil?
|
22
|
+
Shatter.logger.info Shatter::Service::Base.service_definition.function_collection
|
23
|
+
Shatter.logger.info operation
|
24
|
+
function = Shatter::Service::Base.service_definition.function_collection[operation]
|
25
|
+
if function.nil?
|
26
|
+
DRbObject.new_with_uri("druby://#{Shatter::Service::Discovery.service_instance_url}")
|
27
|
+
.set_static_result_for(uuid, {result: nil, error: :unknown_operation})
|
28
|
+
else
|
29
|
+
begin
|
30
|
+
func_params = params.merge(uuid:)
|
31
|
+
Shatter.logger.info "routing #{path}/#{func_params}"
|
32
|
+
DRbObject.new_with_uri("druby://#{Shatter::Service::Discovery.service_instance_url}")
|
33
|
+
.send(
|
34
|
+
operation.to_sym,
|
35
|
+
func_params
|
36
|
+
)
|
37
|
+
rescue ArgumentError => e
|
38
|
+
DRbObject.new_with_uri("druby://#{Shatter::Service::Discovery.service_instance_url}")
|
39
|
+
.set_static_result_for(uuid, {result: nil, error: e.message })
|
40
|
+
end
|
41
|
+
end
|
42
|
+
rescue Exception => e
|
43
|
+
Shatter.logger.error "caught error: #{e.message}"
|
44
|
+
Shatter.logger.error "#{e.backtrace.join("\n")}"
|
45
|
+
{ data:, error: e.message, uuid: }
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
module Shatter
|
7
|
+
module Web
|
8
|
+
class Server
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr_reader :application
|
12
|
+
attr_writer :application
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.call(env)
|
16
|
+
request = Rack::Request.new(env)
|
17
|
+
path = env["PATH_INFO"]
|
18
|
+
if env["PATH_INFO"] == "/callbacks"
|
19
|
+
uuid = env['QUERY_STRING'].split("=")[1]
|
20
|
+
response_for(uuid)
|
21
|
+
elsif env["PATH_INFO"] == "/base_time"
|
22
|
+
[200, {}, [""]]
|
23
|
+
else
|
24
|
+
params = JSON.parse(request.body.read, {symbolize_names: true})
|
25
|
+
uuid = SecureRandom.uuid
|
26
|
+
future = application.new.async.route(uuid, path, params)
|
27
|
+
future.add_observer(:server_call_result, self)
|
28
|
+
[200, { "delay" => "20", "location" => "/callbacks?uuid=#{uuid}" }, []]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.server_call_result(time, value, error)
|
33
|
+
return if error.nil?
|
34
|
+
Shatter.logger.error "#{ error }"
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.response_for(uuid)
|
38
|
+
response = application.new.response_for(uuid)
|
39
|
+
return [200, {}, [response.to_json]] unless response.nil?
|
40
|
+
|
41
|
+
[200, { "delay" => "100", "location" => "/callbacks?uuid=#{uuid}" }, []]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/shatter.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "shatter/version"
|
4
|
+
require_relative "shatter/web/application"
|
5
|
+
require_relative "shatter/config"
|
6
|
+
require_relative "shatter/web/server"
|
7
|
+
require_relative "shatter/service/base"
|
8
|
+
require_relative "shatter/service/discovery"
|
9
|
+
require_relative "shatter/service/service_definition"
|
10
|
+
require_relative "shatter/service/response_pool"
|
11
|
+
require_relative "shatter/util"
|
12
|
+
|
13
|
+
$stdout.sync = true
|
14
|
+
|
15
|
+
module Shatter
|
16
|
+
class Error < StandardError; end
|
17
|
+
def self.logger
|
18
|
+
Util::Logger.instance
|
19
|
+
end
|
20
|
+
# Your code goes here...
|
21
|
+
end
|
data/shatter.gemspec
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/shatter/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "shatter-rb"
|
7
|
+
spec.version = Shatter::VERSION
|
8
|
+
spec.authors = ["Eric Roos"]
|
9
|
+
spec.email = ["ericroos@hey.com"]
|
10
|
+
|
11
|
+
spec.summary = "Write a short summary, because RubyGems requires one."
|
12
|
+
spec.description = "Write a longer description or delete this line."
|
13
|
+
spec.homepage = "https://rubygems.org/gems/shatter"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = ">= 3.1.0"
|
16
|
+
|
17
|
+
#spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
|
18
|
+
|
19
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
20
|
+
spec.metadata["source_code_uri"] = "https://github.com/EricRoos/shatter"
|
21
|
+
spec.metadata["changelog_uri"] = "https://github.com/EricRoos/shatter/tree/master/CHANGELOG"
|
22
|
+
|
23
|
+
# Specify which files should be added to the gem when it is released.
|
24
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
|
+
spec.files = Dir.chdir(__dir__) do
|
26
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
27
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:javascript|bin|test|spec|features)/|\.(?:git|circleci)|appveyor)})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
spec.bindir = "exe"
|
31
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
32
|
+
spec.require_paths = ["lib"]
|
33
|
+
|
34
|
+
# Uncomment to register a new dependency of your gem
|
35
|
+
# spec.add_dependency "example-gem", "~> 1.0"
|
36
|
+
spec.add_dependency "rack", "~> 3.0"
|
37
|
+
spec.add_dependency "rackup", "~> 0.2.3"
|
38
|
+
spec.add_dependency "concurrent-ruby", "~> 1.1"
|
39
|
+
spec.add_dependency "pg", "~> 1.4"
|
40
|
+
spec.add_dependency "zk", "~> 1.10"
|
41
|
+
spec.add_dependency "puma", "~> 6.0"
|
42
|
+
spec.add_dependency "thor", "~> 1.2.1"
|
43
|
+
spec.add_dependency "erb", "~> 2.2.0"
|
44
|
+
# spec.add_dependency "zookeeper", "~>1.5.4", github: 'EricRoos/zookeeper'
|
45
|
+
|
46
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
47
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
48
|
+
spec.add_development_dependency "rubocop", "~> 1.21"
|
49
|
+
spec.add_development_dependency "rubocop-rake"
|
50
|
+
spec.add_development_dependency "rubocop-rspec"
|
51
|
+
# For more information and examples about making a new gem, check out our
|
52
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
53
|
+
#spec.metadata["rubygems_mfa_required"] = "true"
|
54
|
+
end
|
data/sig/shatter.rbs
ADDED
data/templates/config.ru
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
version: '3.1'
|
2
|
+
|
3
|
+
services:
|
4
|
+
zoo1:
|
5
|
+
image: zookeeper
|
6
|
+
restart: always
|
7
|
+
hostname: zoo1
|
8
|
+
ports:
|
9
|
+
- 2181:2181
|
10
|
+
environment:
|
11
|
+
ZOO_MY_ID: 1
|
12
|
+
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
|
13
|
+
|
14
|
+
zoo2:
|
15
|
+
image: zookeeper
|
16
|
+
restart: always
|
17
|
+
hostname: zoo2
|
18
|
+
ports:
|
19
|
+
- 2182:2181
|
20
|
+
environment:
|
21
|
+
ZOO_MY_ID: 2
|
22
|
+
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
|
23
|
+
|
24
|
+
zoo3:
|
25
|
+
image: zookeeper
|
26
|
+
restart: always
|
27
|
+
hostname: zoo3
|
28
|
+
ports:
|
29
|
+
- 2183:2181
|
30
|
+
environment:
|
31
|
+
ZOO_MY_ID: 3
|
32
|
+
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
|
@@ -0,0 +1,32 @@
|
|
1
|
+
version: '3.1'
|
2
|
+
|
3
|
+
services:
|
4
|
+
zoo1:
|
5
|
+
image: zookeeper
|
6
|
+
restart: always
|
7
|
+
hostname: zoo1
|
8
|
+
ports:
|
9
|
+
- 2181:2181
|
10
|
+
environment:
|
11
|
+
ZOO_MY_ID: 1
|
12
|
+
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
|
13
|
+
|
14
|
+
zoo2:
|
15
|
+
image: zookeeper
|
16
|
+
restart: always
|
17
|
+
hostname: zoo2
|
18
|
+
ports:
|
19
|
+
- 2182:2181
|
20
|
+
environment:
|
21
|
+
ZOO_MY_ID: 2
|
22
|
+
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
|
23
|
+
|
24
|
+
zoo3:
|
25
|
+
image: zookeeper
|
26
|
+
restart: always
|
27
|
+
hostname: zoo3
|
28
|
+
ports:
|
29
|
+
- 2183:2181
|
30
|
+
environment:
|
31
|
+
ZOO_MY_ID: 3
|
32
|
+
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Shatter::Config.zookeeper_host = "localhost:2181"
|
2
|
+
Shatter::Config.initial_delay = 100
|
3
|
+
Shatter::Config.missing_result_delay = 100
|
4
|
+
Shatter::Config.service_port = ENV.fetch('SHATTER_SERVICE_PORT') { 8787 }
|
5
|
+
|
6
|
+
require_relative '../application'
|
7
|
+
|
8
|
+
Shatter::Service::Base.service_definition = <%= app_name%>::ServiceDefinition
|
9
|
+
Shatter::Web::Server.application = <%= app_name%>::Application
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "pg"
|
2
|
+
require "shatter/service/function"
|
3
|
+
require "shatter/service/function_params"
|
4
|
+
|
5
|
+
module <%= app_name %>
|
6
|
+
module Functions
|
7
|
+
class HelloWorldFunction < Shatter::Service::Function
|
8
|
+
define_param :name, nullable: false, type: 'string'
|
9
|
+
define_param :number, nullable: false, type: 'integer'
|
10
|
+
|
11
|
+
def invoke
|
12
|
+
params.to_h => name:, uuid:
|
13
|
+
{ result: "Hello #{name}", uuid:, error: nil, uuid: }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './functions/hello_world_function'
|
4
|
+
|
5
|
+
module <%= app_name %>
|
6
|
+
class ServiceDefinition < Shatter::Service::ServiceDefinition
|
7
|
+
register_function :hello_world, <%= app_name %>::Functions::HelloWorldFunction
|
8
|
+
end
|
9
|
+
end
|