shatter-rb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|