1
0
Fork 0

Cache power

This commit is contained in:
magnolia-fan 2011-11-28 16:24:47 +04:00
parent 4c40a928ab
commit 23cf09613d
13 changed files with 60 additions and 30 deletions

View File

@ -35,5 +35,6 @@ end
group :production do group :production do
gem 'pg' gem 'pg'
gem 'dalli' # Memcache
gem 'uglifier' gem 'uglifier'
end end

View File

@ -55,6 +55,7 @@ GEM
execjs execjs
coffee-script-source (1.1.3) coffee-script-source (1.1.3)
daemons (1.1.4) daemons (1.1.4)
dalli (1.1.3)
delayed_job (2.1.4) delayed_job (2.1.4)
activesupport (~> 3.0) activesupport (~> 3.0)
daemons daemons
@ -147,6 +148,7 @@ DEPENDENCIES
awesome_print awesome_print
bitmask_attributes bitmask_attributes
coffee-script coffee-script
dalli
delayed_job delayed_job
haml haml
heroku heroku

View File

@ -15,7 +15,9 @@ class window.Search
log "Loading artist page ..." log "Loading artist page ..."
_search.showSpinner() _search.showSpinner()
name = name.split(' ').join('+') name = name.split(' ').join('+')
$.get '/artist/' +name+ '/', (data) -> _ajax.previous_page = "/artist/#{name}/"
_ajax.go "/artist/#{name}/"
$.get "/artist/#{name}", (data) ->
if data.status in ['ok', 'loading'] if data.status in ['ok', 'loading']
_page.render data _page.render data
_search.hideSpinner() _search.hideSpinner()

View File

@ -48,5 +48,6 @@ table.stats {
.vk-like td { .vk-like td {
padding: 0 !important; padding: 0 !important;
border: none;
line-height: 12px; line-height: 12px;
} }

View File

@ -10,16 +10,28 @@ class ApplicationController < ActionController::Base
end end
def compile_page params def compile_page params
@data = params[:data] unless params[:data].nil? compiler = lambda do |params|
@status = params[:status] unless params[:status].nil? @data = params[:data].call(&(params[:data].lambda? ? :call : :serialize)) unless params[:data].nil?
render json: { @status = params[:status] unless params[:status].nil?
renderer: "unified", {
data: @data, renderer: "unified",
html: render_compact_partial(params[:partial]), data: @data,
title: params[:title], html: render_compact_partial(params[:partial]),
status: (params[:status] unless params[:status].nil?), title: params[:title],
callback: (params[:callback] unless params[:callback].nil?) status: (params[:status] unless params[:status].nil?),
}, include: (params[:include] unless params[:include].nil?) callback: (params[:callback] unless params[:callback].nil?)
}.to_json.to_s
end
unless params[:cache].nil?
data = Rails.cache.fetch(params[:cache_key] || cache_key_for(params[:data]), expires_in: params[:cache]) do
compiler.call(params)
end
else
data = compiler.call(params)
end
render text: data, content_type: 'application/json'
end end
def get_artist_name_from_query def get_artist_name_from_query
@ -27,6 +39,10 @@ class ApplicationController < ActionController::Base
end end
protected protected
def cache_key_for object
"#{object.class.to_s.underscore}_#{object.id}"
end
def authorize def authorize
unless Vkontakte.check(params) unless Vkontakte.check(params)

View File

@ -20,25 +20,19 @@ class ArtistController < ApplicationController
return render json: { status: 'corrected', correct_name: best_match } return render json: { status: 'corrected', correct_name: best_match }
elsif best_match == artist_name elsif best_match == artist_name
queue_loading(artist_name, results[0][:mbid]) queue_loading(artist_name, results[0][:mbid])
return render json: { status: 'loading', html: render_compact_partial(:page) }
else else
@suggestions = results.take(5) @suggestions = results.take(5)
return render json: { status: 'suggestions', html: render_compact_partial(:suggestions) } return render json: { status: 'suggestions', html: render_compact_partial(:suggestions) }
end end
end end
# Artist loading failed
if @artist.status == 2
return render json: { status: 'fail', html: render_compact_partial(:fail) }
end
cache_for 1.week
compile_page( compile_page(
data: @artist.serialize, data: @artist,
partial: "artist/page", partial: "artist/page",
title: @artist.name, title: @artist.name,
status: @artist.status_str, status: @artist.status_str,
callback: {object: :player, action: :updateLibrary} callback: {object: :player, action: :updateLibrary},
cache: 3.minutes
) )
end end

View File

@ -8,18 +8,22 @@ class PlaylistController < ApplicationController
artist = Artist.find_by_name(get_artist_name_from_query) artist = Artist.find_by_name(get_artist_name_from_query)
return if artist.nil? return if artist.nil?
playlist = Playlist.new(name: "#{artist.name}: Last.fm TOP 50", artist: artist, pic_url: artist.pic_url) compiler = lambda do
LastFM::Artist.get_top_tracks(artist: artist.name)["toptracks"]["track"].each do |track| playlist = Playlist.new(name: "#{artist.name}: Last.fm TOP 50", artist: artist, pic_url: artist.pic_url)
tracks = Track.joins(:album, :artists).where(name: track["name"], "track_artists.artist_id" => artist.id) LastFM::Artist.get_top_tracks(artist: artist.name)["toptracks"]["track"].each do |track|
playlist.playlist_items << PlaylistItem.new(track_id: tracks.first.id) unless tracks.empty? tracks = Track.joins(:album, :artists).where(name: track["name"], "track_artists.artist_id" => artist.id)
playlist.playlist_items << PlaylistItem.new(track_id: tracks.first.id) unless tracks.empty?
end
playlist.serialize
end end
cache_for 1.week
compile_page( compile_page(
data: playlist.serialize, data: compiler,
partial: "playlist/tracks", partial: "playlist/tracks",
title: playlist.name, title: "#{artist.name}: Last.fm TOP 50",
callback: {object: :player, action: :updateLibrary} callback: {object: :player, action: :updateLibrary},
cache: 3.minutes,
cache_key: "lastfmtop50_#{artist.id}"
) )
end end
end end

View File

@ -18,6 +18,7 @@ class Artist < ActiveRecord::Base
self.status = 0 self.status = 0
save! save!
Delayed::Job.enqueue(LoadArtistJob.new(name)) Delayed::Job.enqueue(LoadArtistJob.new(name))
clear_cache
end end
def serialize def serialize
@ -31,6 +32,10 @@ class Artist < ActiveRecord::Base
artist_links: artist_links.map(&:serialize) artist_links: artist_links.map(&:serialize)
} }
end end
def clear_cache
Rails.cache.delete "artist_#{id}"
end
private private

View File

@ -1,4 +1,4 @@
.fb-like{ "data-href" => "http://facebook.com/BeatHavenHQ", "data-send" => "false", "data-layout" => "button_count", "data-width" => "100", "data-show-faces" => "false", "data-font" => "lucida grande" } .fb-like{ "data-href" => "http://facebook.com/BeatHavenHQ", "data-send" => "false", "data-layout" => "button_count", "data-width" => "100", "data-show-faces" => "false", "data-font" => "lucida grande" }
.vk-like .vk-like
%script{ type: "text/javascript" } %script{ type: "text/javascript" }
document.write(VK.Share.button(false, {type: "round", text: "Нравится"})); = "document.write(VK.Share.button(false, {type: \"round\", text: \"#{t('global.like')}\"}));".html_safe

View File

@ -27,4 +27,7 @@ Beathaven::Application.configure do
# Expands the lines which load the assets # Expands the lines which load the assets
config.assets.debug = true config.assets.debug = true
# Storing cache inside app process
config.cache_store = :memory_store
end end

View File

@ -37,7 +37,7 @@ Beathaven::Application.configure do
# config.logger = SyslogLogger.new # config.logger = SyslogLogger.new
# Use a different cache store in production # Use a different cache store in production
# config.cache_store = :mem_cache_store config.cache_store = :dalli_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server # Enable serving of images, stylesheets, and JavaScripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com" # config.action_controller.asset_host = "http://assets.example.com"

View File

@ -11,6 +11,7 @@ en:
hello: "Hi there" hello: "Hi there"
settings: "Settings" settings: "Settings"
your_ad_here: "Your ad couldn't<br/>be here" your_ad_here: "Your ad couldn't<br/>be here"
like: "Like"
title: title:
greetings: Greetings greetings: Greetings

View File

@ -11,6 +11,7 @@ ru:
hello: "Привет" hello: "Привет"
settings: "Настройки" settings: "Настройки"
your_ad_here: "Здесь не могла бы<br/>быть Ваша реклама" your_ad_here: "Здесь не могла бы<br/>быть Ваша реклама"
like: "Нравится"
title: title:
greetings: Привет greetings: Привет