0

Earlier I raised an issue here Event code multiple page publishing failling. The event code is working fine when i publish single or double pages. But i get the below errors when i publish say 10 or 20 or 100 pages together. It is a random behaviour, sometimes 10 pages get published successfully and sometimes not even two pages get published. There are cases where after 10 pages gets failed in publishing, i am unable to publish single page. In such cases i have to restart all the trdion services, restart the cms, COM+ etc. And after i do that, my single page publishing starts working fine.

The list of random errors i get is :

  1. Class does not support Automation or does not support expected interface.

  2. The operation is not valid for the state of the transaction.

  3. The transaction under which this method call was executing was asynchronously aborted.

But all these errors goes away when i restart everything. I believe there can be some issue in the code? Becuase when i switch off the event code those pages are getting published successfully. Below is code which is run for every page publish. So if i select 20 pages and right click and publish, the below code will run for each page. The code access the component of that page, makes a xml node of it, opens the predefined page (.xml) file and appends the xml node to the component of the predefined page and publish the predefined page finally.After the predefined page gets published via event code, I get a .xml file with all the xml nodes, so if there are 10 xml nodes in the file, publishing a page will add 11th node to it. I am using that xml file for my image gallery and news.

public void ProcessPressReleasePageForPublish(Page page, TcmUri pubTargUri)
    {
        Component compSource = null;
        Page pageDestination = null;
        Component componentDestinaton = null;
        StringBuilder builder = new StringBuilder();
        XmlDocument document = new XmlDocument();
        string prefixUrl = string.Empty;
        Publication publication = (Publication)page.ContextRepository;            

        try
        {                
            this.eventHelper = new EventHelper();
            string str = string.Empty;
            compSource = page.ComponentPresentations[0].Component;
            builder.AppendFormat("<ID>{0}</ID>", compSource.Id);
            ItemFields fieldsMetaCommon = new ItemFields(compSource.Metadata, compSource.MetadataSchema);
            KeywordField fieldSection = (KeywordField)fieldsMetaCommon["pr_section"];
            IList<Keyword> fieldSectionkeywords = fieldSection.Values;
            try
            {
                //Getting section keywords                 
                string strkeywordText = string.Empty;                    
                if (fieldSectionkeywords != null)
                {
                    foreach (Keyword key in fieldSectionkeywords)
                    {
                        builder.AppendFormat("<Section>{0}</Section>", key.Title.ToString());
                    }
                }
            }
            catch (Exception ex)
            {
                EventHelper.WriteEventToHTMLLog("ProcessPressReleasePageForPublish - Error in keyword area: " + ex.StackTrace);
            }


            string strPressTitle = string.Empty;
            SingleLineTextField fieldTitle = (SingleLineTextField)fieldsMetaCommon["pr_title"];
            if (fieldTitle != null && !string.IsNullOrEmpty(fieldTitle.Value))
            {
                strPressTitle = Convert.ToString(fieldTitle.Value);                    
                builder.AppendFormat("<Title>{0}</Title>", strPressTitle);
            }
            string strSummary = string.Empty;                
            XhtmlField multiLineFieldBody = (XhtmlField)fieldsMetaCommon["Summary"];
            if (multiLineFieldBody != null && !string.IsNullOrEmpty(multiLineFieldBody.Value))
            {
                strSummary = Convert.ToString(multiLineFieldBody.Value);                 
                builder.AppendFormat("<Summary><![CDATA[{0}]]></Summary>", strSummary);
            }

            DateField dateFieldPublishDate = (DateField)fieldsMetaCommon["pr_date"];

            if (dateFieldPublishDate != null && dateFieldPublishDate.Value != null)
            {
                string pubDateFormat = string.Empty;
                try
                {
                    pubDateFormat = dateFieldPublishDate.Value.GetDateTimeFormats('s')[0];                        
                    builder.AppendFormat("<Date>{0}</Date>", pubDateFormat);
                }
                catch (Exception)
                { EventHelper.WriteEventToHTMLLog("ProcessPressReleasePageForPublish: ERROR - Date issue"); }
            }

            builder.AppendFormat("<pagetcm>{0}</pagetcm>", page.Id);

            ComponentLinkField linkFieldCaseStudyThumb = fieldsMetaCommon["Thumbnail"] as ComponentLinkField;

            if (linkFieldCaseStudyThumb != null && linkFieldCaseStudyThumb.Value != null && !string.IsNullOrEmpty(linkFieldCaseStudyThumb.Value.ToString()))
            {
                Component tempComponent = linkFieldCaseStudyThumb.Value; //(or linkField.Values[0]                    
                builder.AppendFormat("<Thumbnail>{0}</Thumbnail>", publication.MultimediaUrl + "/" + this.GetImagePublishPath(tempComponent.BinaryContent.Filename, tempComponent.Id));
            }


            builder.AppendFormat("<url>{0}</url>", this.eventHelper.EscapeXMLText(page.PublishLocationUrl));                
            string strURI;
            strURI = this.eventHelper.Value("PressReleaseXMLPage");                
            pageDestination = (Page)publication.GetObject(strURI);                
            componentDestinaton = pageDestination.ComponentPresentations[0].Component;                

            ItemFields fieldsNewCommon = new ItemFields(componentDestinaton.Content, componentDestinaton.Schema);
            MultiLineTextField multiLineFieldXmlData = (MultiLineTextField)fieldsNewCommon["XMLdata"];

            if (multiLineFieldXmlData != null && !string.IsNullOrEmpty(multiLineFieldXmlData.Value))
            {                    
                document.LoadXml(multiLineFieldXmlData.Value.ToString().Trim());
                XmlNode oldChild = document.SelectSingleNode("descendant::PressRelease[ID='" + compSource.Id + "']");

                if (oldChild != null)
                {
                    oldChild.ParentNode.RemoveChild(oldChild);                        
                }
                XmlNode nodePressReleases = document.SelectSingleNode("PressReleases");
                XmlElement newChild = null;
                newChild = document.CreateElement("PressRelease");
                newChild.InnerXml = builder.ToString();
                nodePressReleases.AppendChild(newChild);
                str = document.InnerXml.ToString();                    
                oldChild = null;
                newChild = null;
            }
            else
            {
                str = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<pressreleases><pressrelease>" + builder.ToString() + "</pressrelease></pressreleases>";
            }
            if (componentDestinaton.IsShared)
            {                 
                componentDestinaton.Localize();
            }

            if (componentDestinaton.IsCheckedOut)
            {
                componentDestinaton.CheckIn(true);
            }
            componentDestinaton.CheckOut(true);
            XmlNamespaceManager xMan = new XmlNamespaceManager(componentDestinaton.Content.OwnerDocument.NameTable);
            xMan.AddNamespace("ns", componentDestinaton.Content.NamespaceURI);

            if (componentDestinaton.Content.SelectSingleNode("/ns:Content/ns:XMLdata", xMan) != null)
            {
                componentDestinaton.Content.SelectSingleNode("/ns:Content/ns:XMLdata", xMan).InnerText = str;
            }
            else
            {
                EventHelper.WriteEventToHTMLLog("ProcessPressReleasePageForPublish : ERROR- Final Update Fail");
            }
            bool isCheckOut = componentDestinaton.TryCheckOut();
            try
            {
                componentDestinaton.Save(true);
            }
            catch (Exception ex)
            {
                EventHelper.WriteEventToHTMLLog("ProcessPressReleasePageForPublish - Save Error - " + ex.Message + "-->" + ex.StackTrace);
            }
            if (componentDestinaton.IsCheckedOut)
            {
                componentDestinaton.CheckIn(true);
            }
            List<IdentifiableObject> items = new List<IdentifiableObject>();
            items.Add(pageDestination);
            List<TargetType> targets = new List<TargetType> { new TargetType(pubTargUri, pageDestination.Session) };
            PublishInstruction publishInstruction = new PublishInstruction(pageDestination.Session);
            PublishEngine.Publish(items, publishInstruction, targets, PublishPriority.Normal);                
        }
        catch (Exception exception)
        {
            EventHelper.WriteEventToHTMLLog("ProcessPressReleasePageForPublish: Error -" + exception.Message + "--> StackTrace-" + exception.StackTrace);
        }
        finally
        {
            builder = null;
            document = null;                
           // compSource = null;
           // pageDestination = null;
           // componentDestinaton = null;             
        }
    }

Do you guys see any issue in the code? Or do you think i can improve it especially becuase of the scenario i have here.

4
  • 1
    I haven't seen your code very closely, but I can imagine this issue as a memory leak issue. Do not rely on .NET GC and release your objects as soon as possible. I know you are doing something like that in finally block, but just re-review your code and see if there is any object that you might have missed to release Commented Jul 4, 2014 at 7:54
  • 1
    What is this.eventHelper? I would create a new EventHelper in every method. Are you using the Async event triggers? Try changing that to the Sync triggers. Further, THROW the exceptions, then you see better where it fails and what the actual exception is. Why do you initialize some Tridion items at the top to null?
    – Raimond
    Commented Jul 4, 2014 at 8:29
  • @Raimond - EventHelper is a helper class which has the code to write logs to a xml file when an issue occurs and some common methods. There is no valid reasons of initializing the object to null at the start. What is the other way or what do you suggest ?
    – Varun
    Commented Jul 4, 2014 at 9:37
  • Any other help i can get on this?
    – Varun
    Commented Jul 4, 2014 at 13:11

1 Answer 1

1

The exceptions/errors that you see are most likely bogus. This can be caused by not complying with the Single Threaded Apartment model as required (per the documentation).

What this means is, you can't use static variables in your classes (and "this.eventHelper declaration" is an example where you may be doing this outside of the method which you've shared). Also if you have any multithreaded code (or locking/monitoring), possibly with the logic managing your xml files, then this could be a source of your trouble.

Here is a little more detail on the whole Single Threaded Apartment model with Tridion: http://www.tridiondeveloper.com/static-variables-in-tridion-templates

5
  • I have used static method 'WriteEventToHTMLLog' in my public EventHelper Class. And I use it to write logs to track the steps of the code EventHelper.WriteEventToHTMLLog("Logging starts here"). I have not used any locking mechanism on the log file nor xml file. So just to be more precise.. do you think that the static method declared in the public class EventHelper is creating issue?
    – Varun
    Commented Jul 8, 2014 at 11:53
  • Using the static method should be fine. It's using static variables that's usually a culprit. What exactly is the declaration of this.eventHelper - please share that line of code? Commented Jul 9, 2014 at 8:39
  • Declaration is at the top of the .cs file 'private EventHelper eventHelper;' and i initialize in the method as 'this.eventHelper = new EventHelper();' and use it as 'string strURI ; strURI = this.eventHelper.Value("PressReleaseXMLPage");'
    – Varun
    Commented Jul 9, 2014 at 16:39
  • Any other help on this?
    – Varun
    Commented Jul 16, 2014 at 8:01
  • What is the error stack trace when the pages fail publishing? Commented Jul 16, 2014 at 11:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.