EzDevInfo.com

goliath

Goliath is a non-blocking Ruby web server framework Goliath

how to send_data or attached file with goliath and grape?

not sure how this is done, but following how's its done in Sinatra wouldn't cut it on Goliath - How can I send binary data from Sinatra?


Source: (StackOverflow)

How do Goliath or EventMachine switch context?

Assume I have an I/O-bounded operations. I do have a callbacks (or em-synchrony)

  1. How does EM switch to proccess next request keeping previous one waiting for callback?
  2. How does it keep Thread.current variables isolated?
  3. How can I emulate long running jobs?

Source: (StackOverflow)

Advertisements

Async web processing using Goliath

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)

Suggested Redis driver for use within Goliath?

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)

Goliath not being asynchronous

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)

How to achieve strong parameter protection without Rails?

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)

how to get Goliath::Runner instance port in Goliath?

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)

Ruby goliath non-blocking server mapping

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)

any example on Goliath + OmniAuth

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)

Goliath + Redis: Testing sequence of requests

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)

How to do HTTP authentication with Goliath/Heroku?

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)

Goliath breaks em-synchrony/em-hiredis when multiple with_api() tests are called in one RSpec suite

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)

Access Rails models inside a different module

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)

Multiple subscribers with EM-WebSocket or Goliath

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)

Silencing errors in Grape/Goliath

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)