Exception with projects sharing a workspace

Topics: User Forum
Mar 12, 2007 at 11:39 AM
I have set up CruiseControl.NET so that we have 2 projects sharing the default workspace, which is never deleted. The build server is multi-processor.

Ocassionally (usually if the machine reboots or at the start of our build time when there are outstanding changes in both projects) I get one of the builds throwing an exception

<cruisecontrol project="Directa 5.00">
<request source="IntervalTrigger" buildCondition="IfModificationExists">IntervalTrigger triggered a build (IfModificationExists)</request>
<build date="12/03/2007 03:00:00" buildtime="00:00:00" buildcondition="IfModificationExists" />
<exception><![CDATA[Microsoft.TeamFoundation.VersionControl.Client.MappingConflictException: The path D:\Builds\Directa\Directa 5.00 is already mapped in workspace CCNET.
at Microsoft.TeamFoundation.VersionControl.Client.InternalCache.CheckForMappingConflicts(WorkspaceInfo workspace)
at Microsoft.TeamFoundation.VersionControl.Client.InternalCache.InsertWorkspace(WorkspaceInfo workspace)
at Microsoft.TeamFoundation.VersionControl.Client.InternalCache.InsertWorkspace(Workspace workspace)
at Microsoft.TeamFoundation.VersionControl.Client.Client.InsertWorkspaceIntoCache(Workspace localWorkspace)
at Microsoft.TeamFoundation.VersionControl.Client.Client.UpdateWorkspace(Workspace workspace, String newName, String newComment, WorkingFolder[] newMappings, String newComputer)
at Microsoft.TeamFoundation.VersionControl.Client.Client.InternalSetWorkingFolder(Workspace workspace, WorkingFolder workingFolder, Boolean isDelete)
at Microsoft.TeamFoundation.VersionControl.Client.Workspace.Map(String serverPath, String localPath)
at ThoughtWorks.CruiseControl.Core.Sourcecontrol.Vsts.GetSource(IIntegrationResult result)
at ThoughtWorks.CruiseControl.Core.IntegrationRunner.Build(IIntegrationResult result)]]></exception>
</cruisecontrol>

Looking at the CCNet.Log (with Debug turned on) you can see that both projects are trying to get modifications at the same time.

2007-03-12 03:00:00,028 Directa 5.00:DEBUG Checking Team Foundation Server for Modifications
2007-03-12 03:00:00,028 Directa 5.00:DEBUG From: 11/03/2007 19:55:45 - To: 12/03/2007 03:00:00
2007-03-12 03:00:00,106 Directa 5.10:DEBUG Checking Team Foundation Server for Modifications
2007-03-12 03:00:00,106 Directa 5.10:DEBUG From: 10/03/2007 06:34:15 - To: 12/03/2007 03:00:00
2007-03-12 03:00:00,153 Directa 5.00:DEBUG Found 1 modifications
2007-03-12 03:00:00,153 Directa 5.00:INFO 1 modification detected.
2007-03-12 03:00:00,153 Directa 5.00:INFO Building: IntervalTrigger triggered a build (IfModificationExists)
2007-03-12 03:00:00,184 Directa 5.10:DEBUG Found 2 modifications
2007-03-12 03:00:00,184 Directa 5.10:INFO 2 modifications detected.
2007-03-12 03:00:00,184 Directa 5.10:INFO Building: IntervalTrigger triggered a build (IfModificationExists)
2007-03-12 03:00:00,200 Directa 5.10:DEBUG Existing workspace detected - reusing
2007-03-12 03:00:00,200 Directa 5.00:DEBUG Existing workspace detected - reusing
2007-03-12 03:00:00,278 Directa 5.10:DEBUG Getting $/Root/Directa/Directa 5.10 to D:\Builds\Directa\Directa 5.10
2007-03-12 03:00:00,278 Directa 5.10:DEBUG Performing a Get Latest
2007-03-12 03:00:00,497 Directa 5.00:INFO Integration complete: Exception - 12/03/2007 03:00:00
2007-03-12 03:00:01,137 Directa 5.10:DEBUG Starting process C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe in working directory D:\Builds\Directa\Directa 5.10 with arguments ..........
2007-03-12 03:00:02,669 Directa 5.10:DEBUG Build started 12/03/2007 03:00:02.

I am assuming this is a concurrency issue, but was not sure where the plugin object is shared by both integration threads and so an issue with CC.NET or whether it was the TFS API that was at fault.

Cheers for any help,

Justin
Mar 12, 2007 at 12:29 PM
Justin,

Would you be able to post snippets of your ccnet.config file so I can see if there is a problem there, or be able to reproduce the problem on my setup? If you would prefer to send me this in a private message then that is fine.

Cheers,

Martin.
Mar 12, 2007 at 1:03 PM
Martin,

I have made minor changes to hide machine names and ports but,

<cruisecontrol>
<project name="Directa 5.00">
<workingDirectory>D:\Builds\Directa\Directa 5.00</workingDirectory>
...
<sourcecontrol type="vsts" autoGetSource="true">
<server>http://tfs:8080</server>
<project>$/Root/Directa/Directa 5.00</project>
<workingDirectory>D:\Builds\Directa\Directa 5.00</workingDirectory>
</sourcecontrol>
...
</project>

<project name="Directa 5.10">
<workingDirectory>D:\Builds\Directa\Directa 5.10</workingDirectory>
...
<sourcecontrol type="vsts" autoGetSource="true">
<server>http://tfs:8080</server>
<project>$/Root/Directa/Directa 5.10</project>
<workingDirectory>D:\Builds\Directa\Directa 5.10</workingDirectory>
</sourcecontrol>
...
</project>
</cruisecontrol>

The only unusual thing is that both projects are under the same TFS project / $/Root as we are currently only using TFS for version control.

Both projects also have a triggers section
<triggers>
<!-- Every 20 minutes check for changes -->
<filterTrigger startTime="20:00" endTime="03:00">
<trigger type="intervalTrigger" seconds="300" />
</filterTrigger>
</triggers>
and 3am is the only time the problem has materialised because the system is checking both projects at the same time.

Cheers,

Justin
Mar 12, 2007 at 4:34 PM
Hmm - so the Directa 5.00 one works fine normally?

This is very odd. I'm going to look into this. As a work-around, you might want to take a look at this blog post from Brad Wilson http://www.agileprogrammer.com/dotnetguy/archive/2007/02/23/22253.aspx where he suggests deleting the workspace. I wonder if it is these workspace issues that he is trying to avoid by working the way he is working. This dramatically increases the download time of the source control though for every build.

Another work-around worth trying to to specify a different workspace name per project. To do this you will need to manually delete the old working folder mappings from that workspace on the build server.
Mar 12, 2007 at 5:23 PM
Martin,

It is random whether 5.00 or 5.10 fails. I guess it is to do with thread synchronisation because the server is dual processor. It is possible that having a different workspace per project will give me a workaround, as it is currently only occasional, I am happy at the moment, but I may move to that model if I get more projects (I was hoping to avoid it).

Is it possible that QueryWorkspaces is returning the same instance of the Workspace object, and once you have called Map() the first time it throws an exception for existing WorkingFolders? I have not tried compiling and testing the plugin myself.

Cheers,

Justin
Mar 12, 2007 at 8:23 PM
Possibly something like that - which would be odd though because the .NET Object Model is supposed to be thread safe and I thought that there was one instance of the plug-in per project invocation. I'm probably doing something stupid in my code. I'll take another look and see.

Cheers,

M.