armstrong 0.4.1 → 0.4.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +33 -10
- data/Rakefile +2 -3
- data/armstrong.gemspec +1 -1
- data/demo/armstrong_test.rb +5 -0
- data/lib/armstrong/connection.rb +12 -0
- metadata +4 -4
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Armstrong #
|
2
|
-
An evented, fiber-based server for Ruby. This project
|
2
|
+
An evented, fiber-based server for Ruby. This project was inspired by [Brubeck](http://brubeck.io) and [Sinatra](http://www.sinatrarb.com/). The goal was to make it really easy to make an evented server that acted quick and scaled infinitely. This is accomplished by using [Mongrel2](http://mongrel2.org), [ZeroMQ](http://zeromq.org) and [Rubinius](rubini.us). Rubinius has the actor gem included already so it makes it really convenient to just use rubinius. Also, the 2.0.0dev branch has super nice thread handling, allowing for true Ruby concurrency that MRI just can't offer with its GIL.
|
3
3
|
|
4
4
|
## Mongrel2 and ZeroMQ ##
|
5
5
|
Although it seems like a strange direction to start writing servers in, eventually most companies end up in the realm of evented servers. This is because it offers nearly infinite scalability for free.
|
@@ -37,7 +37,7 @@ There's a sample `mongrel2.conf` and `config.sqlite` in the `demo` folder, feel
|
|
37
37
|
|
38
38
|
## minimal example ##
|
39
39
|
|
40
|
-
require '
|
40
|
+
require 'armstrong'
|
41
41
|
|
42
42
|
get "/" do
|
43
43
|
"hello world"
|
@@ -64,23 +64,46 @@ You can also return other codes and custom headers by returning an array with th
|
|
64
64
|
|
65
65
|
## benchmarking ##
|
66
66
|
|
67
|
+
#### Armstrong ####
|
67
68
|
$ siege -d 1 -c 150 -t 10s localhost:6767/
|
68
69
|
** SIEGE 2.70
|
69
70
|
** Preparing 150 concurrent users for battle.
|
70
71
|
The server is now under siege...
|
71
72
|
Lifting the server siege... done.
|
72
|
-
Transactions:
|
73
|
-
Availability:
|
74
|
-
Elapsed time:
|
75
|
-
Data transferred:
|
76
|
-
Response time:
|
77
|
-
Transaction rate:
|
78
|
-
Throughput:
|
79
|
-
Concurrency:
|
73
|
+
Transactions: 5029 hits
|
74
|
+
Availability: 100.00 %
|
75
|
+
Elapsed time: 9.06 secs
|
76
|
+
Data transferred: 0.05 MB
|
77
|
+
Response time: 0.26 secs
|
78
|
+
Transaction rate: 555.08 trans/sec
|
79
|
+
Throughput: 0.01 MB/sec
|
80
|
+
Concurrency: 146.56
|
80
81
|
Successful transactions: 5029
|
81
82
|
Failed transactions: 0
|
82
83
|
Longest transaction: 0.67
|
83
84
|
Shortest transaction: 0.02
|
85
|
+
|
86
|
+
#### Sinatra ####
|
87
|
+
|
88
|
+
_These benchmarks were done using Rubinius as the Ruby interpreter. You will get much better results for sinatra with MRI 1.9.2 but the concurrency will still plateau at about 110. I could not start up more than 110 concurrent users without sinatra closing all connections and blowing up._
|
89
|
+
|
90
|
+
$ siege -d1 -c 110 -t 10s localhost:4567/
|
91
|
+
** SIEGE 2.70
|
92
|
+
** Preparing 20 concurrent users for battle.
|
93
|
+
The server is now under siege...
|
94
|
+
Lifting the server siege... done.
|
95
|
+
Transactions: 1192 hits
|
96
|
+
Availability: 97.23 %
|
97
|
+
Elapsed time: 9.39 secs
|
98
|
+
Data transferred: 0.01 MB
|
99
|
+
Response time: 0.70 secs
|
100
|
+
Transaction rate: 126.94 trans/sec
|
101
|
+
Throughput: 0.00 MB/sec
|
102
|
+
Concurrency: 88.98
|
103
|
+
Successful transactions: 1192
|
104
|
+
Failed transactions: 34
|
105
|
+
Longest transaction: 1.39
|
106
|
+
Shortest transaction: 0.20
|
84
107
|
|
85
108
|
## License ##
|
86
109
|
GPLv3
|
data/Rakefile
CHANGED
@@ -18,9 +18,8 @@ namespace :g do
|
|
18
18
|
desc "Push gem"
|
19
19
|
task :p do
|
20
20
|
Rake::Task["g:b"].invoke
|
21
|
-
gem_file = `ls *.gem`.to_a.
|
21
|
+
gem_file = `ls *.gem`.to_a.last.chomp
|
22
22
|
puts "pushing #{gem_file}"
|
23
|
-
|
24
|
-
`gem push #{gem_file}`
|
23
|
+
puts `gem push #{gem_file}`
|
25
24
|
end
|
26
25
|
end
|
data/armstrong.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Gem::Specification.new 'armstrong', '0.4.
|
1
|
+
Gem::Specification.new 'armstrong', '0.4.5' do |s|
|
2
2
|
s.description = "Armstrong is an Mongrel2 fronted, actor-based web development framework similar in style to sinatra. With natively-threaded interpreters (Rubinius2), Armstrong provides true concurrency and high stability, by design."
|
3
3
|
s.summary = "Highly concurrent, sinatra-like framework"
|
4
4
|
s.author = "Artem Titoulenko"
|
data/demo/armstrong_test.rb
CHANGED
data/lib/armstrong/connection.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'ffi'
|
2
2
|
require 'ffi-rzmq'
|
3
3
|
require 'json'
|
4
|
+
require 'cgi'
|
4
5
|
|
5
6
|
class Connection
|
6
7
|
attr_reader :app_id, :sub_addr, :pub_addr, :request_sock, :response_sock, :context
|
@@ -81,9 +82,20 @@ class Connection
|
|
81
82
|
env[:body], _ = parse_netstring(head_rest)
|
82
83
|
|
83
84
|
env[:headers] = JSON.parse(env[:headers])
|
85
|
+
if(env[:headers]["METHOD"] == "POST")
|
86
|
+
env[:post] = parse_params(env)
|
87
|
+
end
|
88
|
+
|
84
89
|
return env
|
85
90
|
end
|
86
91
|
|
92
|
+
def parse_params(env)
|
93
|
+
r = {}
|
94
|
+
m = env[:body].scan(/(\w+)=(.*?)(?:&|$)/)
|
95
|
+
m.each { |k| r[CGI::unescape(k[0].to_s)] = CGI::unescape(k[1]) }
|
96
|
+
return r
|
97
|
+
end
|
98
|
+
|
87
99
|
# From WEBrick: thanks dawg.
|
88
100
|
StatusMessage = {
|
89
101
|
100 => 'Continue',
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: armstrong
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3072838298281563226
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 0.4.
|
9
|
+
- 5
|
10
|
+
version: 0.4.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Artem Titoulenko
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-11-
|
18
|
+
date: 2011-11-23 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: ffi
|