سؤال

أنا أعمل على تطبيق القضبان، حيث أستخدم صفحة التخزين المؤقت للصفحة لتخزين إخراج HTML ثابت. التخزين المؤقت يعمل بشكل جيد. أواجه مشكلة في تنقل المخابئ، رغم ذلك.

أعتقد أن مشكلتي هي، جزئيا، لأنني لا أقوم بعدم انتهاء ذاكرة التخزين المؤقت من جهاز التحكم الخاص بي. يتم التعامل مع جميع الإجراءات اللازمة لهذا النموذج. يبدو أن هذا كما يجب أن تكون قابلة للقيام، ولكن كل الإشارات إلى انتهاء صلاحية ذاكرة التخزين المؤقت القائمة على النمذات التي أجدها قديمة، أو لا تعمل بطريقة أخرى.

في ملف بيئتي.

config.load_paths += %W( #{RAILS_ROOT}/app/sweepers )

ولدي، في مجلد / كحل، ملف Linksweeper:

class LinkSweeper < ActionController::Caching::Sweeper
  observe Link

  def after_update(link)
    clear_links_cache(link)
  end

  def clear_links_cache(link)
  # expire_page :controller => 'links', :action => 'show', :md5 => link.md5
    expire_page '/l/'+ link.md5 + '.html'
  end
end

وبالتالي ... لماذا لا يتم حذف الصفحة المخزنة مؤقتا عند تحديث النموذج؟ (العملية: استخدام البرنامج النصي / وحدة التحكم، أقوم باختيار عناصر من قاعدة البيانات وإنقاذها، لكن صفحاتهم المقابلة لا تحذفها من ذاكرة التخزين المؤقت)، وأستدعى أيضا الأسلوب المحدد في نموذج الارتباط الذي سيتحسح عادة كاسحة. لا يعمل.

إذا كان الأمر يهم، فإن الملف المخزن مؤقتا هو حشاش MD5 قبالة قيمة مفتاح في جدول الروابط. يتم تخزين الصفحات المخزنة مؤقتا كشيء مثل /l/45ed4aade64d427...99919cba2bd90f.html.

في الأساس، يبدو الأمر كما لو أن Sweeper لا يراقب الرابط بالفعل. أنا أيضا قرأت (هنا) قد يكون من الممكن ببساطة إضافة كاسحة إلى config.active_record.observers في البيئة الذي - التي).

هل كانت مفيدة؟

المحلول

مجرد ملاحظة: يمكنك استخدام cache_sweeper في ApplicationController.

class ApplicationController < ActionController::Base
  cache_sweeper :my_sweeper
end

class MySweeper < ActionController::Caching::Sweeper
  observe MyModel

  def after_update(my_model)
    expire_page(...)
  end
end

نصائح أخرى

لذلك لقد جربت عددا من الأساليب المختلفة، لمعرفة ما يعمل، وما لا.

مرة أخرى، لتلخيص الوضع: هدفي هو إنهاء الصفحات المخزنة مؤقتا عند تحديث كائن، ولكن لتنتهي صلاحيتها دون الاعتماد على إجراء تحكم. تستخدم الكسولات التقليدية خطا في وحدة التحكم لإعلام الكناس بأنه يحتاج إلى العمل. في هذه الحالة، لا يمكنني استخدام خط في وحدة التحكم، حيث يحدث التحديث داخل النموذج. لا يعمل البرامج التعليمية العادية في الكناس، حيث يفترض أن تفاعلك الرئيسي مع كائن قاعدة البيانات من خلال وحدة التحكم.

إذا، في قراءة هذا، ترى طريقة لتشديد التعليمات البرمجية الخاصة بي، يرجى التعليق واسمحوا لي أن أعرف.

أولا، دعونا نلقي نظرة على الأشياء التي تعمل، في حالة عالقة في هذا الأمر، أيضا، وتحتاج إلى مساعدة.

من بين كل الأشياء التي جربتها، كان الشيء الوحيد الذي يبدو أنه يعمل حقا هو إعلان أمر After_Update في المراقب عن النموذج. في تلك الأمر، استخدمت الأمر الصريح لعمل EXPIRE_PAGE، وشملت مسارا تم إعلانه في Routes.rb.

وبالتالي. هذا يعمل:

في التكوين / Routes.rb:

map.link 'l/:md5.:format',  :controller => 'links', :action => 'show'

في التطبيق / النماذج / link_observer.rb:

def after_update(link)
  ActionController::Base.expire_page(app.link_path(:md5 => link.md5))
end

لاحظ أن "MD5" محددة لتطبيقي. قد ترغب في استخدام: معرف أو بعض المعرف الفريد الآخر.

لقد وجدت أيضا أن إعلان أن ActionController :: Base ... خط من الطريقة في النموذج الذي يقوم بتحديث العمل. وهذا هو، داخل link.rb، في الطريقة التي تقوم بالفعل بتحديث قاعدة البيانات، إذا عالقة فقط في هذا الخط بالكامل، فقد عمل ذلك. ولكن نظرا لأنني قد أرغب في الانتهاء من أن ذاكرة التخزين المؤقت للصفحة على الطرق الأخرى في المستقبل، إلا أنني أفضل استخراجها في المراقب.

الآن، دعونا نلقي نظرة على بعض الأشياء التي لم تنجح، في حال كنت قد googling حولها.

استدعاء "expire_page (...)" ضمن طريقة After_Update (LINK) داخل link_observer.rb لم تنجح، حيث عاد خطأ "طريقة غير محددة" expire_page "

إنشاء ملف كاسحة وقد لوحظ أن النموذج لا يعمل. لم أستطع العثور على أي رموز خطأ، لكن يبدو أنه لا يدرك أنه كان لديه وظيفة للقيام به. كان هذا بعد استدعاء "config.load_load_path + = =٪ w (# {{{reass_root} / app / scorers)" داخل البيئة.rb. فقط في حالة إصابعات الأصابع في هذا القانون، هنا هو:

class LinkSweeper < ActionController::Caching::Sweeper
  observe Link

  def after_update(link)
    clear_links_cache(link)
  end

  def clear_links_cache(link)
    # DID NOT WORK    expire_page :controller => 'links', :action => 'show', :md5 => link.md5
    # DID NOT WORK    expire_page '/l/'+ link.md5 + '.html'
    # DID NOT WORK    ActionController::Base.expire_page(app.link_path(:md5 => link.md5))
  end
end

كان ذلك أعلاه مثال يحتوي على ملف Link_Sweeper.rb في دليل أو تطبيق / كحل. لقد حاولت أيضا وضع link_sweeper.rb داخل دليل التطبيق / النماذج، وحاول الاتصال به باستخدام الأمر config.active_record.observers في البيئة.rb:

config.active_record.observers = :link_observer, :link_sweeper

ولكن هذا لم يعمل، سواء.

إذن أجل. من الممكن تماما أن تعمل إحدى هذه الأساليب، وأن افسدت شيئا في التعليمات البرمجية. لكنني أعتقد أنني فعلت كل شيء من الكتاب.

في نهاية المطاف، لتلخيص: بدلا من استخدام كاسحة لتنتهي صلاحض التخزين المؤقت للصفحة، تريد إعداد رد اتصال بعد ذلك في مراقب الطراز. سترغب في استخدام المسار الصريح إلى طريقة Base.expire_Page:

def after_update(<model>) # where <model> is the name of the model you're observing
  ActionController::Base.expire_page(app.<model>_path(:id => <model>.id)) # where <model> is the name of the model you're observing
end

نأمل أن يساعد ذلك شخصا آخر على الطريق. مرة أخرى، إذا رأيت في أي مكان في رمز العمل غير العامل حيث كان يجب علي فعل شيء مختلف، واسمحوا لي أن أعرف. إذا رأيت شيئا في رمز العمل الذي يمكن أن يكون أكثر إحكاما، فيرجى إخبارنا بذلك أيضا.

كنت أعاني من نفس المشكلة عند محاولة القيام بتخزين التخزين المؤقت Fragment (القضبان 3). لا يمكن الحصول على كاسحة لاحظت، لذلك استقرت للحل لجعله مراقب AR كما هو موضح أعلاه والدعوة ApplicationController.new.expire_fragment(...).

لقد حصلت على هذا العمل. الفرق الطفيف الوحيد في الإعداد الخاص بي هو أن Sweeper جزء من محرك القضبان؛ الذي يمثل الاختلافات الطفيفة (تحميل ملف Sweeper مع طلبات في INTION في INTION بدلا من إضافته إلى مسار الحمل في Environment.rb، إلخ).

لذلك، يتم تحميل Sweeper في Init.rb من المحرك مثل هذا:

require File.join(File.dirname(__FILE__), 'app', 'sweepers', cached_category_count_sweeper')

اتصلت بها كاسكن لأنها "يكتسح" ذاكرة التخزين المؤقت، لكنني أعتقد أنها مجرد مراقب على النموذج:

class CachedCategoryCountSweeper < ActiveRecord::Observer
  observe CategoryFeature

  def before_save(cf)
    expire_cache(cf.category_id_was) if cf.category_id_changed?
  end

  def after_save(cf)
    expire_cache(cf.category_id)
  end

  def after_destroy(cf)
    expire_cache(cf.category_id)
  end

  def expire_cache(c)
    ApplicationController.expire_page("/categories/#{c}/counts.xml") if !c.nil?
  end
end

بصراحة، لا أحب الاضطرار إلى المسار الصلب، لكنني حاولت إضافة:

include ActionController:UrlWriter

ثم باستخدام طريقة المسار، ولكن عملت فقط بالنسبة لي في التنمية. لم تنجح في الإنتاج، لأن خادم الإنتاج الخاص بي يستخدم جذر عنوان URL نسبي (بدلا من المضيفين الظاهري) والطريقة الداخلية "Page_cache_Path" ستحصل على خطأ في مسار الملف حتى لا يمكن أن تنتهي صلاحيته.

منذ أن هذا مراقب، أضفت إلى البيئة

config.active_record.observers = :cached_category_count_sweeper

أخيرا وحدة التحكم التي تستخدم ذاكرة التخزين المؤقت (لا تنتهي صلاحيته، يتم ذلك من خلال النموذج المراقب):

class CachedCategoryCountsController < ApplicationController
  caches_page :index

  # GET /cached_category_counts.xml
  def index
    ...
  end
end

على أي حال، نأمل أن يساعد هذا.

أندريس مونتانو

لقد تمكنت من الحصول عليها للعمل، عن طريق إضافة

ActionController::Base.expire_page(app.link_path(:md5 => @link.md5))

إلى الطريقة في النموذج نفسه الذي يقوم بتحديث قاعدة البيانات. هذا يشعر بثوقة إلى حد ما، وأحب أن أعرف ما إذا كان بإمكان أي شخص أن يشرح سبب عدم العمل مع إعداد Sweeper العادي، وإذا كان هناك طريقة أكثر أناقة للتعامل مع هذا.

أن المقتطف من الكود (بصرف النظر عن التخصيصات التي وضعتها في تطبيقي الخاص) جاء من هذا المنشور على Ruby-Forum.com.

كتبت قليلا عن هذا الموضوع هنا: القضبان ذاكرة التخزين المؤقت كاسحة الارتباك. وبعد أحب أن أسمع آرائكم.

استنادا إلى إجابات Moiristo و Zoogiezork، أعتقد أن هذا سيعمل (غير مختبر).

class LinkSweeper < ActiveRecord::Observer
  include ActionController::Caching::Pages
  # or if you want to expire fragments
  #include ActionController::Caching::Fragments

  observe Link

  def after_update(link)
    expire_page( ... )
    #expire_fragment( ... )
  end
end
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top