How do i solve ruby grpc health check NOTFOUND error? - ruby

I am getting this error when perform following for health check:
require 'grpc/health/v1/health_pb'
require 'grpc/health/checker'
class HealthCheckService < Grpc::Health::V1::Health::Service
def check(req, req_view)
checker = Grpc::Health::Checker.new
checker.check(req, req_view)
end
end
Error is:
GRPC::NotFound:5:unknown cause.
Anyone has faced this issue before. really would appreciate for help.

Have you installed grpc and gprc-tools?
gem install grpc
gem install grpc-tools
I'm entirely unfamiliar with Ruby but familiar with gRPC.
Your code (with a tweak) works for me:
require 'grpc/health/v1/health_pb'
require 'grpc/health/checker'
class HealthCheckService < Grpc::Health::V1::Health::Service
def check(req, req_view)
checker = Grpc::Health::Checker.new
checker.set_status_for_services(
Grpc::Health::V1::HealthCheckResponse::ServingStatus::SERVING,
"foo",
"bar"
)
checker.check(req, req_view)
end
end
def main
s = GRPC::RpcServer.new
s.add_http2_port("0.0.0.0:50051",:this_port_is_insecure)
s.handle(HealthCheckService)
s.run_till_terminated_or_interrupted([1,"int","SIGQUIT"])
end
main
And then, downloading health.proto, I can:
for SERVICE in "foo" "bar" "baz"
do
grpcurl \
-plaintext \
--proto health.proto \
-d "{\"service\":\"${SERVICE}\"}" \
localhost:50051 \
grpc.health.v1.Health/Check
{
"status": "SERVING"
}
{
"status": "SERVING"
}
ERROR:
Code: NotFound
Message: unknown cause

Related

using the ruby gem and just sinatra and ruby (not rails), how can I connect to a bonsai elasticsearch instance?

I am trying to get up and running with bonsai. I intend to use sinatra and ruby (not rails) although right now I am just trying to connect from my local machine. The script is:
require "csv"
require "elasticsearch"
require 'elasticsearch/transport'
Elasticsearch::Model.client = Elasticsearch::Client.new url: 'https://uz09z96il1:5g9p3h8jow#hectors-first-starte-5298580603.us-west-2.bonsai.io', log: true
#Elasticsearch::Client.new host: 'https://uz09z96il1:5g9p3h8jow#hectors-first-starte-5298580603.us-west-2.bonsai.io', log: true
#Elasticsearch::Model.client = Elasticsearch::Client.new('https://uz09z96il1:5g9p3h8jow#hectors-first-starte-5298580603.us-west-2.bonsai.io')
#client = Elasticsearch::Client.new log: true
#Elasticsearch::Model.client = Elasticsearch::Client.new url: 'https://uz09z96il1:5g9p3h8jow#hectors-first-starte-5298580603.us-west-2.bonsai.io', log: true
CSV.open("candidates.csv", "r") do |f|
f.each_with_index do |item, i|
next if i == 0
p item
client.index index: 'data', type: 'person', body: '{
"first": "#{item[1]}",
"last": "#{item[2]}"
}'
end
end
The basic error is that connection is refused, in this particular example like so:
uninitialized constant Elasticsearch::Model (NameError)
As you can see, from the commented out lines, I have tried as many variations as I can think of.
What's the best way to accomplish this? All help gratefully received, thank you.
You are getting
uninitialized constant Elasticsearch::Model (NameError)
because you haven't included the proper class. Try adding:
require 'elasticsearch/model'
At the top of your code.

How can I solve these problems I'm having with the stretcher and faraday gems?

On my local machine, I am using elasticsearch, ruby, sinatra and the stretcher gem.
I get the following error:
faraday.rb:99:in `method_missing': undefined method `load_autoloaded_constants' for #<Faraday::Connection:0x9b9f218> (NoMethodError)
The truncated ruby code is:
require 'sinatra'
require 'stretcher'
configure do
ES = Stretcher::Server.new('http://localhost:9200')
end
class Products
def self.match(text)
ES.index(:products).search size: 1000, query: {
multi_match: { query: text, fields: [:title, :description] }
}
end
end
get "/" do
erb :index
end
get "/:search" do
erb :result, locals: { products: Products.match(params[:search]) }
end
post "/" do
unless ES.index(:products).exists?
# create index if not exists
ES.index(:products).create(mappings: {
product: {
properties: {
title: {type: :string},
price: {type: :integer},
description: {type: :string}
}
}
})
end
All help gratefully received.
When I install stretcher it installs faraday_middleware-multi_json 0.0.6 and faraday 0.9.0 and faraday_middleware 0.9.1 by default.
I think many of us are facing this issue but I haven't found a single place where you will get a proper instructions.
Steps to resolve "faraday method missing: load_autoloaded_constants" error
1. go to command line and open stretcher folder under gems folder
sudo subl /home/abhinay/.rvm/gems/ruby-2.1.1/gems/stretcher-1.21.1/
2. Open lib/stretcher.rb
Add this line: require 'multi_json' # line 5
Remove these line:
require 'faraday_middleware/multi_json' # line 7
Faraday.load_autoloaded_constants # line 8
3. Open lib/stretcher/server.rb
change
builder.response :multi_json, :content_type => /\bjson$/ #line 9
to
builder.response :json, :content_type => /\bjson$/
and
builder.request :multi_json
to
builder.request :json # line 11
4. Open spec/lib/stretcher_index_spec.rb
change #line 44
block.call.should == %{curl -XPUT 'http://localhost:9200/foo' -d '#{MultiJson.dump(options)}' '-H Accept: application/json' '-H Content-Type: application/json' '-H User-Agent: Stretcher Ruby Gem #{Stretcher::VERSION}'}
to
block.call.should == %{curl -XPUT 'http://localhost:9200/foo' -d '#{JSON.dump(options)}' '-H Accept: application/json' '-H Content-Type: application/json' '-H User-Agent: Stretcher Ruby Gem #{Stretcher::VERSION}'}
5. Open stretcher.gemspec change #line 30
gem.add_dependency('faraday_middleware', '~> 0.9.0')
to
gem.add_dependency('faraday_middleware', '~> 0.9')
and Remove these lines # line 33 & 34
gem.add_dependency('multi_json', '>= 1.0')
gem.add_dependency('faraday_middleware-multi_json', "~> 0.0.5")
I believe this is a known Stretcher issue. Refer to https://github.com/PoseBiz/stretcher/pull/85
Options:
1) Use the prior version of Faraday, e.g. Gemfile with:
gem 'faraday', '0.8.9'
2) Mirror the changes to address known Stretcher issue 85.
Use this fork/sha of stretcher: https://github.com/whatstherub/stretcher/commit/b09bce05e3ed07d47ab2a408e2ef674738dc8b28

How do I get Threads to work in ruby CGI

I have the following script (ruby 1.9.3), if I comment out the two Thread lines it works fine, if I leave them in I get a 500 Internal error on my webserver. Why does this not work in CGI, but work fine on the command line?
#!/usr/bin/ruby
require 'rubygems'
require 'cgi'
print "Content-type: text/html\n\n"
TIMEOUT = 8
def worker(data, results)
results[data] = rand(6)
end
if __FILE__ == $PROGRAM_NAME
results = {}
worker("abc", results)
t = Thread.new{ worker("xyz", results) }
t.join(TIMEOUT)
print results
print "done"
end
I would start with looking at the error logs from your webserver with the hopes of seeing what is causing the 501. I tried this on my server and it worked as expected.
Perhaps the webserver is starting up a different ruby or can't find the gems.
If you can't see it in the error logs, you could try catching errors with rescue, i.e.:
begin
t = Thread.new{ worker("xyz", results) }
t.join(TIMEOUT)
rescue => e
puts e.inspect
end

Ruby script does not work with weird errors about highline library

I have the following Ruby script:
begin
puts "What is the password? "
the_pass = ask("") { |q| q.echo = "*" }
end while the_pass == nil || the_pass == "\n" || the_pass == ""
And it fails when I hit Enter:
undefined method default_external' for REXML::Encoding:Module
/Library/Ruby/Gems/1.8/gems/highline-1.6.19/lib/highline.rb:621:in
say'
/Library/Ruby/Gems/1.8/gems/highline-1.6.19/lib/highline.rb:914:in
get_response'
/Library/Ruby/Gems/1.8/gems/highline-1.6.19/lib/highline.rb:259:in
ask'
Looks like it fails when validating the input for the_pass, but I cannot understand the error, how are they related?
Thanks
This is bad error handling in the HighLine gem for Ruby < 1.9.
The offending line (identified by your error message) is:
statement.force_encoding(Encoding.default_external) if defined?(Encoding) && Encoding.default_external
You can handle this by either:
Removing any include REXML commands in your script. This will keep REXML::Encoding from being associated with Encoding.
Adding the following line somewhere early in your script:
REXML::Encoding.instance_eval { def default_external; false; end }
This line will prevent the missing method error and will prevent HighLine from trying to force encoding where it shouldn't.

Ruby: Parse API Response

I am trying to geht this script to run: http://dysinger.net/2008/10/13/using-amazon-ec2-metadata-as-a-simple-dns but dosnt work because it is using an old amazon sdk version, i rewrote it to use the new one:
#!/usr/bin/env ruby
require "rubygems"
require "aws-sdk"
%w(optparse rubygems aws-sdk resolv pp).each {|l| require l}
options = {}
parser = OptionParser.new do |p|
p.banner = "Usage: hosts [options]"
p.on("-a", "--access-key USER", "The user's AWS access key ID.") do |aki|
options[:access_key_id] = aki
end
p.on("-s",
"--secret-key PASSWORD",
"The user's AWS secret access key.") do |sak|
options[:secret_access_key] = sak
end
p.on_tail("-h", "--help", "Show this message") {
puts(p)
exit
}
p.parse!(ARGV) rescue puts(p)
end
if options.key?(:access_key_id) and options.key?(:secret_access_key)
puts "127.0.0.1 localhost"
AWS.config(options)
AWS::EC2.new(options)
answer = AWS::EC2::Client.new.describe_instances
answer.reservationSet.item.each do |r|
r.instancesSet.item.each do |i|
if i.instanceState.name =~ /running/
puts(Resolv::DNS.new.getaddress(i.privateDnsName).to_s +
" #{i.keyName}.ec2 #{i.keyName}")
end
end
end
else
puts(parser)
exit(1)
end
What this should do is outputing a new /etc/hosts file with my ec2 instances in it.
And i get a response =D, but answer is a hash and therefore i get the
error undefined method `reservationSet' for #<Hash:0x7f7573b27880>.
And this is my problem, since i dont know Ruby at all ( All I was doing was reading Amazon Documentation and playing around so i get an answer ). Somehow in the original example this seemed to work. I suppose that back then, the API did not return a hash, anyway...how can i iterate through a hash like above, to get this to work?
This code may help you:
answer = AWS::EC2::Client.new.describe_instances
reservations = answer[:reservation_set]
reservations.each do |reservation|
instances = reservation[:instances_set]
instances.each do |instance|
if instance[:instance_state][:name] == "running"
private_dns_name = instance[:private_dns_name]
key_name = instance[:key_name]
address = Resolv::DNS.new.getaddress(private_dns_name)
puts "{address} #{key_name}.ec2 #{key_name}"
end
end
end
Generally change your code from using methods with names e.g. item.fooBarBaz to using a hash e.g. item[:foo_bar_baz]
When you're learning Ruby the "pp" command is very useful for pretty-printing variables as you go, such as:
pp reservations
pp instances
pp private_dns_name

Resources