2

I have a strange thing occurring; as usual, I can't post code, unfortunately, so I'm describing the problem in case anyone can suggest a possible cause.

I have an xpage with a custom control included on it; the custom control handles document locking and changing to edit/read-only modes via links. The document locking is done by setting an applicationScope variable based on the UNID. To make it more friendly for other users on the system, I run a function periodically on the page to check whether the document is locked or not and update a link/label/tooltips appropriately (e.g. if locked by another user, then the "Edit" button is disabled; when the lock is released, it's re-enabled). This is done by calling an "xagent" through a standard, simple dojo-based ajax call.

For some reason, the behavior of the system gets erratic after 45 seconds to a minute. I'm checking the lock status every ten seconds or so, so it's not happening with the first call. I'm displaying a list of records associated with the document; each record is a row in a repeat. When I first go into edit mode, the controls are all displayed as they should be, i.e. editable. If the user changes a particular value with a combobox, it updates the whole row with a partial refresh. When things get erratic, I noticed that the row starts refreshing in read-only mode, which suggests to me that the document is changing edit mode. The only time I knowingly change edit mode is if a "Cancel" or "Save" button is pressed. (The locking mechanism itself doesn't have anything to do with the edit mode.)

It certainly seems like the ajax call I'm making is at the root of this. But I've stripped the xagent and the client-side code down to practically nothing, and it's still happening. I can't see what would be causing this behavior. Can anyone hazard a guess? Thanks....

Reid Rivenburgh
  • 373
  • 1
  • 9
  • Another piece of data.... Before realizing that the document seemed to be changing edit mode at some point, the main odd thing I was seeing was that the SSJS script associated with the "Edit" link wasn't being executed. The CSJS actions were, and returning true; the page would do a complete refresh, but the SSJS never ran and the mode never changed to "edit". Pressing it again would do the right thing. Again, this is after idling for 45 seconds to a minute, and it's still the case. – Reid Rivenburgh Jul 14 '15 at 20:14
  • Some more data: If I remove the AJAX call, it works fine. I have stripped that server-side xagent code to the point that it simply returns a hard-coded, dummy javascript variable (nothing to do with locking or Notes documents) as JSON; same result. This has to be something REALLY dumb! – Reid Rivenburgh Jul 14 '15 at 23:42

2 Answers2

4

Maybe check if the server log file has warnings like:

WARNING CLFAD####W: State data not available for /page because no control tree was found in the cache.

If you're seeing those warnings, it could be that the server can no longer find the current XPage page instance in the cache. In that case the page will revert to the initial state, like when the page was first opened. That might be why the document goes to read-only mode.

The session cache of server-side page instances only holds 4 pages when xsp.persistence.mode=basic, or it holds 16 instances when xsp.persistence.mode=file or fileex.

If you load 4 xagent page instances, then that will fill the cache, and it will no longer be able to find the page instance for the current XPage you are viewing. So the XPage will stop performing server-side actions, and partial refresh will always show the initial state of that area of the page.

To avoid that problem, in the xagent page you can set viewState="nostate" on the xp:view tag, so that page instances are not saved for the xagent page, as described here: https://tobysamples.wordpress.com/2014/12/11/no-state-no-problem/

Or else you can create and reuse one page instance for the xagent, so only one is created. That is, on the first call to the XAgent, have the xagent return the $$viewid value for the xagent page instance (#{javascript:view.getUniqueViewId()}), and then in subsequent requests to the xagent use that $$viewid in the request, to restore the existing xagent page instance instead of creating new instances that will fill the cache. So the subsequent xagent requests will be like so:

/myApp.nsf/xagent1.xsp?$$viewid=!aaaaaaaa!

  • It looks like you nailed it, because making the xagent "nostate" seems to have fixed it. Thank you so much! (FYI, I was not seeing any server log output like you described. That would have helped. I'll check with my domino admin about that.) – Reid Rivenburgh Jul 15 '15 at 15:13
  • 1
    The warning was added in 9.0. In earlier releases, it didn't give the warning, but it has always had that behavior (showing the initial page state and not performing actions when there's a cache miss). – Maire Kehoe - IBM Jul 15 '15 at 16:07
  • 1
    The warning message is not in log.nsf but rather in the error-log*.xml files in the IBM_Technical_Support folder in the data directory. Use XPages Log File Reader for easy access to those files – Per Henrik Lausten Jul 15 '15 at 18:49
1

It's hard to troubleshoot without code, but here are a few thoughts:

  1. How are you checking document locking? Via a client-side JavaScript AJAX call or an XPages partial refresh? If the latter, what is the refresh area? If the former, what is the refresh area you're passing and the return HTML? Does it always occur when you're in edit mode on a row and the check happens, or independently of that? The key thing to check here is what the check for locking is doing - is it checking the server and returning a message outside the repeat, or checking the server and returning HTML that overwrites what's currently on the browser with defaults, e.g. the document mode as read mode.
  2. What network activity is happening between the browser and the server and when? Is something else overwriting the HTML for the row, so resetting the row to read mode.

It's unlikely to be random, the key is going to be identifying the reproduceable steps to identify a common scenario/scenarios and cause.

EDIT Following on from your additional info, is there a rendered property on the Edit link? If that calculates to false in earlier JSF lifecycle phases, the eventHandler is not available to be triggered during the Invoke Application phase. Because the eventHandler also includes the refreshId, there is no refreshId and refreshMode, so it defaults to a full refresh with no SSJS running. See this blog post for clarification http://www.intec.co.uk/view-isrenderingphase-and-buttons/.

Paul Stephen Withers
  • 15,699
  • 1
  • 15
  • 33
  • Good questions, Paul. 1. I'm gathering locking info with a client-side AJAX call, not a partial refresh. It's calling an xagent, which is just returning json data, no actual refreshed portion of the page. The locking system only reads/modifies applicationScope; it does nothing else with documents, besides get the UNID if necessary. (I think I got the bulk of the code and idea from Julian Buss.) This is why I don't understand how the mode is changing. 2. I'm looking at the network transfers in the dev tools, and the AJAX call is the only thing happening (as expected). – Reid Rivenburgh Jul 14 '15 at 17:19
  • There is indeed a rendered property on the Edit link; it's the standard "compositeData.theDoc.isEditable()". We use this everywhere, though not normally in a custom contrl. I admit to being uninformed about JSF lifecycle phases, so I'm not sure what is going on exactly.... And am even more confused that whatever is happening, it works fine for the first 45 or so seconds? Thank you for the pointer, though.. I will study the post. – Reid Rivenburgh Jul 14 '15 at 20:54
  • FYI, I completely removed the rendered property, and I still see the same behavior. – Reid Rivenburgh Jul 14 '15 at 20:58
  • The rendered property is probably affecting the full refresh, but it's not clear whether this is two unconnected issues. It sounds like they are. – Paul Stephen Withers Jul 14 '15 at 21:00