rdkit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b7f8dab0976c2aaf2d8045793c9c52713a7ff867
4
+ data.tar.gz: 0cb9f68b9684fc6c2a5e553202a724396ae75d46
5
+ SHA512:
6
+ metadata.gz: 2e1c7b165b6cc10f382afd74618dd5a5df2a1722e8bbad9a5eb69c2742449fe6f2ca6e39ec0a4b163574b4cce8ae8aaf78a45ccbafddd18e26dc7896e072956d
7
+ data.tar.gz: 2b6889a5764936fb592b0d29418aab64108c7cb53f1b22c2d2e87381a9259e2f8ab7f3f8f4e0e3366a5e554f1399d6a6218b8a28317ed5ef30f7b83ace5a964f
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ script: bundle exec rspec
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rdkit.gemspec
4
+ gemspec
@@ -0,0 +1,209 @@
1
+ # RDKit
2
+
3
+ RDKit is a simple toolkit to write Redis-like, single-threaded multiplexing-IO server.
4
+
5
+ The server speaks [Redis RESP protocol](http://redis.io/topics/protocol), so you can reuse many Redis-compatible clients and tools such as:
6
+
7
+ - `redis-cli`
8
+ - `redis-benchmark`
9
+ - [Redic](https://github.com/amakawa/redic)
10
+
11
+ And a lot more.
12
+
13
+ `RDKit` is used to power the [520 Love Radio](http://s.weibo.com/weibo/same%2520%25E7%2594%25B5%25E5%258F%25B0) service of [same.com](http://same.com)
14
+
15
+ [![Code Climate](https://codeclimate.com/github/forresty/rdkit/badges/gpa.svg)](https://codeclimate.com/github/forresty/rdkit)
16
+ [![Build Status](https://travis-ci.org/forresty/rdkit.svg?branch=master)](https://travis-ci.org/forresty/rdkit)
17
+
18
+ ## Installation
19
+
20
+ Add this line to your application's Gemfile:
21
+
22
+ ```ruby
23
+ gem 'rdkit'
24
+ ```
25
+
26
+ And then execute:
27
+
28
+ $ bundle
29
+
30
+ Or install it yourself as:
31
+
32
+ $ gem install rdkit
33
+
34
+ ## Usage
35
+
36
+ see examples under `example` folder.
37
+
38
+ ### Implementing a counter server
39
+
40
+ A simple counter server source code listing:
41
+
42
+ ```ruby
43
+ require 'rdkit'
44
+
45
+ # counter/version.rb
46
+ module Counter
47
+ VERSION = '0.0.1'
48
+ end
49
+
50
+ # counter/core.rb
51
+ module Counter
52
+ class Core < RDKit::Core
53
+ attr_accessor :count
54
+
55
+ def initialize
56
+ @count = 0
57
+ @last_tick = Time.now
58
+ end
59
+
60
+ # `tick!` is called periodically by RDKit
61
+ def tick!
62
+ @last_tick = Time.now
63
+ end
64
+
65
+ def incr(n)
66
+ @count += n
67
+ end
68
+
69
+ def introspection
70
+ {
71
+ counter_version: Counter::VERSION,
72
+ count: @count,
73
+ last_tick: @last_tick
74
+ }
75
+ end
76
+ end
77
+ end
78
+
79
+ # counter/command_runner.rb
80
+ module Counter
81
+ class CommandRunner < RDKit::RESPRunner
82
+ def initialize(counter)
83
+ @counter = counter
84
+ end
85
+
86
+ # every public method of this class will be accessible by clients
87
+ def count
88
+ @counter.count
89
+ end
90
+
91
+ def incr(n=1)
92
+ @counter.incr(n.to_i)
93
+ end
94
+ end
95
+ end
96
+
97
+ # counter/server.rb
98
+ module Counter
99
+ class Server < RDKit::Server
100
+ def initialize
101
+ super('0.0.0.0', 3721)
102
+
103
+ # @core is required by RDKit
104
+ @core = Core.new
105
+
106
+ # @runner is also required by RDKit
107
+ @runner = CommandRunner.new(@core)
108
+ end
109
+
110
+ def introspection
111
+ super.merge(counter: @core.introspection)
112
+ end
113
+ end
114
+ end
115
+
116
+ # start server
117
+
118
+ server = Counter::Server.new
119
+
120
+ trap(:INT) { server.stop }
121
+
122
+ server.start
123
+
124
+ ```
125
+
126
+ ### Connect using `redis-cli`
127
+
128
+ ```shell
129
+ $ redis-cli -p 3721
130
+ 127.0.0.1:3721> count
131
+ (integer) 0
132
+ 127.0.0.1:3721> incr
133
+ (integer) 1
134
+ 127.0.0.1:3721> incr 10
135
+ (integer) 11
136
+ 127.0.0.1:3721> count
137
+ (integer) 11
138
+ 127.0.0.1:3721> info
139
+ # Server
140
+ rdkit_version:0.0.1
141
+ multiplexing_api:select
142
+ process_id:15083
143
+ tcp_port:3721
144
+ uptime_in_seconds:268
145
+ uptime_in_days:0
146
+ hz:10
147
+
148
+ # Clients
149
+ connected_clients:1
150
+ connected_clients_peak:1
151
+
152
+ # Memory
153
+ used_memory_rss:31.89M
154
+ used_memory_peak:31.89M
155
+
156
+ # Counter
157
+ counter_version:0.0.1
158
+ count:11
159
+ last_tick:2015-05-27 20:15:38 +0800
160
+
161
+ # Stats
162
+ total_connections_received:1
163
+ total_commands_processed:6
164
+
165
+ 127.0.0.1:3721> xx
166
+ (error) ERR unknown command 'xx'
167
+ ```
168
+
169
+ ### Benchmarking with `redis-benchmark`
170
+
171
+ ```shell
172
+ $ redis-benchmark -p 3721 incr
173
+ ====== count ======
174
+ 10000 requests completed in 0.73 seconds
175
+ 50 parallel clients
176
+ 3 bytes payload
177
+ keep alive: 1
178
+
179
+ 0.01% <= 1 milliseconds
180
+ 2.27% <= 2 milliseconds
181
+ 42.31% <= 3 milliseconds
182
+ 63.99% <= 4 milliseconds
183
+ 96.14% <= 5 milliseconds
184
+ ...
185
+ 99.97% <= 68 milliseconds
186
+ 99.98% <= 71 milliseconds
187
+ 99.99% <= 74 milliseconds
188
+ 100.00% <= 77 milliseconds
189
+ 13679.89 requests per second
190
+ ```
191
+
192
+ Since it is single-threaded, the count will be correct:
193
+
194
+ ```shell
195
+ 127.0.0.1:3721> count
196
+ (integer) 10000
197
+ ```
198
+
199
+ ## Development
200
+
201
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
202
+
203
+ ## Contributing
204
+
205
+ 1. Fork it ( https://github.com/forresty/rdkit/fork )
206
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
207
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
208
+ 4. Push to the branch (`git push origin my-new-feature`)
209
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rdkit"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,12 @@
1
+ require 'rdkit'
2
+
3
+ require_relative 'counter/version'
4
+ require_relative 'counter/core'
5
+ require_relative 'counter/command_runner'
6
+ require_relative 'counter/server'
7
+
8
+ server = Counter::Server.new
9
+
10
+ trap(:INT) { server.stop }
11
+
12
+ server.start
@@ -0,0 +1,16 @@
1
+ module Counter
2
+ class CommandRunner < RDKit::RESPRunner
3
+ def initialize(counter)
4
+ @counter = counter
5
+ end
6
+
7
+ # every public method of this class will be accessible by clients
8
+ def count
9
+ @counter.count
10
+ end
11
+
12
+ def incr(n=1)
13
+ @counter.incr(n.to_i)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,31 @@
1
+ module Counter
2
+ class Core < RDKit::Core
3
+ attr_accessor :count
4
+
5
+ def initialize
6
+ @count = 0
7
+ @last_tick = Time.now
8
+ end
9
+
10
+ def incr(n)
11
+ @count += n
12
+ end
13
+
14
+ ###########################################
15
+ # overriding required RDKit::Core methods
16
+ ###########################################
17
+
18
+ # `tick!` is called periodically by RDKit
19
+ def tick!
20
+ @last_tick = Time.now
21
+ end
22
+
23
+ def introspection
24
+ {
25
+ counter_version: Counter::VERSION,
26
+ count: @count,
27
+ last_tick: @last_tick
28
+ }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,17 @@
1
+ module Counter
2
+ class Server < RDKit::Server
3
+ def initialize
4
+ super('0.0.0.0', 3721)
5
+
6
+ # @core is required by RDKit
7
+ @core = Core.new
8
+
9
+ # @runner is also required by RDKit
10
+ @runner = CommandRunner.new(@core)
11
+ end
12
+
13
+ def introspection
14
+ super.merge(counter: @core.introspection)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module Counter
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,10 @@
1
+ require_relative 'rdkit/version'
2
+ require_relative 'rdkit/errors'
3
+ require_relative 'rdkit/resp'
4
+ require_relative 'rdkit/logger'
5
+ require_relative 'rdkit/introspection'
6
+ require_relative 'rdkit/inheritable'
7
+ require_relative 'rdkit/core'
8
+ require_relative 'rdkit/command_parser'
9
+ require_relative 'rdkit/resp_runner'
10
+ require_relative 'rdkit/server'
@@ -0,0 +1,45 @@
1
+ require "hiredis/reader"
2
+ # http://redis.io/topics/protocol
3
+ # Hiredis::Reader does not handle inline commands, so
4
+
5
+ module RDKit
6
+ class CommandParser
7
+ def initialize
8
+ @reader = Hiredis::Reader.new
9
+ @buffer = []
10
+ @regexp = Regexp.new("\\A(.+)\\r\\n\\z")
11
+ @error = nil
12
+ end
13
+
14
+ def feed(data)
15
+ if data =~ @regexp
16
+ @buffer << $1.split
17
+ else
18
+ @reader.feed(data)
19
+
20
+ read_into_buffer!
21
+ end
22
+ end
23
+
24
+ def gets
25
+ raise @error unless @error.nil?
26
+
27
+ if result = @buffer.shift
28
+
29
+ result
30
+ else
31
+ @reader.gets
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def read_into_buffer!
38
+ until (reply = @reader.gets) == false
39
+ @buffer << reply
40
+ end
41
+ rescue RuntimeError => e
42
+ @error = ProtocolError.new(e) if e.message =~ /Protocol error/
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,13 @@
1
+ module RDKit
2
+ class Core
3
+ include Inheritable
4
+
5
+ def tick!
6
+ raise ShouldOverrideError
7
+ end
8
+
9
+ def introspection
10
+ raise ShouldOverrideError
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ module RDKit
2
+ class RDKitError < StandardError; end
3
+
4
+ class ProtocolError < RDKitError; end
5
+ class UnknownCommandError < ProtocolError; end
6
+ class WrongNumberOfArgumentError < ProtocolError; end
7
+
8
+ class NotImplementedError < RDKitError; end
9
+
10
+ class SDKRequirementNotMetError < RDKitError; end
11
+ class ShouldOverrideError < SDKRequirementNotMetError; end
12
+ end
@@ -0,0 +1,15 @@
1
+ module RDKit
2
+ module Inheritable
3
+ def self.included(base)
4
+ base.instance_eval do
5
+ def instance(*args)
6
+ @subclass.new(*args)
7
+ end
8
+
9
+ def inherited(klass)
10
+ @subclass = klass
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,82 @@
1
+ # 127.0.0.1:6379> info
2
+ # # Server
3
+ # redis_version:2.8.17
4
+ # redis_git_sha1:00000000
5
+ # redis_git_dirty:0
6
+ # redis_build_id:32eb139b4f2b63
7
+ # redis_mode:standalone
8
+ # os:Darwin 13.4.0 x86_64
9
+ # arch_bits:64
10
+ # multiplexing_api:kqueue
11
+ # gcc_version:4.2.1
12
+ # process_id:471
13
+ # run_id:efa5b449cc3ba9c53f7bbb159a773e6ff20d575c
14
+ # tcp_port:6379
15
+ # uptime_in_seconds:1510124
16
+ # uptime_in_days:17
17
+ # hz:10
18
+ #
19
+ # # Clients
20
+ # connected_clients:1
21
+ # client_longest_output_list:0
22
+ # client_biggest_input_buf:0
23
+ #
24
+ # # Memory
25
+ # used_memory:124510288
26
+ # used_memory_human:118.74M
27
+ # used_memory_rss:119885824
28
+ # used_memory_peak:124510288
29
+ # used_memory_peak_human:118.74M
30
+ # used_memory_lua:33792
31
+ # mem_fragmentation_ratio:0.96
32
+ # mem_allocator:libc
33
+ #
34
+ # # Persistence
35
+ #
36
+ # # Stats
37
+ # total_connections_received:74408
38
+ # total_commands_processed:5122851
39
+ # instantaneous_ops_per_sec:0
40
+ # rejected_connections:0
41
+ # pubsub_channels:0
42
+ # pubsub_patterns:0
43
+
44
+ module RDKit
45
+ module Introspection
46
+ class Stats
47
+ attr_reader :data
48
+
49
+ def initialize
50
+ @data = {}
51
+
52
+ @data.default = 0
53
+ end
54
+
55
+ module ClassMethods
56
+ @@instance = Stats.new
57
+
58
+ def incr(key)
59
+ @@instance.data[key] += 1
60
+ end
61
+
62
+ def info
63
+ @@instance.data
64
+ end
65
+ end
66
+
67
+ class << self; include ClassMethods; end
68
+ end
69
+
70
+ module ClassMethods
71
+ def register(server)
72
+ @@server = server
73
+ end
74
+
75
+ def info
76
+ @@server.introspection.merge({ stats: Stats.info })
77
+ end
78
+ end
79
+
80
+ class << self; include ClassMethods; end
81
+ end
82
+ end
@@ -0,0 +1,27 @@
1
+ module RDKit
2
+ class Logger
3
+ def debug(message)
4
+ return unless $DEBUG && ENV['RACK_ENV'] != 'test'
5
+
6
+ log(message)
7
+ end
8
+
9
+ def info(message)
10
+ log(message)
11
+ end
12
+
13
+ def warn(message)
14
+ log(message)
15
+ end
16
+
17
+ def log(message)
18
+ case message
19
+ when StandardError
20
+ puts message.inspect
21
+ puts message.backtrace.join("\n")
22
+ else
23
+ puts message
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ # http://redis.io/topics/protocol
2
+
3
+ module RDKit
4
+ class RESP
5
+ module ClassMethods
6
+ def compose(data)
7
+ case data
8
+ when Integer
9
+ ":#{data}\r\n"
10
+ when Array
11
+ "*#{data.size}\r\n" + data.map { |i| compose(i) }.join
12
+ when NilClass
13
+ # Null Bulk String, not Null Array of "*-1\r\n"
14
+ "$-1\r\n"
15
+ when StandardError
16
+ "-#{data.message}\r\n"
17
+ else
18
+ # always Bulk String
19
+ "$#{data.bytesize}\r\n#{data}\r\n"
20
+ end
21
+ end
22
+ end
23
+
24
+ class << self; include ClassMethods; end
25
+ end
26
+ end
@@ -0,0 +1,46 @@
1
+ module RDKit
2
+ class RESPRunner
3
+ include Inheritable
4
+
5
+ def resp(cmd)
6
+ RESP.compose(call(cmd))
7
+ rescue => e
8
+ RESP.compose(e)
9
+ end
10
+
11
+ # 获取服务器状态
12
+ def info
13
+ Introspection.info.map do |type, value|
14
+ "# #{type.capitalize}\r\n" + value.map { |k, v| "#{k}:#{v}" }.join("\r\n") + "\r\n"
15
+ end.join("\r\n") + "\r\n"
16
+ end
17
+
18
+ private
19
+
20
+ def call(cmd)
21
+ @logger ||= Logger.new
22
+
23
+ Introspection::Stats.incr(:total_commands_processed)
24
+
25
+ @logger.debug "running command: #{cmd}"
26
+ cmd, *args = cmd
27
+
28
+ cmd.downcase!
29
+
30
+ if self.respond_to?(cmd)
31
+ self.__send__(cmd, *args)
32
+ else
33
+ raise UnknownCommandError, "ERR unknown command '#{cmd}'"
34
+ end
35
+ rescue ArgumentError => e
36
+ raise WrongNumberOfArgumentError, "ERR wrong number of arguments for '#{cmd}' command"
37
+ end
38
+
39
+ module RedisCompatibility
40
+ def select(id); 'OK'; end
41
+ def ping; 'PONG'; end
42
+ end
43
+
44
+ include RedisCompatibility
45
+ end
46
+ end
@@ -0,0 +1,192 @@
1
+ require 'newrelic_rpm'
2
+
3
+ module RDKit
4
+ class Server
5
+ HZ = 10
6
+ CYCLES_TIL_MEMORY_RESAMPLE = 1000
7
+
8
+ attr_reader :server_up_since
9
+ attr_reader :runner
10
+ attr_reader :core
11
+ attr_reader :host, :port
12
+
13
+ def initialize(host, port)
14
+ @host, @port = host, port
15
+
16
+ @cycles = 0
17
+ @peak_memory = 0
18
+ @peak_connected_clients = 0
19
+
20
+ @clients, @command_parsers = Hash.new, Hash.new
21
+
22
+ @logger = Logger.new
23
+
24
+ Introspection.register(self)
25
+
26
+ @server_up_since = Time.now
27
+ end
28
+
29
+ def sanity_check!
30
+ unless @host && @port
31
+ raise SDKRequirementNotMetError, '@host and @port are required for server to run'
32
+ end
33
+
34
+ if @core.nil?
35
+ raise SDKRequirementNotMetError, '@core is required to represent your business logics'
36
+ end
37
+
38
+ if @runner.nil?
39
+ raise SDKRequirementNotMetError, '@runner is required to act as an RESP frontend'
40
+ end
41
+ end
42
+
43
+ def start
44
+ sanity_check!
45
+
46
+ @server_socket = TCPServer.new(@host, @port)
47
+
48
+ run_acceptor
49
+ end
50
+
51
+ def stop
52
+ @logger.warn "signal caught, shutting down..."
53
+ exit
54
+ end
55
+
56
+ def introspection
57
+ {
58
+ server: {
59
+ rdkit_version: RDKit::VERSION,
60
+ multiplexing_api: 'select',
61
+ process_id: Process.pid,
62
+ tcp_port: @port,
63
+ uptime_in_seconds: (Time.now - @server_up_since).to_i,
64
+ uptime_in_days: ((Time.now - @server_up_since) / (24 * 60 * 60)).to_i,
65
+ hz: HZ,
66
+ },
67
+ clients: {
68
+ connected_clients: @clients.size,
69
+ connected_clients_peak: @peak_connected_clients
70
+ },
71
+ memory: {
72
+ used_memory_rss: used_memory_rss_in_mb,
73
+ used_memory_peak: used_memory_peak_in_mb
74
+ },
75
+ }
76
+ end
77
+
78
+ private
79
+
80
+ def used_memory_rss_in_mb
81
+ update_peak_memory!
82
+
83
+ '%0.2f' % used_memory_rss + 'M'
84
+ end
85
+
86
+ def used_memory_peak_in_mb
87
+ '%0.2f' % @peak_memory + 'M'
88
+ end
89
+
90
+ def add_client
91
+ Introspection::Stats.incr(:total_connections_received)
92
+
93
+ socket = @server_socket.accept_nonblock
94
+
95
+ @command_parsers[socket] = CommandParser.new
96
+
97
+ @clients[socket] = Fiber.new do
98
+ with_error_handling(socket) do |io|
99
+ loop { process(io); Fiber.yield }
100
+ end
101
+ end
102
+
103
+ @logger.debug "client #{socket} connected"
104
+
105
+ return @clients[socket]
106
+ end
107
+
108
+ def process(io)
109
+ feed_parser(io)
110
+
111
+ until (reply = get_parser_reply(io)) == false
112
+ send_response(io, reply)
113
+ end
114
+ end
115
+
116
+ def feed_parser(io)
117
+ cmd = io.readpartial(1024)
118
+
119
+ @command_parsers[io].feed(cmd)
120
+ end
121
+
122
+ def get_parser_reply(io)
123
+ @command_parsers[io].gets
124
+ end
125
+
126
+ def send_response(io, cmd)
127
+ resp = runner.resp(cmd)
128
+
129
+ @logger.debug(resp)
130
+
131
+ io.write(resp)
132
+ end
133
+
134
+ def with_error_handling(socket, &block)
135
+
136
+ block.call(socket)
137
+
138
+ rescue Errno::ECONNRESET, EOFError => e
139
+ # client disconnected
140
+ @logger.debug "client #{socket.inspect} has disconnected"
141
+ @logger.debug e
142
+ @command_parsers.delete(socket)
143
+ @clients.delete(socket)
144
+ rescue ProtocolError => e
145
+ # client protocol error, force disconnect
146
+ @logger.debug "client protocol error"
147
+ @logger.debug e
148
+ socket.close
149
+ @command_parsers.delete(socket)
150
+ @clients.delete(socket)
151
+ end
152
+
153
+ def run_acceptor
154
+ @logger.info "accepting on shared socket (#{@host}:#{@port})"
155
+
156
+ loop do
157
+ readable, _ = IO.select([@server_socket, @clients.keys].flatten, nil, nil, 1.0 / HZ)
158
+
159
+ if readable
160
+ readable.each do |socket|
161
+ if socket == @server_socket
162
+ add_client
163
+ else
164
+ # client is a Fiber
165
+ client = @clients[socket]
166
+ client.resume
167
+ end
168
+ end
169
+ end
170
+
171
+ update_peak_memory! if @cycles % CYCLES_TIL_MEMORY_RESAMPLE == 0
172
+ update_peak_connected_clients!
173
+
174
+ @cycles += 1
175
+
176
+ core.tick!
177
+ end
178
+ end
179
+
180
+ def update_peak_memory!
181
+ @peak_memory = [@peak_memory, used_memory_rss].max
182
+ end
183
+
184
+ def update_peak_connected_clients!
185
+ @peak_connected_clients = [@peak_connected_clients, @clients.size].max
186
+ end
187
+
188
+ def used_memory_rss
189
+ NewRelic::Agent::Samplers::MemorySampler.new.sampler.get_sample
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,3 @@
1
+ module RDKit
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rdkit/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rdkit"
8
+ spec.version = RDKit::VERSION
9
+ spec.authors = ["Forrest Ye"]
10
+ spec.email = ["afu@forresty.com"]
11
+
12
+ spec.summary = %q{RDKit is a simple toolkit to write Redis-like, single-threaded multiplexing-IO server.}
13
+ spec.homepage = "http://github.com/forresty/rdkit"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.bindir = "exe"
17
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_runtime_dependency 'hiredis'
21
+ spec.add_runtime_dependency 'newrelic_rpm'
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.8"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec"
26
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rdkit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Forrest Ye
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-05-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hiredis
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: newrelic_rpm
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.8'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.8'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - afu@forresty.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".travis.yml"
93
+ - Gemfile
94
+ - README.md
95
+ - Rakefile
96
+ - bin/console
97
+ - bin/setup
98
+ - example/counter.rb
99
+ - example/counter/command_runner.rb
100
+ - example/counter/core.rb
101
+ - example/counter/server.rb
102
+ - example/counter/version.rb
103
+ - lib/rdkit.rb
104
+ - lib/rdkit/command_parser.rb
105
+ - lib/rdkit/core.rb
106
+ - lib/rdkit/errors.rb
107
+ - lib/rdkit/inheritable.rb
108
+ - lib/rdkit/introspection.rb
109
+ - lib/rdkit/logger.rb
110
+ - lib/rdkit/resp.rb
111
+ - lib/rdkit/resp_runner.rb
112
+ - lib/rdkit/server.rb
113
+ - lib/rdkit/version.rb
114
+ - rdkit.gemspec
115
+ homepage: http://github.com/forresty/rdkit
116
+ licenses: []
117
+ metadata: {}
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 2.4.5
135
+ signing_key:
136
+ specification_version: 4
137
+ summary: RDKit is a simple toolkit to write Redis-like, single-threaded multiplexing-IO
138
+ server.
139
+ test_files: []