[RUBY-ON-RAILS] 레일 3.1 Rails.cache 오류 - 형식 오류 : 기본적 proc 디렉토리와 해시를 덤프 할 수 없습니다
RUBY-ON-RAILS레일 3.1 Rails.cache 오류 - 형식 오류 : 기본적 proc 디렉토리와 해시를 덤프 할 수 없습니다
I는 3.1.0.rc4 (루비 1.9.2p180 (2011-02-18 수요일 수정 30,909) x86_64에-darwin10])에 Rails.cache 방식의 문제로 실행. 코드는 2.3.12에서 동일한 응용 프로그램 내에서 잘 작동 (루비 1.8.7 (2011-02-18 패치 레벨 334)는 i686 - 리눅스], MBARI 0x8770, 루비 엔터 프라이즈 에디션 2011.03), 그러나 업그레이드 다음 오류를 반환하기 시작했다. 나는 왜 아직 알아낼 수 없었다.
이 오류는 그들에 하나 개 이상의 범위가 캐시 개체를 시도 할 때 발생하는 것 같습니다.
또한, 람다를 사용하는 범위에 관계없이 얼마나 많은 범위의 실패합니다.
나는 이러한 패턴에서 실패를 명중했다 :
Rails.cache.fetch("keyname", :expires_in => 1.minute) do
Model.scope_with_lambda
end
Rails.cache.fetch("keyname", :expires_in => 1.minute) do
Model.scope.scope
end
이것은 내가 나타나는 오류입니다 :
TypeError: can't dump hash with default proc
from /project/shared/bundled_gems/ruby/1.9.1/gems/activesupport-3.1.0.rc4/lib/active_support/cache.rb:627:in `dump'
from /project/shared/bundled_gems/ruby/1.9.1/gems/activesupport-3.1.0.rc4/lib/active_support/cache.rb:627:in `should_compress?'
from /project/shared/bundled_gems/ruby/1.9.1/gems/activesupport-3.1.0.rc4/lib/active_support/cache.rb:559:in `initialize'
from /project/shared/bundled_gems/ruby/1.9.1/gems/activesupport-3.1.0.rc4/lib/active_support/cache.rb:363:in `new'
from /project/shared/bundled_gems/ruby/1.9.1/gems/activesupport-3.1.0.rc4/lib/active_support/cache.rb:363:in `block in write'
from /project/shared/bundled_gems/ruby/1.9.1/gems/activesupport-3.1.0.rc4/lib/active_support/cache.rb:520:in `instrument'
from /project/shared/bundled_gems/ruby/1.9.1/gems/activesupport-3.1.0.rc4/lib/active_support/cache.rb:362:in `write'
from /project/shared/bundled_gems/ruby/1.9.1/gems/activesupport-3.1.0.rc4/lib/active_support/cache.rb:299:in `fetch'
from (irb):62
from /project/shared/bundled_gems/ruby/1.9.1/gems/railties-3.1.0.rc4/lib/rails/commands/console.rb:45:in `start'
from /project/shared/bundled_gems/ruby/1.9.1/gems/railties-3.1.0.rc4/lib/rails/commands/console.rb:8:in `start'
from /project/shared/bundled_gems/ruby/1.9.1/gems/railties-3.1.0.rc4/lib/rails/commands.rb:40:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
나는 사용하여 시도했다 : 대안으로 원 => 진정한 옵션을하지만, Rails.cache.fetch 블록 캐시 객체를 시도하기 때문에 그 작동하지 않습니다.
어떤 제안? 사전에 감사합니다!
해결법
-
==============================
1.이 자세한 조금있을 수 있지만 내가 어떻게 캐싱 내부 작업을 배우고 레일 소스 코드와 함께 시간을 보내고 있었다. 일을 작성하는 것은 아래로 가지 작업이 해치지 않을 수있는 방법에 대한 몇 가지 메모를 공유 나의 이해와 나는 그림을 도움이됩니다. 당신은 서둘러에 있다면 끝으로 건너 뜁니다.
이 자세한 조금있을 수 있지만 내가 어떻게 캐싱 내부 작업을 배우고 레일 소스 코드와 함께 시간을 보내고 있었다. 일을 작성하는 것은 아래로 가지 작업이 해치지 않을 수있는 방법에 대한 몇 가지 메모를 공유 나의 이해와 나는 그림을 도움이됩니다. 당신은 서둘러에 있다면 끝으로 건너 뜁니다.
이 ActiveSupport 내부의 기분을 상하게 방법입니다 :
def should_compress?(value, options) if options[:compress] && value unless value.is_a?(Numeric) compress_threshold = options[:compress_threshold] || DEFAULT_COMPRESS_LIMIT serialized_value = value.is_a?(String) ? value : Marshal.dump(value) return true if serialized_value.size >= compress_threshold end end false end
serialized_value에 할당합니다. 당신이 cache.rb 내부의 주위에 찌를 경우, 당신은 그들이 직렬화 객체에 다시 다음 원수를 캐시에 가서 전에 바이트 문자열로 직렬화 객체에 원수를 사용하고 있음을 알 수 있습니다. 압축 문제는 중요한 것은 원수의 사용이다, 여기에서 중요하지 않습니다.
문제는이다 :
어떤 것들은 원수로 직렬화 할 수없는 상태 (예 : OS의 파일 기술자 또는 블록 등)이있다. 당신이 주목하고있는 오류는 이것이다 :
모델의 누군가가 해시 인 인스턴스 변수를 가지고 있으며, 그 해시 공급 기본값으로 블록을 사용 그래서. column_methods_hash 방법은 이러한 해시를 사용하며, 심지어 @dynamic_methods_hash 내부 해시 캐시; column_methods_hash은 respond_to 공공 방법으로 (간접적으로) 호출됩니다? 그리고 method_missing.
respond_to 하나? 또는 method_missing 아마 조만간 모든 AR 모델 인스턴스에 전화를하거나 메소드를 호출하면 객체가 unserializable하게 얻을 것이다. 그래서, AR 모델 인스턴스는 레일 3 본질적으로 unserializable 있습니다.
흥미롭게도의 respond_to? 및 2.3.8에서 method_missing 구현은 디폴트 값의 블록을 사용하는 해시에 의해 뒷받침된다. 2.3.8 캐시는 "[...]는 캐시 문자열을 의미한다"입니다. 그래서 당신은 전체 개체를 처리 할 수있는 백엔드와 운이지고 있었다 또는 객체가 해시와-발동 그들 있었다 전에이 원수를 사용; 또는 아마도 당신은 MemoryStore 캐시 백엔드를 사용했고, 그것은 조금 더 큰 해시 이상입니다.
여러 범위를-- 람다와 함께 사용하여 AR 오브젝트에 프로세서 수를 저장 끝낼 수 있습니다; 나는 람다 클래스 (또는 싱글 톤 클래스)이 아닌 객체를 저장할 수 있지만 내가 respond_to의 문제로 분석 귀찮게하지 않았다 기대? 그리고 method_missing는 범위의 문제가 관련이 있습니다.
나는 당신이 당신의 캐시에 잘못된 일을 저장하고 운이지고있어 생각합니다. 당신도 제대로 (즉, 저장하는 간단한 생성 된 데이터가 아닌 전체 모델) 레일 캐시를 사용할 수 있습니다 또는 원수에 설명 된대로 당신은 marshal_dump / marshal_load 또는 _dump / _load 방법을 구현할 수 있습니다. 다른 방법으로는 서버 프로세스 당 하나의 별개의 캐시에 자신을 MemoryStore 백엔드 중 하나를 사용하여 제한 할 수 있습니다.
당신이 처리 할 준비하지 않는 한 당신은 액티브 모델을 저장에 의존 할 수없는 것은 레일 캐시에있는 오브젝트 자신을 정렬 화하거나 MemoryStore 캐시 백엔드에 자신을 제한하려는.
문제의 정확한 소스는 레일의 최신 버전에서 변경했지만 해시와 관련된 default_procs의 많은 경우는 여전히 존재한다.
-
==============================
2.덕분에 뮤입니다 - 너무 짧은 그의 뛰어난 분석. 이걸로 이제 직렬화에 내 모델을 얻을 관리했습니다 :
덕분에 뮤입니다 - 너무 짧은 그의 뛰어난 분석. 이걸로 이제 직렬화에 내 모델을 얻을 관리했습니다 :
def marshal_dump {}.merge(attributes) end def marshal_load stuff send :initialize, stuff, :without_protection => true end
또한 AS 예를 들어, 사용하여 쿼리 조인 직접 SQL에 의해 약간의 "가상 속성"세트가 DISTINCT 게시물을 선택합니다. *, INNER 게시물 FROM AUTHOR_NAME AS 저자의 이름 난 후, 각각에 대한 attr_accessor를 선언 덤프 /도를로드해야 작업이 들어 author.post_id = posts.id WHERE posts.id = 123 저자 가입 그래서 같은 :
VIRTUAL_ATTRIBUTES = [:author_name] attr_accessor *VIRTUAL_ATTRIBUTES def marshal_dump virtual_attributes = Hash[VIRTUAL_ATTRIBUTES.map {|col| [col, self.send(col)] }] {}.with_indifferent_access.merge(attributes).merge(virtual_attributes) end def marshal_load stuff stuff = stuff.with_indifferent_access send :initialize, stuff, :without_protection => true VIRTUAL_ATTRIBUTES.each do |attribute| self.send("#{attribute}=", stuff[attribute]) end end
사용 레일 3.2.18
-
==============================
3.어디서 또는 어떤 범위를 사용하는 액티브 :: 관계 개체를 만든 것을 깨달았다. 나는 그 간단한 일을하는 Model.find이 일 것으로 나타났습니다. 나는 일반 배열로 변환을 강제 있도록이 액티브 :: 관계 객체처럼하지 않았다 의심 것을 나를 위해 일했다.
어디서 또는 어떤 범위를 사용하는 액티브 :: 관계 개체를 만든 것을 깨달았다. 나는 그 간단한 일을하는 Model.find이 일 것으로 나타났습니다. 나는 일반 배열로 변환을 강제 있도록이 액티브 :: 관계 객체처럼하지 않았다 의심 것을 나를 위해 일했다.
Rails.cache.fetch([self.id, 'relA']) do relA.where( attr1: 'some_value' ).order( 'attr2 DESC' ).includes( :rel_1, :rel_2 ).decorate.to_a end
-
==============================
4.당신이 그것을 변경 완료 후 바로 기본 시저를 제거합니다. 뭔가 같은 :
당신이 그것을 변경 완료 후 바로 기본 시저를 제거합니다. 뭔가 같은 :
your_hash.default = nil # clear the default_proc
from https://stackoverflow.com/questions/6391855/rails-cache-error-in-rails-3-1-typeerror-cant-dump-hash-with-default-proc by cc-by-sa and MIT license
'RUBY-ON-RAILS' 카테고리의 다른 글
[RUBY-ON-RAILS] 액티브 레코드 테이블에 대량 삽입 기록 (0) | 2020.02.16 |
---|---|
[RUBY-ON-RAILS] 왜 사용 HTTP의 PUT 대신 POST의 DELETE 방법? (0) | 2020.02.16 |
[RUBY-ON-RAILS] 어떻게 레일의 연결 방법의 일을? (0) | 2020.02.16 |
[RUBY-ON-RAILS] periodically_call_remote 3 당량 레일 (0) | 2020.02.16 |
[RUBY-ON-RAILS] GroupingError : 오류 : 열이 GROUP BY 절에 나타나야합니다 또는 집계 함수에 사용 (0) | 2020.02.16 |