Welcome to MSDN Blogs Sign in | Join | Help

Kavitak's WebLog

My space on the web...

Syndication

News

Kavita Kamani works at Microsoft. Everything here, though, is her personal opinion and is not read or approved by Microsoft before it is posted. No warranties or other guarantees will be offered as to the quality of the opinions or anything else offered here.
How to write a caching Policy Activity to improve the performance of your WF rules

To follow up on my post from yesterday on Tuning the performance of your WF Rules, here is some code that you can use to write a custom PolicyActivity that does caching of rule sets.

The dictionary caches your rule set.

public class PolicyCacheService : WorkflowRuntimeService

    {

        private Dictionary<Type, RuleDefinitions> ruleCachedDefinitions = new Dictionary<Type, RuleDefinitions>();

 

        public RuleDefinitions GetRuleDefinitions (Type workflowType)

        {

            RuleDefinitions ruleDefinitions = null;

            lock (ruleCachedDefinitions)

            {

                ruleCachedDefinitions.TryGetValue(workflowType, out ruleDefinitions);

                if (ruleDefinitions == null)

                {

                    ruleDefinitions = GetRuleDefinitionsFromManifest(workflowType);

                    ruleCachedDefinitions.Add(workflowType, ruleDefinitions);

                }

            }

            return (ruleDefinitions);

    }

    private RuleDefinitions GetRuleDefinitionsFromManifest(Type workflowType)

    {

            if  (workflowType == null)

                throw new ArgumentNullException("workflowType");

            RuleDefinitions rules = null;

            String resourceName = workflowType.Name + ".rules";

            Stream stream = workflowType.Module.Assembly.GetManifestResourceStream(workflowType, resourceName);

            if  (stream == null)

                stream = workflowType.Module.Assembly.GetManifestResourceStream(resourceName);

            if  (stream != null)

            {

                using (StreamReader reader = new StreamReader(stream))

                {

                    using (XmlReader xmlReader = XmlReader.Create(reader))

                        rules = new WorkflowMarkupSerializer().Deserialize(xmlReader) as RuleDefinitions;

                }

            }

            return rules;

        }

    }

The execute method of your custom activity would look something like this.

Here, you access the rule set from the PolicyCacheService - the PolicyCacheService returns you a rule set from its cache or fetches it from disk.

       protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

        {

            PolicyCacheService polCacheSvc = executionContext.GetService<PolicyCacheService>();

            if (polCacheSvc == null) throw new InvalidOperationException("PolicyCacheService is needed");

            Activity root = this;

            // Getting the root activity

            while (root.Parent!= null)

            {

                root = root.Parent;

            }

            for (int i = 0; i < RuleSetNames.Length; i++)

            {

                RuleDefinitions ruleDefs = polCacheSvc.GetRuleDefinitions(root.GetType());

                RuleSet rs = ruleDefs.RuleSets[RuleSetNames[i]];

                if (rs != null)

                {

                    RuleEngine re = new RuleEngine(rs,root.GetType());

                    re.Execute(root,executionContext);

                }

            }

            return base.Execute(executionContext);

        }

 

Published Tuesday, October 17, 2006 4:38 PM by kavitak

Filed under:

Comments

# Sample custom PolicyActivity @ Tuesday, October 17, 2006 4:47 PM

Today I posted sample code for a policy cache service that caches rule set (so you can get better performance)

The Connected Framework Rules Team Blog

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