문제

나는 캐싱 할 가치가있는 거의 모든 것을위한 역동적이고 노화 캐시 역할을하도록 설계된 CFC를 구축했습니다. LDAP 쿼리, 기능 결과, 배열, OJECTS, 이름을 지정합니다. 계산하는 데 시간이나 자원이 필요하며 두 번 이상 필요합니다. 몇 가지 작업을 수행하고 싶습니다.

  • 응용 프로그램간에 CFC를 공유하십시오
  • 캐시의 범위를 정의합니다 (서버 / 애플리케이션 / 세션 / 현재 요청 만 해당)
  • 동시에 동시에 다른 캐시 인스턴스를 사용하십시오.
  • 캐시 구성 요소를 사용하여 CFC와 독립적입니다
  • 일반적으로 상식을 준수합니다 (분리, 캡슐화, 직교성, 잠금)

물론 모든 고유 한 작업에 대해 다른 캐시 인스턴스를 사용하고 있지만 응용 프로그램에서 동일한 CFC를 사용할 수 있습니다. 캐시 자체는 캐시 인스턴스에 대한 비공개, 구조물입니다. 범위 자체가 변경 될 때 캐싱 및 잠금을 어떻게 올바르게 구현합니까?

잠금을 위해, 나는 명명 된 자물쇠를 사용합니다 ('CacheRead', 'CacheWrite') 현재, 이것은 안전하지만 나를 이상하게 쳤다. 세션 전용 작업을 위해 서버 전체 잠금 장치를 원하는 이유는 무엇입니까? (예, 아마도 이것 ~이다 학문이지만 어쨌든.)

응용 프로그램 레벨 캐싱을 원할 때 응용 프로그램 범위를 참조로 전달하는 것도 잘못된 것 같습니다. 더 좋은 방법이 있습니까?

도움이 되었습니까?

해결책

캐시하려는 실제 범위 구조를 통과하지 않으려는 욕구를 이해하지만 대안은 제한되어 있습니다. 가장 먼저 떠오르는 것은 캐시를 저장하고 평가하는 범위의 이름 (문자열)을 전달하고 평가하는 것입니다. 본질적으로 평가는 비효율적이며 피해야합니다. 즉, 나는 그것이 어떻게 달성 될지 궁금했습니다. 나는 당신의 코드가 없으므로 방금 방금 흙을 간단하게 "스토리지"추상화 CFC를 만들었습니다 (테스트하고 싶은 것과 관련이 없기 때문에 캐싱이 건너 뜁니다).

cache.cfc :

<cfcomponent>
    <cfset variables.cacheScope = "session" /><!--- default to session --->
    <cfset variables.cache = ""/>

    <cfscript>
    function init(scope){
        variables.cacheScope = arguments.scope;
        return this;
    }

    function cacheWrite(key, value){
        structInsert(evaluate(variables.cacheScope),arguments.key,arguments.value,true);
        return this;
    }

    function cacheRead(key){
        if (not structKeyExists(evaluate(variables.cacheScope), arguments.key)){
            return "";
        }else{
            variables.cache = evaluate(variables.cacheScope);
            return variables.cache[arguments.key];
        }
    }   
    </cfscript>
</cfcomponent>

그리고 그것을 테스트하기위한 견해 :

<!--- clear out any existing session vars --->
<cfset structClear(session)/>
<!--- show empty session struct --->
<cfdump var="#session#" label="session vars">
<!--- create storage object --->
<cfset cacher = createObject("component", "cache").init("session")/>
<!--- store a value --->
<cfset cacher.cacheWrite("foo", "bar")/>
<!--- read stored value --->
<cfset rtn = cacher.cacheRead("foo")/>
<!--- show values --->
<cfdump var="#rtn#">
<cfdump var="#session#" label="session vars">

오프 주제 : jQuery와 같은 메소드 호출을 체인 할 수 있도록 세터 기능을 작성하여 위에서 볼 수 있듯이 "위에 본다"를 반환하고 싶습니다. 보기의 일부는 다음과 같이 쉽게 작성 될 수 있습니다.

<cfset rtn = createObject("component", "cache")
    .init("session")
    .cacheWrite("foo", "bar")
    .cacheRead("foo")/>

이것이 가능하다는 것이 흥미롭지 만, 오버 헤드 평가 비용으로 인해 생산에 사용하지 않을 것입니다. 캐시하려는 범위를 전달할 충분한 이유가 유효한 이유라고 말하고 싶습니다.

여전히 귀찮게한다면 (그리고 아마도 올바르게?), 원하는 범위에서 읽기와 쓰기를 추상화하고 캐싱 CFC로 전달하는 또 다른 CFC를 만들 수 있습니다 (저장 위치). 콜드 스프링), 캐시를 다른 범위로 이동하기로 결정한 경우 "세션"에서 전달한 캐시 CFC를 사용하여 300 페이지를 편집 할 필요가 없으며 대신 1 CFC 또는 Coldspring 구성을 편집 할 수 있습니다.

요청 범위가있을 때 왜 단일 요청 캐싱을 원할 지 확실하지 않습니다. 당신이 찾고있는 것이 현재 요청을 위해 무언가를 캐시하고 곧 죽게하는 방법이라면, 요청 범위가 원하는 것일 수 있습니다. 캐싱은 일반적으로 여러 요청에 걸쳐있을 때 더 가치가 있습니다.

다른 팁

좋아 - 처음에 당신의 질문을 오해했기 때문에 더 이상 혼란을 일으키지 않도록 이전 답변을 삭제했습니다.

이름이 항상 같은 이름을 가질 필요가 없기 때문에 이름이 지정된 자물쇠는 괜찮습니다. 액세스하는 캐시에 따라 동적으로 이름을 지정할 수 있습니다. 개인 구조물의 요소에 액세스 해야하는 경우 이름이 지정된 잠금 장치와 같은 작업을 수행 할 수 있습니다. 키를 이름으로 사용하십시오.

이런 식으로, 잠금 장치가 효과가있는 유일한 시간은 무언가가 동일한 캐시에 이름으로 액세스하려고하는 경우입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top