goliath
Goliath is a non-blocking Ruby web server framework
Goliath
Assume I have an I/O-bounded operations. I do have a callbacks (or em-synchrony)
- How does EM switch to proccess next request keeping previous one waiting for callback?
- How does it keep Thread.current variables isolated?
- How can I emulate long running jobs?
Source: (StackOverflow)
I need a a simple webserver which parses the url it receives, calls som other ruby scripts which do some heavy processing and thereafter return the resulting JSON.
Is Goliath appropriate for this? As far as I can see the requests are being handled sequentially. What should I do to get this right?
class MyServer < Goliath::API
def response(env)
res = create_json_response(env["REQUEST_URI"])
[200, {}, res]
end
end
Source: (StackOverflow)
There seem to be several options for establishing Redis connections for use within EventMachine, and I'm having a hard time understanding the core differences between them.
My goal is to implement Redis within Goliath
The way I establish my connection now is through em-synchrony:
require 'em-synchrony'
require 'em-synchrony/em-redis'
config['redis'] = EventMachine::Synchrony::ConnectionPool.new(:size => 20) do
EventMachine::Protocols::Redis.connect(:host => 'localhost', :port => 6379)
end
What is the difference between the above, and using something like em-hiredis?
If I'm using Redis for sets and basic key:value storage, is em-redis the best solution for my scenario?
Source: (StackOverflow)
I am running a simple goliath server on my localhost with Ruby 1.9.3, and it's not running http requests asynchronously. Here's the code:
require 'goliath'
require 'em-synchrony'
require 'em-synchrony/em-http'
class Server < Goliath::API
use Goliath::Rack::Validation::RequestMethod, %w(GET PUT POST)
def initialize
super
puts "Started up Bookcover server... Let 'em come!"
end
def response(env)
thumbnail_cover_url, large_book_cover_url = ["http://riffle-bookcovers.s3.amazonaws.com/B00GJYXA5I-thumbnail.jpg", "http://riffle-bookcovers.s3.amazonaws.com/B00GJYXA5I-original.jpg"]
puts "start"
a = EM::HttpRequest.new(thumbnail_cover_url).get
b = EM::HttpRequest.new(large_book_cover_url).get
puts "done"
[200, {}, "Hello World"]
end
end
When I run ab -n 100 http://127.0.0.1:9000/
I can see it waits for each request to be done, which means that the calls are blocking.
However, according to the documentation Goliath uses Em-synchrony to let me write "synchronous-looking" code, which is not the case here.
I would appreciate any hints and comments!
Source: (StackOverflow)
I am developing a boilerplate web application with Goliath + Grape + Active Record 4.2 + Active Record Migrations. Here is my migration file
# db/migrate/20150519063210_create_albums.rb
class CreateAlbums < ActiveRecord::Migration
def change
create_table :albums do |t|
t.string :name
t.string :artist
t.string :genre
t.date :published_at
end
end
end
And my model
# app/models/Album
class Album < ActiveRecord::Base
end
And the Grape API
class ApiV1 < Grape::API
version 'v1', using: :path
format :json
resource 'albums' do
get '/' do
Album.all
end
post '/' do
Album.create(params[:album]) # <-- raises ActiveModel::ForbiddenAttributesError
end
end
end
When I call POST /v1/albums/
with some parameters, the application always raises ActiveModel::ForbiddenAttributesError
. It seem that ActiveRecord wants ActionController::Parameters
to be the arguments, but Grape gives it Hashie::Mash
.
I've tried implementing a simple Rack middleware to convert env['params']
from a Hash
to a ActionController::Parameters
and using it after Goliath::Rack::Params
, but Grape just sanitizes it out when the helper method params
is called. I also tried implementing and using a Grape middleware to do the same thing and got the same result.
Is there any solution on this or I just have to down grade to ActiveRecord 3?
Source: (StackOverflow)
I am trying to grab server's port outside a request controller in Goliath, which means I cannot access env['SERVER_PORT']
.
So I tried to parse ARGV
, turns out it's empty
I found there's a port
property of Goliath::Runner
, but how to refer to the current runner instance in Goliath?
Source: (StackOverflow)
I am trying out goliath non-blocking ruby server.
For my application I need to make at least 2 defined routes, lets say "/call_one" and "/call_two", each map should respond in a different manner.
Goliath documentation mentions map function which is exactly what I need. But it no longer exists in source.
Source: (StackOverflow)
basically my last attempt was im getting this error:
[:error, "bad URI(is not URI?): ://localhost:80/auth/twitter/auth/twitter"]
when i browse to
http://127.0.0.1/auth/twitter
this is my goliath server
class Application < Goliath::API
use(Rack::Session::Cookie
use OmniAuth::Strategies::Developer
use OmniAuth::Builder do
provider :twitter, '..', '..'
provider :facebook, '..', '..'
provider :developer
end
end
interestingly /auth/developer has no issues - but twitter or facebook has.
Any ideas?
Source: (StackOverflow)
I wrote an endpoint that has two operations: PUT and GET. GET retrieves what was PUT, so a good way to ensure both work would be to test them in sequence.
My cURL testing tells me the service works. However, I can't get my test that does the same thing to pass!
it "accepts authenticated PUT data" do
attributes1 = {
user: {
lat: '12.34',
lng: '56.78'
}
}
with_api(Location, { log_stdout: true, verbose: true }) do
put_request({ query: { auth_token: 'abc' }, body: attributes1.to_json }) do |client|
client.response_header.status.must_equal 201
get_request({ query: { auth_token: 'abc' } }) do |client|
client.response_header.status.must_equal 200
client.response.must_match_json_expression([attributes1[:user]])
end
end
end
end
Note that PUT accepts JSON in the body, and GET returns JSON. The service uses Redis as the datastore, and I use mock_redis to mock it.
test_helper.rb:
$redis = MockRedis.new
class Goliath::Server
def load_config(file = nil)
config['redis'] = $redis
end
end
top of spec:
before do
$redis.flushdb
end
The GET should retrieve what was just PUT, but instead it retrieves JSON "null".
Am I doing anything obviously wrong? Perhaps with how I am passing along body data to the request?
It would definitely help to get some better logging when my tests are running. I tried the { log_stdout: true, verbose: true } options, but this still only seems to output basic INFO logging from the Goliath server, which doesn't tell me anything about data and params.
Any help would be appreciated!
Source: (StackOverflow)
I'm using Goliath as my app server, and I am trying to convert "Ruby – Secure staging environment of your public app from users and bots" so it applies to my Goliath application.
I am trying to use Rack::Static
but I'm not sure how to write the code. I was trying something like:
class Application < Goliath::API
use(Rack::Lock)
But I am not really sure how to translate the link I posted.
I'm open to other alternatives, I just need my whole site password protected.
Source: (StackOverflow)
I'm just experiencing weird behavior while testing an Goliath API with RSpec. One of my tests looks like this:
require 'helper'
describe Scales::Dispatch do
it "should return a 404 if resource was not found" do
with_api(Scales::Server) do
get_request(:path => '/') do |client|
client.response_header.http_status.should == 404
end
end
end
it "should return a resource" do
Scales::Storage::Sync.set "/existing", "some content"
with_api(Scales::Server) do
get_request(:path => '/existing') do |client|
client.response_header.http_status.should == 200
client.response.should == "some content"
end
end
Scales::Storage::Sync.del "/existing"
end
end
The API basically just looks up a key in a redis with the help of em-synchrony/em-hiredis
like this:
module Scales
module Lookup
class << self
def request(env)
response = Storage::Async.get(path(env))
response.nil? ? render_not_found : render(response)
end
private
def path(env)
env["REQUEST_URI"]
end
def render_not_found
[404, {}, ""]
end
def render(response)
[200, {}, response]
end
end
end
end
Both tests run individually, but not together. After the first is executed, the whole system stalls about 10 seconds. The second with_api is then called but the get_request is never executed - and i think it is running in some sort of timeout.
I discovered the same behavior at another, pretty similar test which is pushing and popping a queue like this:
describe Scales::Queue::Async do
[Scales::Queue::Async::Request, Scales::Queue::Async::Response].each do |queue|
context queue.name.split("::").last do
it "should place a few jobs" do
async do
queue.add "job 1"
queue.add "job 2"
queue.add "job 3"
end
end
it "should take them out blocking" do
async do
queue.pop.should == "job 1"
queue.pop.should == "job 2"
queue.pop.should == "job 3"
end
end
end
end
end
The contents of second async do ..
is also not executed at all. Without goliath loaded a pretty similar test runs perfectly:
require 'eventmachine'
require 'em-synchrony'
require 'em-synchrony/em-hiredis'
module Helpers
def async
if EM.reactor_running?
yield
else
out = nil
EM.synchrony do
out = yield
EM.stop
end
out
end
end
end
RSpec.configure do |config|
config.include Helpers
config.treat_symbols_as_metadata_keys_with_true_values = true
end
describe "em-synchrony/em-hiredis" do
it "should lpush a job" do
async do
redis = EM::Hiredis.connect
redis.lpush("a_queue", "job1")
end
end
it "should block pop a job" do
async do
redis = EM::Hiredis.connect
redis.brpop("a_queue", 0).last.should == "job1"
end
end
end
The async do ..
for the previous task is the same RSpec helper.
I was searching the whole day like crazy, but to me it doesn't make any sense. Because the last test is running completely fine, I guess its neither a em-synchrony
nor a em-synchrony/em-hiredis
thing.
Maybe goliath is not stopping, occupying the EM somewhat too long or so?
Thanks for your help, this is driving me nuts!
Source: (StackOverflow)
I'm writing a web service for my Rails app using Goliath and I want to log all the requests sent to my web server. I have this Api
class which is inside two modules:
require 'goliath'
module WebService
module Rest
class Api < Goliath::API
def response(env)
# Log the request
Logger.create(id: params['id'], type: params['type'])
[200, {}, "success"]
end
end
end
I have a model in app/models
named Logger
. The problem is when I run ruby api.rb -sv
it throws an error:
uninitialized constant WebService::Rest::Api::Logger
What should I do? Thanks.
Source: (StackOverflow)
So I'm attempting to setup em-websocket (or potentially Goliath), so that users can come to a different route and thusly be subscribed to only that channel, so for example:
example.com/channel_1
Browsers open there will only receive messages published to channel_1
, actually to that point it doesn't have to be a route like this I'd settle for using params. So I'm using AMQP and it has the notion of a direct exchange, and routing keys. Is there something analogous to that with websockets?
I've got a Goliath server working but the issue is, that because it uses shared endpoints, I think that all the browsers open with a websocket connection are getting the same messages, here's what I'm doing:
channel.queue(params['channel'], :auto_delete => true).subscribe do |payload|
config['channel'].push(payload)
end
So this example uses AMQP, which I'd still like to use, but the issue I think lies in that each client is reinstantiating EM::Channel.new
, and then the messages are pushed to that channel, I just don't understand how I would have multiple clients subscribed to different channels.
Any help understanding this or guiding me to a more appropriate design pattern.
Source: (StackOverflow)
I'm working with a Grape API running on Goliath. Currently, if a method returns an error for some reason, the client receives a 500 – and the exact error raised!
How can I silence the output from the API and just have it return a generic 500 error?
Source: (StackOverflow)