Skip to content

Commit 360e28b

Browse files
committed
merge master
2 parents 8ea448c + be04426 commit 360e28b

File tree

122 files changed

+4717
-593
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+4717
-593
lines changed

‎.gemtest‎

Whitespace-only changes.

‎.gitignore‎

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1-
Makefile
2-
mkmf.log
3-
*.o
4-
*.bundle
1+
Gemfile.lock
2+
3+
.bundle/
54
doc/
65
pkg/
7-
examples/log
8-
*.swp
9-
Gemfile.lock
6+
_site
7+
108
.yardoc
119
.livereload
10+
.rvmrc
11+
12+
*.swp
1213
*.watchr
1314
*.rbc
14-
.rvmrc
15-
_site
15+
16+
examples/log
17+
examples/goliath.log*
18+
examples/goliath.pid
19+
examples/rasterize/thumb

‎Gemfile‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
11
source"http://rubygems.org"
22

3-
gem'em-websocket',:git=>'http://github.com/dj2/em-websocket',:branch=>'factory_change'
4-
gem'http_parser.rb',:git=>'http://github.com/dj2/http_parser.rb',:branch=>'upgrade_data'
5-
63
gemspec

‎HISTORY.md‎

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# HISTORY
2+
3+
## v0.9.3 (Oct 16, 2011)
4+
5+
- new router DSL - much improved, see examples
6+
- refactored async_aroundware
7+
- make jruby friendlier (removed 1.9 req in gemspec)
8+
- enable epoll
9+
- SSL support
10+
- unix socket support
11+
- reload config on HUP
12+
- and a number of small bugfixes + other improvements..
13+
- See full list @ https://github.com/postrank-labs/goliath/compare/v0.9.2...v0.9.3
14+
15+
## v0.9.2 (July 21, 2011)
16+
17+
- See full list @ https://github.com/postrank-labs/goliath/compare/v0.9.1...v0.9.2
18+
19+
## v0.9.1 (Apr 12, 2011)
20+
21+
- Added extra messaging around the class not matching the file name (Carlos Brando)
22+
23+
- Fix issue with POST parameters not being parsed by Goliath::Rack::Params
24+
- Added support for multipart encoded POST bodies
25+
- Added support for parsing nested query string parameters (Nolan Evans)
26+
- Added support for parsing application/json POST bodies
27+
- Content-Types outside of multipart, urlencoded and application/json will not be parsed automatically.
28+
29+
- added 'run as user' option
30+
- SERVER_NAME and SERVER_PORT are set to values in HOST header
31+
32+
- Cleaned up spec examples (Justin Ko)
33+
34+
- moved logger into 'rack.logger' key to be more Rack compliant (Env#logger added to
35+
keep original API consistent)
36+
- add command line option for specifying config file
37+
- HTTP_CONTENT_LENGTH and HTTP_CONTENT_TYPE were changed to CONTENT_TYPE and CONTENT_LENGTH
38+
to be more Rack compliant
39+
- fix issue with loading config file in development mode
40+
41+
- Rack::Reloader will be loaded automatically by the framework in development mode.
42+
43+
44+
## v0.9.0 (Mar 9, 2011)
45+
46+
(Initial Public Release)
47+
48+
Goliath is an open source version of the non-blocking (asynchronous) Ruby web server framework
49+
powering PostRank. It is a lightweight framework designed to meet the following goals: bare
50+
metal performance, Rack API and middleware support, simple configuration, fully asynchronous
51+
processing, and readable and maintainable code (read: no callbacks).
52+
53+
The framework is powered by an EventMachine reactor, a high-performance HTTP parser and Ruby 1.9
54+
runtime. One major advantage Goliath has over other asynchronous frameworks is the fact that by
55+
leveraging Ruby fibers, it can untangle the complicated callback-based code into a format we are
56+
all familiar and comfortable with: linear execution, which leads to more maintainable and readable code.
57+
58+
While MRI is the recommend platform, Goliath has been tested to run on JRuby and Rubinius.
59+
60+
Goliath has been in production at PostRank for over a year, serving a sustained 500 requests/s for
61+
internal and external applications. Many of the Goliath processes have been running for months at
62+
a time (read: no memory leaks) and have served hundreds of gigabytes of data without restarts. To
63+
scale up and provide failover and redundancy, our individual Goliath servers at PostRank are usually
64+
deployed behind a reverse proxy (such as HAProxy).

‎README.md‎

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,23 @@ Each HTTP request within Goliath is executed in its own Ruby fiber and all async
2020

2121
## Getting Started: Hello World
2222

23-
require 'goliath'
23+
```ruby
24+
require'goliath'
2425

25-
class Hello < Goliath::API
26-
# reload code on every request in dev environment
27-
use ::Rack::Reloader, 0 if Goliath.dev?
26+
classHello < Goliath::API
27+
defresponse(env)
28+
[200,{}, "Hello World"]
29+
end
30+
end
2831

29-
def response(env)
30-
[200,{}, "Hello World"]
31-
end
32-
end
32+
> ruby hello.rb -sv
33+
> [97570:INFO] 2011-02-1500:33:51 :: Starting server on 0.0.0.0:9000in development mode. Watch out for stones.
34+
```
3335

34-
> ruby hello.rb -sv
35-
> [97570:INFO] 2011-02-15 00:33:51 :: Starting server on 0.0.0.0:9000 in development mode. Watch out for stones.
36+
See examples directory for more, hands-on examples of building Goliath powered web-services. Are you new to EventMachine, or want a detailed walk-through of building a Goliath powered API? You're in luck, we have two super-awesome peepcode screencasts which will teach you all you need to know:
3637

37-
See examples directory for more, hands-on examples of building Goliath powered web-services.
38+
*[Meet EventMachine: Part 1](http://peepcode.com/products/eventmachine) - introduction to EM, Fibers, etc.
39+
*[Meet EventMachine: Part 2](http://peepcode.com/products/eventmachine-ii) - building an API with Goliath
3840

3941
## Performance: MRI, JRuby, Rubinius
4042

@@ -55,7 +57,7 @@ Goliath has been in production at PostRank for over a year, serving a sustained
5557
* Mongrel is a threaded web-server, and both Passenger and Unicorn fork an entire VM to isolate each request from each other. By contrast, Goliath builds a single instance of the Rack app and runs all requests in parallel through a single VM, which leads to a much smaller memory footprint and less overhead.
5658

5759
* How do I deploy Goliath in production?
58-
* We recommend deploying Goliath behind a reverse proxy such as HAProxy, Nginx or equivalent. Using one of the above, you can easily run multiple instances of the same application and load balance between them within the reverse proxy.
60+
* We recommend deploying Goliath behind a reverse proxy such as HAProxy ([sample config](https://github.com/postrank-labs/goliath/wiki/HAProxy)), Nginx or equivalent. Using one of the above, you can easily run multiple instances of the same application and load balance between them within the reverse proxy.
5961

6062
## Guides
6163

@@ -66,6 +68,7 @@ Goliath has been in production at PostRank for over a year, serving a sustained
6668

6769
### Hands-on applications:
6870

71+
*[Peepcode](http://peepcode.com/products/eventmachine)[screencasts](http://peepcode.com/products/eventmachine-ii)
6972
*[Asynchronous HTTP, MySQL, etc](https://github.com/postrank-labs/goliath/wiki/Asynchronous-Processing)
7073
*[Response streaming with Goliath](https://github.com/postrank-labs/goliath/wiki/Streaming)
7174
*[Examples](https://github.com/postrank-labs/goliath/tree/master/examples)
@@ -74,6 +77,10 @@ Goliath has been in production at PostRank for over a year, serving a sustained
7477

7578
*[Goliath: Non-blocking, Ruby 1.9 Web Server](http://www.igvita.com/2011/03/08/goliath-non-blocking-ruby-19-web-server)
7679
*[Stage left: Enter Goliath - HTTP Proxy + MongoDB](http://everburning.com/news/stage-left-enter-goliath/)
80+
*[InfoQ: Meet the Goliath of Ruby Application Servers](http://www.infoq.com/articles/meet-goliath)
81+
*[Node.jsはコールバック・スパゲティを招くか](http://el.jibun.atmarkit.co.jp/rails/2011/03/nodejs-d123.html)
82+
*[Goliath on LinuxFr.org (french)](http://linuxfr.org/news/en-vrac-spécial-ruby-jruby-sinatra-et-goliath)
83+
*[Goliath et ses amis (slides in french)](http://nono.github.com/Presentations/20110416_Goliath/)
7784

7885
## Discussion and Support
7986

@@ -83,4 +90,5 @@ Goliath has been in production at PostRank for over a year, serving a sustained
8390

8491
## License & Acknowledgments
8592

86-
Goliath is distributed under the MIT license, for full details please see the LICENSE file.
93+
Goliath is distributed under the MIT license, for full details please see the LICENSE file.
94+
Rock favicon CC-BY from [Douglas Feer](http://www.favicon.cc/?action=icon&file_id=375421)

‎Rakefile‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ require 'yard'
55
require'rspec/core/rake_task'
66

77
task:default=>[:spec]
8+
task:test=>[:spec]
89

910
desc"run spec tests"
1011
RSpec::Core::RakeTask.new('spec')do |t|

‎examples/activerecord/srv.rb‎

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,9 @@ class User < ActiveRecord::Base
1919
end
2020

2121
classSrv < Goliath::API
22-
use ::Rack::Reloader,0ifGoliath.dev?
23-
2422
useGoliath::Rack::Params
2523
useGoliath::Rack::DefaultMimeType
26-
useGoliath::Rack::Formatters::JSON
27-
useGoliath::Rack::Render
28-
useGoliath::Rack::ValidationError
24+
useGoliath::Rack::Render,'json'
2925

3026
useGoliath::Rack::Validation::RequiredParam,{:key=>'id',:type=>'ID'}
3127
useGoliath::Rack::Validation::NumericRange,{:key=>'id',:min=>1}

‎examples/api_proxy.rb‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env ruby
2+
3+
# Rewrites and proxies requests to a third-party API, with HTTP basic authentication.
4+
5+
require'goliath'
6+
require'em-synchrony/em-http'
7+
8+
classTwilioResponse < Goliath::API
9+
useGoliath::Rack::Params
10+
useGoliath::Rack::JSONP
11+
12+
HEADERS={authorization: ENV.values_at("TWILIO_SID","TWILIO_AUTH_TOKEN")}
13+
BASE_URL="https://api.twilio.com/2010-04-01/Accounts/#{ENV['TWILIO_SID']}/AvailablePhoneNumbers/US"
14+
15+
defresponse(env)
16+
url="#{BASE_URL}#{env['REQUEST_PATH']}?#{env['QUERY_STRING']}"
17+
logger.debug"Proxying #{url}"
18+
19+
http=EM::HttpRequest.new(url).gethead: HEADERS
20+
logger.debug"Received #{http.response_header.status} from Twilio"
21+
22+
[200,{'X-Goliath'=>'Proxy','Content-Type'=>'application/javascript'},http.response]
23+
end
24+
end
25+
26+
classTwilio < Goliath::API
27+
get%r{^/(Local|TollFree)},TwilioResponse
28+
end

‎examples/async_aroundware_demo.rb‎

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env ruby
2+
$: << File.dirname(__FILE__)+'/../lib'
3+
4+
require'goliath'
5+
require'em-synchrony/em-http'
6+
require'yajl/json_gem'
7+
8+
#
9+
# Here's a way to make an asynchronous request in the middleware, and only
10+
# proceed with the response when both the endpoint and our middleware's
11+
# responses have completed.
12+
#
13+
# To run this, start the 'test_rig.rb' server on port 9002:
14+
#
15+
# bundle exec ./examples/test_rig.rb -sv -p 9002
16+
#
17+
# And then start this server on port 9000:
18+
#
19+
# bundle exec ./examples/barrier_aroundware_demo.rb -sv -p 9000
20+
#
21+
# Now curl the async_aroundware_demo_multi:
22+
#
23+
# $ time curl 'http://127.0.0.1:9000/?delay_1=1.0&delay_2=1.5'
24+
#{"results":{
25+
# "sleep_2":{"delay": 1.5, "actual": 1.5085558891296387 },
26+
# "sleep_1":{"delay": 1.0, "actual": 1.0098700523376465 }
27+
# } }
28+
#
29+
# The requests are run concurrently:
30+
#
31+
# $ ./examples/async_aroundware_demo.rb -sv -p 9000 -e prod &
32+
# [68463:INFO] 2011-05-03 23:13:03 :: Starting server on 0.0.0.0:9000 in production mode. Watch out for stones.
33+
# $ ab -n10 -c10 'http://127.0.0.1:9000/?delay_1=1.5&delay_2=2.0'
34+
# Connection Times (ms)
35+
# min mean[+/-sd] median max
36+
# Connect: 0 0 0.1 0 0
37+
# Processing: 2027 2111 61.6 2112 2204
38+
# Waiting: 2027 2111 61.5 2112 2204
39+
# Total: 2027 2112 61.5 2113 2204
40+
#
41+
#
42+
43+
BASE_URL='http://localhost:9002/'
44+
45+
classRemoteRequestBarrier
46+
includeGoliath::Rack::BarrierAroundware
47+
attr_accessor:sleep_1
48+
49+
defpre_process
50+
# Request with delay_1 and drop_1 -- note: 'aget', because we want execution to continue
51+
req=EM::HttpRequest.new(BASE_URL).aget(:query=>{:delay=>env.params['delay_1'],:drop=>env.params['drop_1']})
52+
enqueue:sleep_1,req
53+
returnGoliath::Connection::AsyncResponse
54+
end
55+
56+
defpost_process
57+
# unify the results with the results of the API call
58+
ifsuccesses.include?(:sleep_1)thenbody[:results][:sleep_1]=JSON.parse(sleep_1.response)
59+
elsebody[:errors][:sleep_1]=sleep_1.error;end
60+
[status,headers,JSON.pretty_generate(body)]
61+
end
62+
end
63+
64+
classBarrierAroundwareDemo < Goliath::API
65+
useGoliath::Rack::Params
66+
useGoliath::Rack::Validation::NumericRange,{:key=>'delay_1',:default=>1.0,:max=>5.0,:min=>0.0,:as=>Float}
67+
useGoliath::Rack::Validation::NumericRange,{:key=>'delay_2',:default=>0.5,:max=>5.0,:min=>0.0,:as=>Float}
68+
#
69+
useGoliath::Rack::BarrierAroundwareFactory,RemoteRequestBarrier
70+
71+
defresponse(env)
72+
# Request with delay_2 and drop_2 -- note: 'get', because we want execution to proceed linearly
73+
resp=EM::HttpRequest.new(BASE_URL).get(:query=>{:delay=>env.params['delay_2'],:drop=>env.params['drop_2']})
74+
75+
body={:results=>{},:errors=>{}}
76+
77+
ifresp.response_header.status.to_i != 0
78+
body[:results][:sleep_2]=JSON.parse(resp.response)rescue'parsing failed'
79+
else
80+
body[:errors][:sleep_2]=resp.error
81+
end
82+
83+
[200,{},body]
84+
end
85+
end

‎examples/async_upload.rb‎

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,9 @@
55
require'yajl'
66

77
classAsyncUpload < Goliath::API
8-
9-
# reload code on every request in dev environment
10-
use ::Rack::Reloader,0ifGoliath.dev?
11-
128
useGoliath::Rack::Params# parse & merge query and body parameters
139
useGoliath::Rack::DefaultMimeType# cleanup accepted media types
14-
useGoliath::Rack::Formatters::JSON# JSON output formatter
15-
useGoliath::Rack::Render# auto-negotiate response format
10+
useGoliath::Rack::Render,'json'# auto-negotiate response format
1611

1712
defon_headers(env,headers)
1813
env.logger.info'received headers: ' + headers.inspect

0 commit comments

Comments
(0)