Teamcity, Resharper, Branches & Build Times.

For our builds, the Resharper inspection step is by far and away the longest step in our build chain (build is about 1.30m,   inspect varies between 6 minutes and 16 minutes).

The variation is huge, and it would be great if we can get some consistency in those inspection times.   I believe the inconsistency is caused by Resharper caching its results and the next build using that cache.   If the code is from a similar branch, the inspection is quick, if its from a dissimilar branch, it's much longer.

We have 10 build agents, all the same spec, so TeamCity dishes out these build tasks pretty much at random to an agent.  Therefore when we have development on dissimilar streams, we get lots of long builds.

All of our agents are capable of building all of our projects and branches, we really don't want to limit flexibility by assigning some agents to specific branches, as it busy times, we get bottlenecks and idle (reserved) agents.

Is there a good strategy to deal with this problem?

Alternatively, could I ask for a feature in TeamCity, where the agent selection logic, when all agents are of a similar capability, if an agent is available that last built this branch, it's assigned to this agent again.  This would help I feel.

Alternatively, is there a way Resharper can have multiple caches, so we can have a cache for some of our common branches (develop, master etc).

0
4 comments

Hi Mark,

> is there a way Resharper can have multiple caches, so we can have a cache for some of our common branches

In TeamCity, you can define a parameter that dynamically sets the cache path based on the branch name. This way, each branch will have its own subdirectory for cache files, which helps avoid cache invalidation when switching branches.

In your project or build configuration, go to Parameters and add a new configuration parameter,  for example:

RSHARPER_CACHE_PATH= C:\ReSharperCache\%teamcity.build.branch%

You can replace the path based on your request. 

Then reference this variable in the ReSharper CLI arguments:

--caches-home=%RSHARPER_CACHE_PATH%



For more detailed information, please refer to https://www.jetbrains.com/help/resharper/InspectCode.html#auxiliary-parameters

Best Regards,
Tom

0

Thanks, this is only really a partial solution, and actually can make things worse, potentially MUCH worse.

Currently, a pull request (branch build) would use the common cache, and a percentage of it would be OK to use, some of it would be invalidated, basically what we currently have.

By switching to this suggestion, every pull request branch build would have it's own cache, empty the first time, resulting in long build times, longer than if we had just not used the common cache.  Also, in a multiple agent environment, the chances of an agent from the pool having an cache it can use is low, very low for pull request builds.  The chances are higher for our master branches, however given how agents are allocated, it's still not perfect, as the last agent to build the branch is isn't necessarily the agent that will be chosen.

It feels currently, a hybrid solution is needed, it's not perfect by any means;

  • master branches use a master cache.
  • pull requests builds use a common pull request branch.

This prevents some cross-pollution, but doesn't eliminate it.  What it feels is needed, is something on the server that when all agents are the same performance index, the last agent that build the branch will be favored over other agents, if it's available.  This will help ensure the cache hit rate is higher.

 

0

Also, this doesn't really work, as Reshaper relies on the cache directory existing, it seems it's not smart enough to create it if it's not there.

 java.io.FileNotFoundException:  (The filename, directory name, or volume label syntax is incorrect)

0

Hi Mark,

In your case, I recommend dynamically setting the value for the RSHARPER_CACHE_PATH parameter. You can retrieve the branch name in the build step and then set the RSHARPER_CACHE_PATH based on that branch name.
In a build step (such as Shell, PowerShell, or Bash), you can define the parameter and use TeamCity’s service message format to export it:

echo "##teamcity[setParameter name='RSHARPER_CACHE_PATH' value='dynamic_value']"

You can choose either a common directory or the default ReSharper cache folder on the agent:

<agent_Home>\system\dotnet-tools-inspectcode

>  Also, this doesn't really work, as Reshaper relies on the cache directory existing, it seems it's not smart enough to create it if it's not there.

However, if the cache directory doesn’t exist, ReSharper will create it during the build process. I tested it with TeamCity version 2024.07.3.

Best Regards,
Tom

0

Please sign in to leave a comment.