oria 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ pkg/*
data/README.markdown CHANGED
@@ -3,12 +3,12 @@ Oria
3
3
 
4
4
  Oria (oh-rye-uh) is an in-memory, Ruby-based Key-Value Store. It's designed to handle moderate amounts of data quickly
5
5
  and easily without causing deployment issues or server headaches. It uses EventMachine to provide a networked interface
6
- to a semi-persistent KVS and asynchronously writes the in-memory data to YAML files.
6
+ to a semi-persistent store and asynchronously writes the in-memory data to YAML files.
7
7
 
8
8
  Installation
9
9
  -
10
10
 
11
- Oria is a provided as a Gem. Use the following command to install it:
11
+ Oria is provided as a Gem. Use the following command to install it:
12
12
 
13
13
  gem install oria --source http://gemcutter.org
14
14
 
@@ -41,7 +41,7 @@ untested, so please test it heavily before deploying, and _report any issues you
41
41
  Usage
42
42
  -
43
43
 
44
- Okay, now for the fun part. Oria behaves (mostly) like a Hash - you could say that it responds to 2/3 of @wycats' Moneta
44
+ Okay, now for the fun part. Oria behaves (mostly) like a Hash - you could say that it responds to 2/3 of [@wycats](http://github.com/wycats)' Moneta
45
45
  plugin. Specifically, it responds to the following Hash methods:
46
46
 
47
47
  []=(value) Set a key to ... something.
@@ -117,6 +117,9 @@ Let's try it out:
117
117
  Oria.app_key = "my_app_1"
118
118
  Oria[:foo] #=> "bar"
119
119
 
120
+ That's it! I hope you enjoy Oria, and please let me know if you find any issues or have any trouble. As you will no doubt see from
121
+ the current version information, it's a very young project, and any contribution is welcome.
122
+
120
123
  Dependencies
121
124
  -
122
125
 
@@ -127,7 +130,60 @@ It also needs [EventMachine](http://github.com/eventmachine/eventmachine) to do
127
130
  UDP sockets, and spent a lifetime on this. But EventMachine is seriously, seriously, seriously awesome, and works very well
128
131
  without me writing an insane amount of code I couldn't write very well anyway. Check it out and see for yourself.
129
132
 
130
- That's it! I hope you enjoy Oria, and please let me know if you find any issues or have any trouble. As you will no doubt see from
131
- the current version information, it's a very young project, and any contribution is welcome.
133
+ Warnings
134
+ -
135
+
136
+ Oria is weak in a few places. First, it forks all over the place with no regard for the consequences. Someday I'm going to upgrade it
137
+ to use Daemons, but not right now. In general, the forking is dangerous and clumsy.
138
+
139
+ Also, Oria's auto-start feature relies on `sleep`. In fact, Oria relies on `sleep` in more than one place. _This is terrible_ and I
140
+ want to fix it someday. But I also want to get the code out there so people can start breaking it and tell me where it breaks.
141
+
142
+ Which means: **please report any problems you have using the [Github issue tracking](http://github.com/flipsasser/oria/issues)!**
143
+
144
+ Benchmarks
145
+ -
146
+
147
+ I've run some benchmarks comparing Oria to Redis. It's not pretty:
148
+
149
+ user system total real
150
+ Redis (write): 0.050000 0.020000 0.070000 ( 0.115850)
151
+ Oria (write): 0.140000 0.110000 0.250000 ( 1.267912)
152
+ Redis (read): 0.070000 0.020000 0.090000 ( 0.145078)
153
+ Oria (read): 0.150000 0.110000 0.260000 ( 1.247791)
154
+
155
+ As you can see, Oria is about 10x slower than Redis on my development computer. Even worse, if you run the benchmark like so:
156
+
157
+ ruby redis_v_oria.rb 10000
158
+
159
+ Oria's server will fail to fulfill all of those requests. Scary. Clearly, it needs some serious improvement. Oria will never be
160
+ as performant as something like Redis - it's not meant to be (plus it's written in Ruby, not C). But it could use some reduction
161
+ in overhead, and any help is welcome.
162
+
163
+ But I knew Oria wouldn't compete with Redis. What about MySQL?
164
+
165
+ user system total real
166
+ MySQL (write): 0.270000 0.030000 0.300000 ( 0.445586)
167
+ Oria (write): 0.170000 0.120000 0.290000 ( 1.676674)
168
+ MySQL (read): 0.310000 0.020000 0.330000 ( 0.484944)
169
+ Oria (read): 0.120000 0.120000 0.240000 ( 1.616851)
170
+
171
+ Ew. Oria is consistently about 4x slower than MySQL. But check this out: I removed persistence, and here are the new benchmarks:
172
+
173
+ user system total real
174
+ Redis (write): 0.040000 0.020000 0.060000 ( 0.113882)
175
+ Oria (write): 0.130000 0.100000 0.230000 ( 0.396776)
176
+ Redis (read): 0.070000 0.020000 0.090000 ( 0.145068)
177
+ Oria (read): 0.130000 0.100000 0.230000 ( 0.395410)
178
+
179
+ That's getting competitive. How about MySQL?
180
+
181
+ user system total real
182
+ MySQL (write): 0.270000 0.030000 0.300000 ( 0.453413)
183
+ Oria (write): 0.150000 0.110000 0.260000 ( 0.430725)
184
+ MySQL (read): 0.320000 0.030000 0.350000 ( 0.484978)
185
+ Oria (read): 0.100000 0.100000 0.200000 ( 0.373431)
186
+
187
+ Oh snap! Oria outperforms MySQL when persistence is disabled. So I'll have to refactor the code.
132
188
 
133
189
  Copyright (c) 2009 Flip Sasser, released under the MIT license
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -0,0 +1,26 @@
1
+ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
2
+ /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
3
+ /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
4
+ /*!40101 SET NAMES utf8 */;
5
+ /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
6
+ /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
7
+ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
8
+ /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
9
+
10
+ DROP TABLE IF EXISTS `oria_test`;
11
+
12
+ CREATE TABLE `oria_test` (
13
+ `id` int(11) NOT NULL AUTO_INCREMENT,
14
+ `key` varchar(32) DEFAULT NULL,
15
+ `value` varchar(128) DEFAULT NULL,
16
+ PRIMARY KEY (`id`),
17
+ UNIQUE KEY `key` (`key`)
18
+ ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
19
+
20
+ /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
21
+ /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
22
+ /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
23
+ /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
24
+ /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
25
+ /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
26
+ /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
@@ -0,0 +1,33 @@
1
+ require 'rubygems'
2
+ require 'redis'
3
+ require '../lib/oria'
4
+ require 'benchmark'
5
+
6
+ redis = Redis.new
7
+ n = (ARGV.shift || 1000).to_i
8
+
9
+ Benchmark.bm(15) do |bm|
10
+ bm.report("Redis (write):") do
11
+ n.times do
12
+ redis['foo'] = 'bar'
13
+ end
14
+ end
15
+
16
+ bm.report("Oria (write):") do
17
+ n.times do
18
+ Oria['foo'] = 'bar'
19
+ end
20
+ end
21
+
22
+ bm.report("Redis (read):") do
23
+ n.times do
24
+ foo = redis['foo']
25
+ end
26
+ end
27
+
28
+ bm.report("Oria (read):") do
29
+ n.times do
30
+ foo = Oria['foo']
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,39 @@
1
+ require 'rubygems'
2
+ require 'sequel'
3
+ require '../lib/oria'
4
+ require 'benchmark'
5
+
6
+ DB = Sequel.connect('mysql://root@localhost/oria_test')
7
+ n = (ARGV.shift || 1000).to_i
8
+
9
+ Benchmark.bm(15) do |bm|
10
+ bm.report("MySQL (write):") do
11
+ table = DB[:oria_test]
12
+ n.times do
13
+ if foo = table[:key => 'foo']
14
+ foo.update(:value => 'bar')
15
+ else
16
+ table.insert(:key => 'foo', :value => 'bar')
17
+ end
18
+ end
19
+ end
20
+
21
+ bm.report("Oria (write):") do
22
+ n.times do
23
+ Oria['foo'] = 'bar'
24
+ end
25
+ end
26
+
27
+ bm.report("MySQL (read):") do
28
+ table = DB[:oria_test]
29
+ n.times do
30
+ foo = table[:key => 'foo']
31
+ end
32
+ end
33
+
34
+ bm.report("Oria (read):") do
35
+ n.times do
36
+ foo = Oria['foo']
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,45 @@
1
+ require 'rubygems'
2
+ require 'sequel'
3
+ require '../lib/oria'
4
+ require 'benchmark'
5
+
6
+ DB = Sequel.sqlite
7
+ DB.create_table :oria_test do
8
+ primary_key :id
9
+ String :key
10
+ String :value
11
+ end
12
+
13
+ n = (ARGV.shift || 1000).to_i
14
+
15
+ Benchmark.bm(16) do |bm|
16
+ bm.report("SQLite3 (write):") do
17
+ table = DB[:oria_test]
18
+ n.times do
19
+ if foo = table[:key => 'foo']
20
+ foo.update(:value => 'bar')
21
+ else
22
+ table.insert(:key => 'foo', :value => 'bar')
23
+ end
24
+ end
25
+ end
26
+
27
+ bm.report("Oria (write):") do
28
+ n.times do
29
+ Oria['foo'] = 'bar'
30
+ end
31
+ end
32
+
33
+ bm.report("SQLite3 (read):") do
34
+ table = DB[:oria_test]
35
+ n.times do
36
+ foo = table[:key => 'foo']
37
+ end
38
+ end
39
+
40
+ bm.report("Oria (read):") do
41
+ n.times do
42
+ foo = Oria['foo']
43
+ end
44
+ end
45
+ end
data/bin/oria CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'optparse'
3
- # require 'rubygems'
4
- # require 'oria'
5
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'oria'))
3
+ require 'rubygems'
4
+ require 'oria'
5
+ # require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'oria'))
6
6
 
7
7
  module OriaCommand
8
8
  def self.go
@@ -15,7 +15,7 @@ module OriaCommand
15
15
  stop
16
16
  start
17
17
  else
18
- puts parser #"Usage: oria start|stop|restart"
18
+ puts parser
19
19
  end
20
20
  end
21
21
 
@@ -29,6 +29,9 @@ module OriaCommand
29
29
  opts.on('-h', '--host [IP]', 'The hostname or IP Oria should listen on.') do |host|
30
30
  @options[:host] = port
31
31
  end
32
+ opts.on('-d', '--debug', 'Log output to /tmp/oria.log') do |debug|
33
+ @options[:debug] = true
34
+ end
32
35
  end
33
36
  end
34
37
 
data/lib/oria/server.rb CHANGED
@@ -3,10 +3,16 @@ require 'tmpdir'
3
3
  module Oria
4
4
  class Server < EventMachine::Connection
5
5
  class << self
6
+ @@timer = nil
7
+
6
8
  def debug?
7
9
  @@debug
8
10
  end
9
11
 
12
+ def log(value, app_key = nil)
13
+ logger.debug("#{"#{app_key}: " if app_key}#{value}") if debug?
14
+ end
15
+
10
16
  def logger
11
17
  require 'logger'
12
18
  @@logger ||= Logger.new(log_file, 0, 100 * 1024 * 1024)
@@ -42,11 +48,14 @@ module Oria
42
48
  end
43
49
  end
44
50
 
45
- def write_hash
46
- @@write_hash ||= proc do
51
+ def store_hash(app_key)
52
+ @@timer.cancel if @@timer
53
+ @@timer = EventMachine::Timer.new(10) do
54
+ log "Writing changes to disk", app_key
47
55
  File.open(yaml_store, 'w') do |store|
48
56
  store.puts YAML.dump(@@servers)
49
57
  end
58
+ @@timer = nil
50
59
  end
51
60
  end
52
61
 
@@ -69,11 +78,11 @@ module Oria
69
78
  end
70
79
 
71
80
  def post_init
72
- log "Client connected"
81
+ Oria::Server.log "Client connected"
73
82
  end
74
83
 
75
84
  def receive_data(data)
76
- log "Responding to #{data}"
85
+ Oria::Server.log "Responding to #{data}"
77
86
  data = data.split(' ')
78
87
  method = data.shift
79
88
  data = JSON.parse(data.join(' '))
@@ -98,10 +107,12 @@ module Oria
98
107
  end
99
108
  if defined?(response)
100
109
  response = JSON.generate({:response => response})
101
- log "Sending response: #{response}"
110
+ Oria::Server.log "Sending response: #{response}"
111
+ Oria::Server.store_hash(@app_key)
102
112
  send_data response
103
113
  end
104
- EventMachine.defer(Oria::Server.write_hash)
114
+ rescue JSON::ParserError
115
+ send_data "Invalid request"
105
116
  end
106
117
 
107
118
  def unbind
@@ -112,12 +123,6 @@ module Oria
112
123
  @hash ||= @@servers[@app_key || 'default'] ||= {}
113
124
  end
114
125
 
115
- def log(value)
116
- if Oria::Server.debug?
117
- Oria::Server.logger.debug(value)
118
- end
119
- end
120
-
121
126
  def random_key
122
127
  chars = ['a'..'z', 'A'..'Z', 0..9].map(&:to_a).flatten
123
128
  max = [hash.length, 2].max
data/oria.gemspec CHANGED
@@ -5,13 +5,17 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{oria}
8
- s.version = "0.0.1"
8
+ s.version = "0.0.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Flip Sasser"]
12
- s.date = %q{2009-11-22}
12
+ s.date = %q{2009-11-23}
13
13
  s.default_executable = %q{oria}
14
- s.description = %q{}
14
+ s.description = %q{
15
+ Oria (oh-rye-uh) is an in-memory, Ruby-based Key-Value store. It's designed to handle moderate amounts of data quickly
16
+ and easily without causing deployment issues or server headaches. It uses EventMachine to provide a networked interface
17
+ to a semi-persistent KVS and asynchronously writes the in-memory data to YAML files.
18
+ }
15
19
  s.email = %q{flip@x451.com}
16
20
  s.executables = ["oria"]
17
21
  s.extra_rdoc_files = [
@@ -19,15 +23,21 @@ Gem::Specification.new do |s|
19
23
  "README.markdown"
20
24
  ]
21
25
  s.files = [
22
- "LICENSE",
26
+ ".gitignore",
27
+ "LICENSE",
23
28
  "README.markdown",
24
29
  "Rakefile",
25
30
  "VERSION",
31
+ "benchmarks/mysql_table.sql",
32
+ "benchmarks/redis_v_oria.rb",
33
+ "benchmarks/sequel_v_oria.rb",
34
+ "benchmarks/sqlite_v_oria.rb",
26
35
  "bin/oria",
27
36
  "lib/oria.rb",
28
37
  "lib/oria/client.rb",
29
38
  "lib/oria/errors.rb",
30
39
  "lib/oria/server.rb",
40
+ "oria.gemspec",
31
41
  "spec/oria_spec.rb",
32
42
  "spec/rcov.opts",
33
43
  "spec/spec.opts",
@@ -49,14 +59,14 @@ Gem::Specification.new do |s|
49
59
 
50
60
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
51
61
  s.add_runtime_dependency(%q<eventmachine>, [">= 0.12.10"])
52
- s.add_runtime_dependency(%q<json>, [">= 2.0.0"])
62
+ s.add_runtime_dependency(%q<json>, [">= 1.2.0"])
53
63
  else
54
64
  s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
55
- s.add_dependency(%q<json>, [">= 2.0.0"])
65
+ s.add_dependency(%q<json>, [">= 1.2.0"])
56
66
  end
57
67
  else
58
68
  s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
59
- s.add_dependency(%q<json>, [">= 2.0.0"])
69
+ s.add_dependency(%q<json>, [">= 1.2.0"])
60
70
  end
61
71
  end
62
72
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oria
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Flip Sasser
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-22 00:00:00 -05:00
12
+ date: 2009-11-23 00:00:00 -05:00
13
13
  default_executable: oria
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -42,10 +42,15 @@ extra_rdoc_files:
42
42
  - LICENSE
43
43
  - README.markdown
44
44
  files:
45
+ - .gitignore
45
46
  - LICENSE
46
47
  - README.markdown
47
48
  - Rakefile
48
49
  - VERSION
50
+ - benchmarks/mysql_table.sql
51
+ - benchmarks/redis_v_oria.rb
52
+ - benchmarks/sequel_v_oria.rb
53
+ - benchmarks/sqlite_v_oria.rb
49
54
  - bin/oria
50
55
  - lib/oria.rb
51
56
  - lib/oria/client.rb