beez 0.1.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.
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,36 @@
1
+ require_relative 'lib/beez/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "beez"
5
+ spec.version = Beez::VERSION
6
+ spec.authors = ["Pierre-Louis Gottfrois"]
7
+ spec.email = ["pierrelouis.gottfrois@gmail.com"]
8
+
9
+ spec.summary = %q{Simple, efficient ruby workers for Zeebe business processes.}
10
+ spec.description = %q{Simple, efficient ruby workers for Zeebe business processes.}
11
+ spec.homepage = "https://github.com/gottfrois/beez"
12
+ spec.license = "MIT"
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
14
+
15
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "https://github.com/gottfrois/beez"
19
+ spec.metadata["changelog_uri"] = "https://github.com/gottfrois/beez/CHANGELOG.md"
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ end
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_dependency "zeebe-client", "~> 0.7"
31
+ spec.add_dependency "concurrent-ruby", "~> 1.0"
32
+
33
+ spec.add_development_dependency "pry"
34
+ spec.add_development_dependency "bundler"
35
+ spec.add_development_dependency "rspec", "~> 3.0"
36
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "beez"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,139 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_0roiw93" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Zeebe Modeler" exporterVersion="0.9.1">
3
+ <bpmn:process id="order-process" isExecutable="true">
4
+ <bpmn:startEvent id="StartEvent_1" name="Order Placed">
5
+ <bpmn:outgoing>SequenceFlow_0l1itgv</bpmn:outgoing>
6
+ </bpmn:startEvent>
7
+ <bpmn:serviceTask id="ServiceTask_1uaxkgt" name="Initiate Payment">
8
+ <bpmn:extensionElements>
9
+ <zeebe:taskDefinition type="initiate-payment" />
10
+ </bpmn:extensionElements>
11
+ <bpmn:incoming>SequenceFlow_0l1itgv</bpmn:incoming>
12
+ <bpmn:outgoing>SequenceFlow_05wimmt</bpmn:outgoing>
13
+ </bpmn:serviceTask>
14
+ <bpmn:sequenceFlow id="SequenceFlow_0l1itgv" sourceRef="StartEvent_1" targetRef="ServiceTask_1uaxkgt" />
15
+ <bpmn:intermediateCatchEvent id="IntermediateCatchEvent_178qswy" name="Payment Received">
16
+ <bpmn:incoming>SequenceFlow_05wimmt</bpmn:incoming>
17
+ <bpmn:outgoing>SequenceFlow_0sdhelb</bpmn:outgoing>
18
+ <bpmn:messageEventDefinition messageRef="Message_1jdabrh" />
19
+ </bpmn:intermediateCatchEvent>
20
+ <bpmn:sequenceFlow id="SequenceFlow_05wimmt" sourceRef="ServiceTask_1uaxkgt" targetRef="IntermediateCatchEvent_178qswy" />
21
+ <bpmn:exclusiveGateway id="ExclusiveGateway_0xtem5z" name="Order Value?" default="SequenceFlow_1of2ef2">
22
+ <bpmn:incoming>SequenceFlow_0sdhelb</bpmn:incoming>
23
+ <bpmn:outgoing>SequenceFlow_1of2ef2</bpmn:outgoing>
24
+ <bpmn:outgoing>SequenceFlow_1qfaoce</bpmn:outgoing>
25
+ </bpmn:exclusiveGateway>
26
+ <bpmn:sequenceFlow id="SequenceFlow_0sdhelb" sourceRef="IntermediateCatchEvent_178qswy" targetRef="ExclusiveGateway_0xtem5z" />
27
+ <bpmn:serviceTask id="ServiceTask_0ms04gz" name="Ship Without Insurance">
28
+ <bpmn:extensionElements>
29
+ <zeebe:taskDefinition type="ship-without-insurance" />
30
+ </bpmn:extensionElements>
31
+ <bpmn:incoming>SequenceFlow_1of2ef2</bpmn:incoming>
32
+ <bpmn:outgoing>SequenceFlow_1pxhmpe</bpmn:outgoing>
33
+ </bpmn:serviceTask>
34
+ <bpmn:sequenceFlow id="SequenceFlow_1of2ef2" sourceRef="ExclusiveGateway_0xtem5z" targetRef="ServiceTask_0ms04gz" />
35
+ <bpmn:serviceTask id="ServiceTask_0tw27bj" name="Ship With Insurance">
36
+ <bpmn:extensionElements>
37
+ <zeebe:taskDefinition type="ship-with-insurance" />
38
+ </bpmn:extensionElements>
39
+ <bpmn:incoming>SequenceFlow_1qfaoce</bpmn:incoming>
40
+ <bpmn:outgoing>SequenceFlow_0dvg03l</bpmn:outgoing>
41
+ </bpmn:serviceTask>
42
+ <bpmn:sequenceFlow id="SequenceFlow_1qfaoce" name="&#62;$100" sourceRef="ExclusiveGateway_0xtem5z" targetRef="ServiceTask_0tw27bj">
43
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=orderValue &gt;= 100</bpmn:conditionExpression>
44
+ </bpmn:sequenceFlow>
45
+ <bpmn:exclusiveGateway id="ExclusiveGateway_0y9y7j8">
46
+ <bpmn:incoming>SequenceFlow_1pxhmpe</bpmn:incoming>
47
+ <bpmn:incoming>SequenceFlow_0dvg03l</bpmn:incoming>
48
+ <bpmn:outgoing>SequenceFlow_0p15rvb</bpmn:outgoing>
49
+ </bpmn:exclusiveGateway>
50
+ <bpmn:sequenceFlow id="SequenceFlow_1pxhmpe" sourceRef="ServiceTask_0ms04gz" targetRef="ExclusiveGateway_0y9y7j8" />
51
+ <bpmn:sequenceFlow id="SequenceFlow_0dvg03l" sourceRef="ServiceTask_0tw27bj" targetRef="ExclusiveGateway_0y9y7j8" />
52
+ <bpmn:endEvent id="EndEvent_146mj14" name="Order Fulfilled">
53
+ <bpmn:incoming>SequenceFlow_0p15rvb</bpmn:incoming>
54
+ </bpmn:endEvent>
55
+ <bpmn:sequenceFlow id="SequenceFlow_0p15rvb" sourceRef="ExclusiveGateway_0y9y7j8" targetRef="EndEvent_146mj14" />
56
+ </bpmn:process>
57
+ <bpmn:message id="Message_1jdabrh" name="payment-received">
58
+ <bpmn:extensionElements>
59
+ <zeebe:subscription correlationKey="=orderId" />
60
+ </bpmn:extensionElements>
61
+ </bpmn:message>
62
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
63
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="order-process">
64
+ <bpmndi:BPMNEdge id="SequenceFlow_0p15rvb_di" bpmnElement="SequenceFlow_0p15rvb">
65
+ <di:waypoint x="801" y="121" />
66
+ <di:waypoint x="851" y="121" />
67
+ </bpmndi:BPMNEdge>
68
+ <bpmndi:BPMNEdge id="SequenceFlow_0dvg03l_di" bpmnElement="SequenceFlow_0dvg03l">
69
+ <di:waypoint x="701" y="231" />
70
+ <di:waypoint x="776" y="231" />
71
+ <di:waypoint x="776" y="146" />
72
+ </bpmndi:BPMNEdge>
73
+ <bpmndi:BPMNEdge id="SequenceFlow_1pxhmpe_di" bpmnElement="SequenceFlow_1pxhmpe">
74
+ <di:waypoint x="701" y="121" />
75
+ <di:waypoint x="751" y="121" />
76
+ </bpmndi:BPMNEdge>
77
+ <bpmndi:BPMNEdge id="SequenceFlow_1qfaoce_di" bpmnElement="SequenceFlow_1qfaoce">
78
+ <di:waypoint x="526" y="146" />
79
+ <di:waypoint x="526" y="231" />
80
+ <di:waypoint x="601" y="231" />
81
+ <bpmndi:BPMNLabel>
82
+ <dc:Bounds x="543" y="210" width="31" height="14" />
83
+ </bpmndi:BPMNLabel>
84
+ </bpmndi:BPMNEdge>
85
+ <bpmndi:BPMNEdge id="SequenceFlow_1of2ef2_di" bpmnElement="SequenceFlow_1of2ef2">
86
+ <di:waypoint x="551" y="121" />
87
+ <di:waypoint x="601" y="121" />
88
+ </bpmndi:BPMNEdge>
89
+ <bpmndi:BPMNEdge id="SequenceFlow_0sdhelb_di" bpmnElement="SequenceFlow_0sdhelb">
90
+ <di:waypoint x="451" y="121" />
91
+ <di:waypoint x="501" y="121" />
92
+ </bpmndi:BPMNEdge>
93
+ <bpmndi:BPMNEdge id="SequenceFlow_05wimmt_di" bpmnElement="SequenceFlow_05wimmt">
94
+ <di:waypoint x="365" y="121" />
95
+ <di:waypoint x="415" y="121" />
96
+ </bpmndi:BPMNEdge>
97
+ <bpmndi:BPMNEdge id="SequenceFlow_0l1itgv_di" bpmnElement="SequenceFlow_0l1itgv">
98
+ <di:waypoint x="215" y="121" />
99
+ <di:waypoint x="265" y="121" />
100
+ </bpmndi:BPMNEdge>
101
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
102
+ <dc:Bounds x="179" y="103" width="36" height="36" />
103
+ <bpmndi:BPMNLabel>
104
+ <dc:Bounds x="165" y="146" width="65" height="14" />
105
+ </bpmndi:BPMNLabel>
106
+ </bpmndi:BPMNShape>
107
+ <bpmndi:BPMNShape id="ServiceTask_1uaxkgt_di" bpmnElement="ServiceTask_1uaxkgt">
108
+ <dc:Bounds x="265" y="81" width="100" height="80" />
109
+ </bpmndi:BPMNShape>
110
+ <bpmndi:BPMNShape id="IntermediateCatchEvent_178qswy_di" bpmnElement="IntermediateCatchEvent_178qswy">
111
+ <dc:Bounds x="415" y="103" width="36" height="36" />
112
+ <bpmndi:BPMNLabel>
113
+ <dc:Bounds x="410" y="146" width="46" height="27" />
114
+ </bpmndi:BPMNLabel>
115
+ </bpmndi:BPMNShape>
116
+ <bpmndi:BPMNShape id="ExclusiveGateway_0xtem5z_di" bpmnElement="ExclusiveGateway_0xtem5z" isMarkerVisible="true">
117
+ <dc:Bounds x="501" y="96" width="50" height="50" />
118
+ <bpmndi:BPMNLabel>
119
+ <dc:Bounds x="493" y="72" width="65" height="14" />
120
+ </bpmndi:BPMNLabel>
121
+ </bpmndi:BPMNShape>
122
+ <bpmndi:BPMNShape id="ServiceTask_0ms04gz_di" bpmnElement="ServiceTask_0ms04gz">
123
+ <dc:Bounds x="601" y="81" width="100" height="80" />
124
+ </bpmndi:BPMNShape>
125
+ <bpmndi:BPMNShape id="ServiceTask_0tw27bj_di" bpmnElement="ServiceTask_0tw27bj">
126
+ <dc:Bounds x="601" y="191" width="100" height="80" />
127
+ </bpmndi:BPMNShape>
128
+ <bpmndi:BPMNShape id="ExclusiveGateway_0y9y7j8_di" bpmnElement="ExclusiveGateway_0y9y7j8" isMarkerVisible="true">
129
+ <dc:Bounds x="751" y="96" width="50" height="50" />
130
+ </bpmndi:BPMNShape>
131
+ <bpmndi:BPMNShape id="EndEvent_146mj14_di" bpmnElement="EndEvent_146mj14">
132
+ <dc:Bounds x="851" y="103" width="36" height="36" />
133
+ <bpmndi:BPMNLabel>
134
+ <dc:Bounds x="834" y="146" width="70" height="14" />
135
+ </bpmndi:BPMNLabel>
136
+ </bpmndi:BPMNShape>
137
+ </bpmndi:BPMNPlane>
138
+ </bpmndi:BPMNDiagram>
139
+ </bpmn:definitions>
@@ -0,0 +1,49 @@
1
+ require "beez"
2
+
3
+ module Workers
4
+ class InitiatePaymentWorker
5
+ include ::Beez::Worker
6
+
7
+ type "initiate-payment"
8
+ max_jobs_to_activate 5
9
+ poll_interval 1
10
+ timeout 30
11
+
12
+ def process(job)
13
+ rand(35).times do |i|
14
+ logger.info "Processing job #{job.type} #{job.key} by waiting #{i}s"
15
+ sleep 1
16
+ end
17
+ end
18
+ end
19
+
20
+ class ShipWithInsuranceWorker
21
+ include ::Beez::Worker
22
+
23
+ type "ship-with-insurance"
24
+ max_jobs_to_activate 5
25
+ poll_interval 1
26
+
27
+ def process(job)
28
+ rand(35).times do |i|
29
+ logger.info "Processing job #{job.type} #{job.key} by waiting #{i}s"
30
+ sleep 1
31
+ end
32
+ end
33
+ end
34
+
35
+ class ShipWithoutInsuranceWorker
36
+ include ::Beez::Worker
37
+
38
+ type "ship-without-insurance"
39
+ max_jobs_to_activate 5
40
+ poll_interval 1
41
+
42
+ def process(job)
43
+ rand(35).times do |i|
44
+ logger.info "Processing job #{job.type} #{job.key} by waiting #{i}s"
45
+ sleep 1
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ require "bundler/setup"
3
+ require "beez/cli"
4
+
5
+ begin
6
+ cli = ::Beez::CLI.instance
7
+ cli.parse
8
+ cli.run
9
+ rescue => e
10
+ raise e if $DEBUG
11
+ STDERR.puts e.message
12
+ STDERR.puts e.backtrace.join("\n")
13
+ exit 1
14
+ end
@@ -0,0 +1,26 @@
1
+ require 'concurrent'
2
+
3
+ require 'beez/configurable'
4
+ require 'beez/Loggable'
5
+ require 'beez/client'
6
+ require 'beez/worker'
7
+ require 'beez/version'
8
+
9
+ module Beez
10
+ extend ::Beez::Configurable
11
+ extend ::Beez::Loggable
12
+
13
+ # class Error < StandardError; end
14
+
15
+ def self.register_worker(worker)
16
+ self.workers << worker
17
+ end
18
+
19
+ def self.workers
20
+ @workers ||= []
21
+ end
22
+
23
+ def self.client
24
+ @client ||= ::Beez::Client.new
25
+ end
26
+ end
@@ -0,0 +1,143 @@
1
+ require 'singleton'
2
+ require 'optparse'
3
+ require 'fileutils'
4
+ require 'beez'
5
+ require 'beez/launcher'
6
+
7
+ $stdout.sync = true
8
+
9
+ module Beez
10
+ class CLI
11
+ include Singleton
12
+
13
+ attr_accessor :launcher
14
+
15
+ def parse(argv = ARGV)
16
+ parse_options(argv)
17
+ end
18
+
19
+ def run
20
+ boot
21
+
22
+ self_read, self_write = IO.pipe
23
+ sigs = %w[INT TERM]
24
+ sigs.each do |sig|
25
+ trap sig do
26
+ self_write.write("#{sig}\n")
27
+ end
28
+ rescue ArgumentError
29
+ logger.warn "Signal #{sig} not supported"
30
+ end
31
+
32
+ launch(self_read)
33
+ end
34
+
35
+ private
36
+
37
+ def parse_options(argv)
38
+ option_parser.parse!(argv)
39
+ end
40
+
41
+ def option_parser
42
+ OptionParser.new.tap do |p|
43
+ p.on "-e", "--env ENV", "Application environment" do |arg|
44
+ config.env = arg
45
+ end
46
+
47
+ p.on "-r", "--require [PATH|DIR]", "Location of Rails application with workers or file to require" do |arg|
48
+ if !File.exist?(arg) ||
49
+ (File.directory?(arg) && !File.exist?("#{arg}/config/application.rb"))
50
+ raise ArgumentError, "#{arg} is not a ruby file nor a rails application"
51
+ else
52
+ config.require = arg
53
+ end
54
+ end
55
+
56
+ p.on "-t", "--timeout NUM", "Shutdown timeout" do |arg|
57
+ timeout = Integer(arg)
58
+ raise ArgumentError, "timeout must be a positive integer" if timeout <= 0
59
+ config.timeout = timeout
60
+ end
61
+
62
+ p.on "-v", "--verbose", "Print more verbose output" do |arg|
63
+ ::Beez.logger.level = ::Logger::DEBUG
64
+ end
65
+
66
+ p.on "-V", "--version", "Print version and exit" do |arg|
67
+ puts "Beez #{::Beez::VERSION}"
68
+ exit(0)
69
+ end
70
+
71
+ p.banner = "Usage: beez [options]"
72
+ p.on_tail "-h", "--help", "Show help" do
73
+ puts p
74
+
75
+ exit(1)
76
+ end
77
+ end
78
+ end
79
+
80
+ def boot
81
+ ENV["RACK_ENV"] = ENV["RAILS_ENV"] = config.env
82
+
83
+ if File.directory?(config.require)
84
+ require 'rails'
85
+ if ::Rails::VERSION::MAJOR < 4
86
+ raise "Beez does not supports this version of Rails"
87
+ else
88
+ require File.expand_path("#{config.require}/config/environment.rb")
89
+ logger.info "Booted Rails #{::Rails.version} application in #{config.env} environment"
90
+ end
91
+ else
92
+ require config.require
93
+ end
94
+ end
95
+
96
+ def launch(self_read)
97
+ @launcher = ::Beez::Launcher.new
98
+
99
+ if config.env == "development" && $stdout.tty?
100
+ logger.info "Starting processing, hit Ctrl-C to stop"
101
+ end
102
+
103
+ begin
104
+ launcher.start
105
+
106
+ while readable_io = IO.select([self_read])
107
+ signal = readable_io.first[0].gets.strip
108
+ handle_signal(signal)
109
+ end
110
+ rescue Interrupt
111
+ logger.info "Shutting down"
112
+ launcher.stop
113
+ logger.info "Bye!"
114
+
115
+ exit(0)
116
+ end
117
+ end
118
+
119
+ def handle_signal(signal)
120
+ handler = signal_handlers[signal]
121
+ if handler
122
+ handler.call(self)
123
+ else
124
+ logger.warn "No signal handler for #{signal}"
125
+ end
126
+ end
127
+
128
+ def signal_handlers
129
+ {
130
+ "INT" => ->(cli) { raise Interrupt },
131
+ "TERM" => ->(cli) { raise Interrupt },
132
+ }
133
+ end
134
+
135
+ def config
136
+ ::Beez.config
137
+ end
138
+
139
+ def logger
140
+ ::Beez.logger
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,97 @@
1
+ require 'zeebe/client'
2
+
3
+ module Beez
4
+ class Client
5
+
6
+ attr_reader :client
7
+
8
+ def initialize(url: ::Beez.config.zeebe_url, opts: :this_channel_is_insecure)
9
+ @client = ::Zeebe::Client::GatewayProtocol::Gateway::Stub.new(url, opts)
10
+ end
11
+
12
+ def activate_jobs(params = {})
13
+ run(:activate_jobs,
14
+ ::Zeebe::Client::GatewayProtocol::ActivateJobsRequest.new(params)
15
+ )
16
+ end
17
+
18
+ def cancel_workflow_instance(params = {})
19
+ run(:cancel_workflow_instance,
20
+ ::Zeebe::Client::GatewayProtocol::CancelWorkflowInstanceRequest.new(params)
21
+ )
22
+ end
23
+
24
+ def complete_job(params = {})
25
+ run(:complete_job,
26
+ ::Zeebe::Client::GatewayProtocol::CompleteJobRequest.new(params)
27
+ )
28
+ end
29
+
30
+ def create_workflow_instance(params = {})
31
+ run(:create_workflow_instance,
32
+ ::Zeebe::Client::GatewayProtocol::CreateWorkflowInstanceRequest.new(params)
33
+ )
34
+ end
35
+
36
+ def deploy_workflow(params = {})
37
+ run(:deploy_workflow,
38
+ ::Zeebe::Client::GatewayProtocol::DeployWorkflowRequest.new(params)
39
+ )
40
+ end
41
+
42
+ def fail_job(params = {})
43
+ run(:fail_job,
44
+ ::Zeebe::Client::GatewayProtocol::FailJobRequest.new(params)
45
+ )
46
+ end
47
+
48
+ def throw_error(params = {})
49
+ run(:throw_error,
50
+ ::Zeebe::Client::GatewayProtocol::ThrowErrorRequest.new(params)
51
+ )
52
+ end
53
+
54
+ def publish_message(params = {})
55
+ run(:publish_message,
56
+ ::Zeebe::Client::GatewayProtocol::PublishMessageRequest.new(params)
57
+ )
58
+ end
59
+
60
+ def resolve_incident(params = {})
61
+ run(:resolve_incident,
62
+ ::Zeebe::Client::GatewayProtocol::ResolveIncidentRequest.new(params)
63
+ )
64
+ end
65
+
66
+ def set_variables(params = {})
67
+ run(:set_variables,
68
+ ::Zeebe::Client::GatewayProtocol::SetVariablesRequest.new(params)
69
+ )
70
+ end
71
+
72
+ def topology(params = {})
73
+ run(:topology,
74
+ ::Zeebe::Client::GatewayProtocol::TopologyRequest.new(params)
75
+ )
76
+ end
77
+
78
+ def update_job_retries(params = {})
79
+ run(:update_job_retries,
80
+ ::Zeebe::Client::GatewayProtocol::UpdateJobRetriesRequest.new(params)
81
+ )
82
+ end
83
+
84
+ private
85
+
86
+ def run(method, params = {})
87
+ client.public_send(method, params)
88
+ rescue ::GRPC::Unavailable => exception
89
+ logger.error exception.message
90
+ raise exception
91
+ end
92
+
93
+ def logger
94
+ ::Beez.logger
95
+ end
96
+ end
97
+ end