public class ERXAjaxSession
extends com.webobjects.appserver.WOSession
Name | Description |
---|---|
er.extensions.maxPageReplacementCacheSize=30 | er.extensions.maxPageReplacementCacheSize=30 |
er.extensions.appserver.ajax.ERXAjaxSession.storesPageInfo=false | er.extensions.appserver.ajax.ERXAjaxSession.storesPageInfo=false |
er.extensions.overridePrivateCache | er.extensions.overridePrivateCache |
com.webobjects.appserver.WOSession.PageFragmentCache
com.webobjects.foundation.NSKeyValueCodingAdditions.DefaultImplementation, com.webobjects.foundation.NSKeyValueCodingAdditions.Utility
com.webobjects.foundation.NSKeyValueCoding._BooleanFieldBinding, com.webobjects.foundation.NSKeyValueCoding._BooleanMethodBinding, com.webobjects.foundation.NSKeyValueCoding._FieldBinding, com.webobjects.foundation.NSKeyValueCoding._ForwardingBinding, com.webobjects.foundation.NSKeyValueCoding._KeyBinding, com.webobjects.foundation.NSKeyValueCoding._KeyBindingCreation, com.webobjects.foundation.NSKeyValueCoding._MethodBinding, com.webobjects.foundation.NSKeyValueCoding._NumberFieldBinding, com.webobjects.foundation.NSKeyValueCoding._NumberMethodBinding, com.webobjects.foundation.NSKeyValueCoding._ReflectionKeyBindingCreation, com.webobjects.foundation.NSKeyValueCoding.ErrorHandling, com.webobjects.foundation.NSKeyValueCoding.MapImplementation, com.webobjects.foundation.NSKeyValueCoding.Null<T>, com.webobjects.foundation.NSKeyValueCoding.UnknownKeyException, com.webobjects.foundation.NSKeyValueCoding.ValueAccessor
Modifier and Type | Field and Description |
---|---|
protected NSMutableArray |
_permanentContextIDArray
The currently active contextIDs for the permanent pages.
永続ページのカレント・コンテクスト ID
|
protected NSMutableDictionary |
_permanentPageCache
A dict of contextID/pages
contextID/pages のディクショナリー
|
static String |
DONT_STORE_PAGE
Key that tells the session not to store the current page.
|
static String |
FORCE_STORE_PAGE |
static String |
PAGE_REPLACEMENT_CACHE_LOOKUP_KEY
Key that is used to specify that a page should go in the replacement cache instead of
the backtrack cache.
|
_componentState, _httpSession, _httpSessionWatcher, SessionDidCreateNotification, SessionDidRestoreNotification, SessionDidTimeOutNotification
Constructor and Description |
---|
ERXAjaxSession() |
ERXAjaxSession(String sessionID) |
Modifier and Type | Method and Description |
---|---|
protected NSMutableDictionary |
_permanentPageCache()
Returns the permanent page cache.
|
protected com.webobjects.appserver.WOComponent |
_permanentPageWithContextID(String contextID)
Returns the page for the given contextID, null if none is present.
|
void |
_saveCurrentPage()
Semi-private method that saves the current page.
|
protected boolean |
_shouldPutInPermanentCache(com.webobjects.appserver.WOComponent wocomponent)
Reimplementation of the rather weird super imp which references an interface probably no
one has ever heard of...
|
protected void |
cleanPageReplacementCacheIfNecessary()
Iterates through the page replacement cache (if there is one) and removes expired records.
|
protected boolean |
cleanPageReplacementCacheIfNecessary(String _cacheKeyToAge)
Iterates through the page replacement cache (if there is one) and removes expired records.
|
NSMutableDictionary<com.webobjects.appserver.WOComponent,NSMutableDictionary<String,Object>> |
pageInfoDictionary() |
com.webobjects.appserver.WOComponent |
restorePageForContextID(String contextID)
Extension of restorePageForContextID that implements the other side of
Page Replacement Cache.
|
void |
savePage(com.webobjects.appserver.WOComponent page)
Overridden so that Ajax requests are not saved in the page cache.
|
void |
savePageInPermanentCache(com.webobjects.appserver.WOComponent wocomponent)
Saves a page in the permanent cache.
|
boolean |
storesPageInfo() |
_allowToViewEvents, _allowToViewStatistics, _appendCookieToResponse, _awakeInContext, _birthDate, _clearCookieFromResponse, _contextCounter, _contextDidIncrementContextID, _contextIDMatchingIDs, _formattedStatistics, _lifeInMillis, _requestCounter, _setContext, _setHttpSession, _setHttpSessionWatcher, _setSessionID, _sleepInContext, _terminateByJ2EE, _terminateByTimeout, allowedToViewEvents, allowedToViewStatistics, appendToResponse, awake, canAccessFieldsDirectly, clone, context, debugString, defaultEditingContext, domainForIDCookies, expirationDateForIDCookies, getPageFromPageCacheForContextID, getPageFromPageFragmentCacheForContextID, handleQueryWithUnboundKey, handleTakeValueForUnboundKey, invokeAction, isDistributionEnabled, isTerminating, keyEnumerator, keySet, languages, lockDefaultEditingContext, logString, newDefaultEditingContext, objectForKey, removeObjectForKey, savePageInPageCache, savePageInPageFragmentCache, sessionID, setDefaultEditingContext, setDistributionEnabled, setLanguages, setObjectForKey, setStoresIDsInCookies, setStoresIDsInURLs, setTimeOut, sleep, statistics, storesIDsInCookies, storesIDsInURLs, takeValueForKey, takeValueForKeyPath, takeValuesFromRequest, terminate, timeOut, timeOutForIDCookies, timeOutMillis, toString, unableToSetNullForKey, validateEventsLogin, validateStatisticsLogin, validationFailedWithException, valueForKey, valueForKeyPath
public static final String DONT_STORE_PAGE
public static final String FORCE_STORE_PAGE
public static final String PAGE_REPLACEMENT_CACHE_LOOKUP_KEY
protected NSMutableDictionary _permanentPageCache
protected NSMutableArray _permanentContextIDArray
public ERXAjaxSession()
public ERXAjaxSession(String sessionID)
public boolean storesPageInfo()
public NSMutableDictionary<com.webobjects.appserver.WOComponent,NSMutableDictionary<String,Object>> pageInfoDictionary()
public void savePage(com.webobjects.appserver.WOComponent page)
Page Replacement cache is specifically designed to support component actions in Ajax updates. The problem with component actions in Ajax is that if you let them use the normal page cache, then after only 30 (or whatever your backtrack cache is set to) updates from Ajax, you will fill your backtrack cache. Unfortunately for the user, though, the backtrack cache filled up with background ajax requests, so when the user clicks on a component action on the FOREGROUND page, the foreground page has fallen out of the cache, and the request cannot be fulfilled (because its context is gone). If you simply turn off backtrack cache entirely for a request, then you can't have component actions inside of an Ajax updated area, because the context of the Ajax update that generated the link will never get stored, and so you will ALWAYS get a backtrack error.
Enter page replacement cache. If you look at the behavior of Ajax, it turns out that what you REALLY want is a hybrid page cache. You want to keep the backtrack of just the LAST update for a particular ajax component -- you don't care about its previous 29 states because the user can't use the back button to get to them anyway, but if you have the MOST RECENT cached version of the page then you can click on links in Ajax updated areas. Page Replacement cache implements this logic. For each Ajax component on your page that is updating, it keeps a cache entry of its most recent backtrack state (note the difference between this and the normal page cache. The normal page cache contains one entry per user-backtrackable-request. The replacement cache contains one entry per Ajax component*, allowing up to replacement_page_cache_size many components per page). Each time the Ajax area refreshes, the most recent state is replaced*. When a restorePage request comes in, the replacement cache is checked first. If the replacement cache can service the page, then it does so. If the replacement cache doesn't contain the context, then it passes up to the standard page cache. If you are not using Ajax, no replacement cache will exist in your session, and all the code related to it will be skipped, so it should be minimally invasive under those conditions.
* It turns out that we have to keep the last TWO states, because of a race condition in the scenario where the replacement page cache replaces context 2 with the context 3 update, but the user's browser hasn't been updated yet with the HTML from context 3. When the user clicks, they are clicking the context 2 link, which has now been removed from the replacement cache. By keeping the last two states, you allow for the brief period where that transition occurs.
Random note (that I will find useful in 2 weeks when I forget this again): The first time through savePage, the request is saved in the main cache. It's only on a subsequent Ajax update that it uses page replacement cache. So even though the cache is keyed off of context ID, the explanation of the cache being components-per-page-sized works out because each component is requesting in its own thread and generating their own non-overlapping context ids.
独自ページ・キャシュは Ajax updates をコンポーネント・アクションでサポートする為に作成されました。Ajax のコンポーネント・アクションの 一番な問題は一般ページ・キャシュが使用されるので、バックトラック・キャシュ(30、設定によって違うかも)が一杯になります。 Ajax の為にページ・キャシュが一杯になるとユーザが表示中のページをクリックし、コンポーネント・アクションを実行するとそのページがページ・キャシュにない為 エラーが発生します。なぜなら、コンテクストが既にないからです。 バックトラック・キャシュをレクエストの為にオフすると Ajax 更新エリアでのコンポーネント・アクションが使えなくなるのです。なぜなら、Ajax 更新でリンク生成される と生成されているリンクは保存されない。いつでも、バックトラック・エラーが発生します。
独自ページ・キャシュ。 Ajax の振る舞いを見ると一番いい方法はハイブリッド・キャシュになります。 ある Ajax コンポーネントの最後のバックトラックのみを保持します。その前の 29 の Ajax コンポーネント・アクションは必要ありません。 ユーザがブラウザの戻りボタンをクリックすると戻ることはもっとも不可能です。 ただし、最新のバックトラックがあれば、Ajax 更新エリアのリンクもクリックが可能になります。 この独自ページ・キャシュは上記のロジックを使用しています。 ページが更新する各 Ajax コンポーネントの最後の最新なバックトラック状態を保持します。(一般ページ・キャシュと振る舞いが違います) 一般ページ・キャシュは各ユーザ・バックトラック・リクエストを保持します。独自ページ・キャシュは各 ajax コンポーネントを保持します。 (ページの replacement_page_cache_size 分を許可します) Ajax エリアはリフレッシュされる度、最後の状態が置き換わることです。 restorePage ページ・レクエストが来ると独自ページ・キャシュを先に参照します。独自ページ・キャシュがそのページをリストアができれば、それで完了。 独自ページ・キャシュがリストアするページを見つからない場合には一般ページ・キャシュに処理を委託します。 Ajax を使用しない場合、独自ページ・キャシュはセッション内に存在しないことになります。関連コードはスキップされます。
いろいろテストした結果で、最後の状態のみではなく、最後の二つの状態を保存するようになりました。なぜなら、まれに独自ページ・キャシュは コンテクスト2をコンテクスト3にアップデートし、ブラウザのHTMLはまだコンテクスト3でアップデートされていない場合。ユーザがページを 変わる前にコンテクスト2のリンクをクリックすることになります。ただしそのリンクもちょっど独自ページ・キャシュより削除した為に見つかりません。 二つの状態を保存することでトランスアクション内の問題を防ぐことが可能になります。
savePage
in class com.webobjects.appserver.WOSession
protected void cleanPageReplacementCacheIfNecessary()
protected boolean cleanPageReplacementCacheIfNecessary(String _cacheKeyToAge)
_cacheKeyToAge
- protected NSMutableDictionary _permanentPageCache()
protected com.webobjects.appserver.WOComponent _permanentPageWithContextID(String contextID)
contextID
-
public void _saveCurrentPage()
_saveCurrentPage
in class com.webobjects.appserver.WOSession
protected boolean _shouldPutInPermanentCache(com.webobjects.appserver.WOComponent wocomponent)
wocomponent
- - WOComponentpublic void savePageInPermanentCache(com.webobjects.appserver.WOComponent wocomponent)
savePageInPermanentCache
in class com.webobjects.appserver.WOSession
public com.webobjects.appserver.WOComponent restorePageForContextID(String contextID)
restorePageForContextID
in class com.webobjects.appserver.WOSession
Copyright © 2002 – 2020 Project Wonder.