This would be a "Design of POJO Server" thread but forums are down so am
using this broad distribution list. Those not interested in the
technical details of detecting modified deployments can ignore. :)
I'm looking for some input from the VFS and ProfileService folks.
I'm having an issue where the ClusteredDeploymentRepository is failing
to detect modified deployments. Issue leads to a failure in a newly
added test[1]. What the test does is make some changes in the contents
of the farm/ dir, gives time for the HDScanner to run, and then verifies
that the updated content is deployed in all nodes in the cluster.
Everything works fine for content additions and removals, but modifying
an existing file doesn't work.
Problem is in the ClusteredDeploymentRepository.createModificationInfo()
method, which basically duplicates the logic in
HotDeploymentRepository.getModifiedDeployments(). Loops through the
VirtualFiles representing the root of known deployments, checking if
they are removed, and if not, asking the StructureModificationChecker if
they are modified:
// Check for modification
else if (hasDeploymentContentFlags(pathName,
DeploymentContentFlags.MODIFIED)
|| getChecker().hasStructureBeenModified(root))
{
long rootLastModified = root.getLastModified();
...
// Create the modification info
ModificationInfo info = new ModificationInfo(ctx, rootLastModified,
ModifyStatus.MODIFIED);
modified.add(info);
}
Problem occurs in
AbstractStructureModificationChecker.hasStructureBeenModified(VirtualFile):
if (root == null)
throw new IllegalArgumentException("Null root");
// skip vfs deployment context lookup if archive or file
if (root.isArchive() || root.isLeaf())
return root.hasBeenModified(); // !!! RETURNS FALSE
The problem is root.hasBeenModified() returns false. I don't think
VirtualFile.hasBeenModified() is a safe way to check for modification,
since following a modification, it will return true once and only once.
So whatever code asks first gets "true", later code will get "false".
AFAICT, this is the reason AbstractStructureModificationChecker has a
StructureCache injected -- the cache stores modification timestamps to
avoid this problem.
Shouldn't the timestamps for archives/leaf deployments be stored in the
StructureCache as well? And then check for modification using the
StructureCache's data, same as we do for, e.g. a WEB-INF/web.xml?
FYI, the reason that in this case root.hasBeenModified() returns false
is earlier in the HDScanner run ClusteredDeploymentRepository has
scanned the repository content looking for changes so it can replicate
modified files around the cluster. That scan results in a call to
VirtualFile.getChildren() which ends up calling
AbstractVirtualFileHandler()hasBeenModified().
A final twist:
While experimenting with this manually, I found that the first time I
modify the file, the above problem occurs. But then if I modify the file
again, it gets picked up as modified and redeployed. And thereafter,
every time I modify it, it gets redeployed. Only fails the first time.
I've been poking around a long time and have no explanation for why this is.
[1]
http://hudson.qa.jboss.com/hudson/view/JBoss%20AS/job/JBoss-AS-5.1.x-test...
--
Brian Stansberry
Lead, AS Clustering
JBoss, a division of Red Hat
brian.stansberry(a)redhat.com