Permalink
Browse files

Merge pull request #13 from sorah/redis-ready

Redis ready
  • Loading branch information...
rosylilly committed Oct 31, 2015
2 parents b459b8e + bee1ac4 commit 582b185be311511b3e73b85c2bb853661b7f0241
Showing with 67 additions and 23 deletions.
  1. +1 −0 5f/webapp/env.sh
  2. +4 −2 5f/webapp/ruby/Gemfile
  3. +8 −0 5f/webapp/ruby/Gemfile.lock
  4. +53 −21 5f/webapp/ruby/app.rb
  5. +1 −0 5f/webapp/sql/.gitignore
View
@@ -4,5 +4,6 @@ export GOPATH=/home/isucon/gocode
export _JAVA_OPTIONS="-Dfile.encoding=UTF-8"
export ISUCON5_DB_HOST=isu12a
export ISUCON5_DB_PORT=5432
+export REDIS_HOST=isu12a
exec $*
View
@@ -9,6 +9,8 @@ gem "httpclient"
gem 'redis'
gem 'stackprof'
-
-
gem 'expeditor'
+gem 'oj'
+gem 'oj_mimic_json'
+gem 'hiredis'
+gem 'msgpack'
@@ -11,9 +11,13 @@ GEM
concurrent-ruby (= 0.8.0)
concurrent-ruby-ext (= 0.8.0)
retryable (> 1.0)
+ hiredis (0.6.0)
httpclient (2.6.0.1)
kgio (2.10.0)
+ msgpack (0.7.0)
multi_json (1.11.2)
+ oj (2.13.0)
+ oj_mimic_json (1.0.1)
pg (0.18.3)
rack (1.6.4)
rack-protection (1.5.3)
@@ -48,7 +52,11 @@ PLATFORMS
DEPENDENCIES
erubis
expeditor
+ hiredis
httpclient
+ msgpack
+ oj
+ oj_mimic_json
pg
redis
sinatra
View
@@ -3,10 +3,15 @@
require 'pg'
require 'tilt/erubis'
require 'erubis'
-require 'json'
require 'httpclient'
require 'openssl'
require 'expeditor'
+require 'redis'
+require 'hiredis'
+require 'redis/connection/hiredis'
+require 'oj'
+require 'oj_mimic_json'
+require 'msgpack'
# bundle config build.pg --with-pg-config=<path to pg_config>
# bundle install
@@ -102,6 +107,31 @@ def db
conn
end
+ def redis_host
+ ENV['REDIS_HOST'] || 'localhost'
+ end
+
+ def redis
+ return Thread.current[:redis] if Thread.current[:redis]
+ Thread.current[:redis] = Redis.new(
+ host: redis_host,
+ port: ENV['REDIS_PORT'] || 6379,
+ driver: :hiredis
+ )
+ end
+
+ def insert_subscription(user_id)
+ redis.set("subscription/#{user_id}", "\x80")
+ end
+
+ def update_subscription(user_id, params)
+ redis.set("subscription/#{user_id}", params.to_msgpack)
+ end
+
+ def get_subscription(user_id)
+ MessagePack.unpack(redis.get("subscription/#{user_id}") || "\x80")
+ end
+
def authenticate(email, password)
query = <<SQL
SELECT id, email, grade FROM users WHERE email=$1 AND passhash=digest(salt || $2, 'sha512')
@@ -148,14 +178,10 @@ def generate_salt
salt = generate_salt
insert_user_query = <<SQL
INSERT INTO users (email,salt,passhash,grade) VALUES ($1,$2,digest($3 || $4, 'sha512'),$5) RETURNING id
-SQL
- default_arg = {}
- insert_subscription_query = <<SQL
-INSERT INTO subscriptions (user_id,arg) VALUES ($1,$2)
SQL
db.transaction do |conn|
user_id = conn.exec_params(insert_user_query, [email,salt,salt,password,grade]).values.first.first
- conn.exec_params(insert_subscription_query, [user_id, default_arg.to_json])
+ insert_subscription(user_id)
end
redirect '/login'
end
@@ -196,10 +222,7 @@ def generate_salt
user = current_user
halt 403 unless user
- query = <<SQL
-SELECT arg FROM subscriptions WHERE user_id=$1
-SQL
- arg = db.exec_params(query, [user[:id]]).values.first[0]
+ arg = get_subscription(user[:id])
erb :modify, locals: {user: user, arg: arg}
end
@@ -212,23 +235,17 @@ def generate_salt
keys = params.has_key?("keys") ? params["keys"].strip.split(/\s+/) : nil
param_name = params.has_key?("param_name") ? params["param_name"].strip : nil
param_value = params.has_key?("param_value") ? params["param_value"].strip : nil
- select_query = <<SQL
-SELECT arg FROM subscriptions WHERE user_id=$1 FOR UPDATE
-SQL
- update_query = <<SQL
-UPDATE subscriptions SET arg=$1 WHERE user_id=$2
-SQL
+
db.transaction do |conn|
- arg_json = conn.exec_params(select_query, [user[:id]]).values.first[0]
- arg = JSON.parse(arg_json)
+ arg = get_subscription(user[:id])
arg[service] ||= {}
arg[service]['token'] = token if token
arg[service]['keys'] = keys if keys
if param_name && param_value
arg[service]['params'] ||= {}
arg[service]['params'][param_name] = param_value
end
- conn.exec_params(update_query, [arg.to_json, user[:id]])
+ update_subscription(user[:id], arg)
end
redirect '/modify'
end
@@ -253,8 +270,7 @@ def fetch_api(method, uri, headers, params)
halt 403
end
- arg_json = db.exec_params("SELECT arg FROM subscriptions WHERE user_id=$1", [user[:id]]).values.first[0]
- arg = JSON.parse(arg_json)
+ arg = get_subscription(user[:id])
data = arg.map do |service, conf|
#Expeditor::Command.new do
@@ -268,7 +284,23 @@ def fetch_api(method, uri, headers, params)
end
get '/initialize' do
+ puts "===> Initialize DB : #{Time.now.to_s}"
file = File.expand_path("../../sql/initialize.sql", __FILE__)
system("psql", "-f", file, "isucon5f")
+
+ puts "===> Initialize Redis : #{Time.now.to_s}"
+ redis.flushall
+
+ result = db.exec_params('SELECT * FROM subscriptions') do |result|
+ result.values
+ end
+
+ redis.pipelined do
+ result.each do |row|
+ update_subscription(row[0], JSON.parse(row[1]))
+ end
+ end
+
+ ""
end
end
View
@@ -0,0 +1 @@
+*.redis

0 comments on commit 582b185

Please sign in to comment.