I blog, you blog, they blog

  • Memory usage in team system web application

    Some important information for the Team System Web Access administrators. If your TSWA account does not have full permissions to the HKLM\SOFTWARE\Microsoft\VisualStudio\9.0\WorkItemTracking\Cache registry path, you may be wasting a lot of resources. The work item store object stores the cache stamp there which is used on subsequent connect to determine what metadata should be obtained from the server and cached locally. If that key is missing, connecting to the server will pull its entire metadata.

    That's right. Every time a new user connects to the server using web access, TSWA downloads the entire metadata (tens or even hundreds of megabytes) just to throw them away.

    To fix that you should grant TSWA account full permissions to the abovementioned registry path.

    This issue appears in VSTS 2008 and 2008 SP1. We're working on a fix for that issue in dev10; we're planning to change storage mechanism so that saving the cache stamp will work with the default TSWA permissions.

  • Metadata Synchronization by the Migration Toolkit

    There was some confusion regarding how the migration toolkit synchronizes work item tracking metadata between two systems, so I have decided to explain it a little bit.

    During every synchronization pass the toolkit calls non-TFS work item store's SynchronizeMetadata method passing reference to a work item tracking project used by the TFS system. Implementing that method is up to tool's authors; the toolkit itself doesn't make any assumptions about what metadata it synchronizes and in which direction such synchronization occurs.

    In case when TFS system is used on both sides, we implement metadata synchronization by copying metadata from the system defined as TFS from the config file, and applying it to the "Source" system. The synchronization is controlled by an optional MetadataSynchronization element under the source-specific TFS node:

    <Session id=”test”>

      <Tfs server=”Foo”>

        …

      </Tfs>

      <Source>

        <Tfs server=”Bar”>

          <MetadataSynchronization types=”all”/>

        </Tfs>

      </Source>

    </Session>

    Here's what you can control:

    Specifying what metadata must be synchronized:

    <MetadataSynchronization types=”accounts lists types all”/>

    “types” attribute specifies what metadata types will be synchronized. “all” is the default value; specifying an empty string disables metadata synchronization

     

    Skipping synchronization of certain work item types:

    <MetadataSynchronization>

      <IgnoredTypes>

        <Name value=”Bug”/>

        <Name value=”Orcas Bug”/>

      </IgnoredTypes>

    </MetadataSynchronization>

    Work items referenced within the IgnoredTypes section will not be synchronized. Unfortunately this feature does not work with work item type mapping.

     

    Skipping synchronization of certain global lists:

    <MetadataSynchronization>

      <IgnoredLists>

        <Name value=”GlobalList1”/>

        <Name value=”GlobalList2”/>

      </IgnoredLists>

    </MetadataSynchronization>

    Global lists referenced within the IgnoredLists section will not be synchronized.

     

  • Team System MSDN Chat

    Another MSDN chat is coming on 8/1/07. We will be holding two sessions: 10:00 AM - 11:00 AM and 4:00 PM - 5:00 PM. Times are in PST.

  • TF26201 and How to Deal With It

    If you customize work item type definitions in TFS, you may have already encountered this error. Witimport works fine and imports your type with no errors; however, saving your work item gives you the following error: "TF26201: This work item has unsupported fields, or user does not have permissions." Go figure... If you do have permissions for saving that work item, you have just encountered a bug in the rules engine.

    Before I explain how to take care of the issue, let me explain briefly the process of rules evaluation in TFS. Rules get evaluated when a new revision is created (all fields), after field's value was changed by user (affected fields only), and before the work item is saved (all fields). Evaluation occurs in two steps (it's a little bit more complicated, but this is enough to explain the issue):

    1. Processing copy & default rules;
    2. Processing all remaining rules.

    Internally the system stores all rules in a form of a flat list; each rule record includes the rule itself, a field it applies to, and a condition defining when the rule applies. Evaluation of rules occurs according to the following algorithm:

    1. Get the next rule.
    2. Apply the rule if its condition is satisfied
    3. Go to step 1.

    Normally the list includes all rules defined in the work item type, but after a single field change it is included to rules defined for that field and all dependencies. Now consider a work item type with the following field definitions:

      <FIELD refname="Sample.Field.1" name="Sample Field 1" type="String">
        <COPY from="value" value="Value 1"/>
      </FIELD>
      <FIELD refname="Sample.Field.2" name="Sample Field 2" type="String">
        <WHEN field="Sample.Field.1" value="Value 1">
          <COPY from="value" value="Value 2"/>
        </WHEN>
      </FIELD>
      <FIELD refname="Sample.Field.3" name="Sample Field 3" type="String">
        <WHEN field="Sample.Field.2" value="Value 2">
          <REQUIRED/>
        </WHEN>
      </FIELD>

    Whether the COPY rule for Field 2 will be executed during the phase 1 after creating a new work item depends on the order in which copy rules will be processed, and that order is not deterministic (although it always stays the same for a single team foundation server). If COPY rule for Field 1 evaluates first, it modifies Field 1, and condition on Field 2 evaluates to true causing its COPY rule to be executed. However, condition on Field 2 does not evaluate to true if Field 2's COPY rule was obtained first (because Field 1 had not been modified); Field 3 will not appear required. Saving the work item will trigger another round of rules evaluation, which will set Field 2 to Value 2 and will implicitly make Field 3 invalid. Saving the work item fails, and you are getting the ugly TF26201 message.

    At this time we do not have a reliable solution for this problem. Here are some tips to ease the pain:

    • After saving a work item failed with this message, you may be able to identify the field causing that failure by analyzing each field's IsValid property.
    • Avoid "chaining" conditions to results of applying a COPY/DEFAULT rule if that rule is located within a condition.
  • Using EMPTY rule in work item type definition.

    It turned out that the article about EMPTY rule in work item type definition XML is incomplete. It doesn't say one very important thing: EMPTY rule not only clears content of the field, but also makes the field read only. If your work item type uses a combination of both EMPTY and READONLY elemnts, consider removing the redundant read only rule.

  • Migration Toolkit Tips and Tricks

    Here's probably the most important thing everyone should know before using the migration toolkit: you must add accout the toolkit will be running under into the TFS Service Accounts group. Here's the command for doing that:

     tfssecurity.exe /server:http://yourserver:8080 /g+ srv: domain\account

    Work items synchronization disables validation of rules when updating the TFS side, and this works only for members of the Service Accounts group. We're trying to recreate history of changes from the opposite side, and validating these changes against the most recent work item type definition is not the best thing to do here.

  • Effective TFS programming: editing work items

    There's not much optimization you can do when saving work items. But when your application updates multiple work items, consider submitting results in a single batch using WorkItemStore.BatchSave method. Here are some important notes about this method:

    • Everything is submitted in a single backend call. This is more efficient then calling WorkItem.Save for each updated item.
    • Everything is submitted in a single transaction. If the method fails, neither work item gets updated.
  • Effective TFS programming: querying

    Querying in TFS is easy. You run a query specifying a filter; you walk through returned items performing certain actions on each returned item. Now after a few runs you start asking yourself: why is it so slow? Here are some non-obvious implementation details that should answer this question.

    A work item returned by a query only has fields specified in the SELECT clause. Accessing a field not from that list results in a roundtrip to the server to obtain that field for this work item (and for 49 other items from that query; we batch reading operations). If your query asks for System.Id, but also obtain Title, Assigned To and other fields, the object model makes a lot of unnecessary database calls behind the scene.

    Accessing collection of links, file attachments, or historical revisions opens the work item. Opening obtains all work item's data in a single roundtrip to the server. It loads ALL fields in ALL revisions; file attachments and links. At the same time accessing fields like Rev, RelatedLinkCount, HyperlinkCount, AttachedFileCount, and ExternalLinkCount does not require opening the item, so it is better to use these fields to check item's number of revisions or file attachments.

    Calling WorkItemStore.GetWorkItem returns you an opened work item with all data. If your program queries work items to access their historical revisions, file attachments, or links, it is better to create a query returning only System.Id field, and call WorkItemStore.GetWorkItem for each returned work item.

    Here's the summary:

    • Always specify fields you're going to work with in the SELECT clause of the query;
    • Use System.Rev and Count fields to check the number of revisions/file attachments/links instead of using corresponding collections;
    • Accessing links/attachments/revisions opens the work item loading all its data. Consider calling WorkItemStore.GetWorkItem for a work item right after it was returned from the query if you need this data.
  • Introduction

    A few words about me and about this blog. I am a developer at Microsoft; have been working here since 2000. I am a member of the Team Foundation Server team (client side of the work item tracking). I have been involved in development of things like work item type definition XML; rules engine, provisioning (import/export) of work item types/global lists, migration toolkit.

    Here I am going to uncover certain secrets of effective usage of work item tracking in TFS. The plan for the nearest future is:

    • Effective querying and accessing work items;
    • Configuring work items synchronization with the migration toolkit.

    Stay tuned!


© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker