Single Insance Codeunit and XML Automation crashes Navision

hxrhxr Member Posts: 20
Navision ver. 4.0 SP3, SQL database.
There is SingleInstance Codeunit1, which has SonicMQTransport Automation object.
SonicMQTransport is a DLL’a, which receives xml messages from Sonic queue and fires event OnXmlMsg(xmlDocument .IDispatch….) to Navision.

From Navision OnXmlMsg event, I take incoming xml document and parse it with another (not singelinstance) Codeunit2.ParseXML(xmlDoc) procedure.

Codeunit2.ParseXML() procedure parses xml, creates response xml and sends it back to SonicMQueue through SonicMQTransport.SendXMLMessage(xmlDoc…) procedure.

Problem is that after few transactions Navision stops receiving xml, event OnXmlMsg do not fire anymore. However, SonicMQTransport dll still works, because I can see incoming xml files are saving to folder (for debug purposes). Sometimes, Navision not only stops receiving xml, but closes without any error messages.
Furthermore, Task Manager shows that after each transaction Mem usage of finsql.exe increases 12-48kb, and on the last transaction Mem usage increases up to 100kb, and Navision stops receiving xml documents.

Actually, I have suspicions about Codeunit, which parses xml. I have noticed one strange thing. If I make response XML and send it back somewhere in the beginning of ParseXML procedure, Navision makes more transaction (let’s say 50). But If Navision covers more code, and goes deeper to other procedures and after creates xml document and send it back to queue, in this case only few transactions is possible (let’s say after 5 trans. Navision stops receiving xmls or even crashed without any error messages)

Maybe somehow I CREATE xml documents wrong. Do I have use CREATE(XML, TRUE) each time? Or Clear(Codeunit2) before parsing? I try to solve this problem two weeks already, and I think that tried everything, but no luck… Maybe there something that I don’t know working with Single Instance codeunits and Automation object..?

I would appreciate any help or ideas,
hxr

p.s. code sample
SingleInstance Codeunit1----------------------------------------------
* OnRun
CLEAR(SonicMQRegVBL);
IF NOT CREATE(SonicMQRegVBL,TRUE) THEN
  ERROR('RegVBL: Communication component not created');
recSetup.GET;
SonicMQRegVBL.broker:= recSetup."RegVBL Sonic broker";
SonicMQRegVBL.sendQueue:= recSetup."RegVBL send queue";
SonicMQRegVBL.receiveQueue:=recSetup."RegVBL receive queue";
SonicMQRegVBL.pwd:= recSetup."RegVBL password";
SonicMQRegVBL.uid:=recSetup."RegVBL user";
SonicMQRegVBL.messageTimeToLive:=0;
SonicMQRegVBL.dbgIncomingMessagePath:=recSetup."RegVBL debug inc. msg. path";
SonicMQRegVBL.Connect;

* SendXMLMsgRegVBL(VAR XMLDoc : Automation "'Microsoft XML, version 2.0'.DOMDocument";VAR XMLPropertiesDoc : Automation "'Microsoft XML..) 
SonicMQRegVBL.SendXmlMessage2(XMLDoc, XMLPropertiesDoc, 0, CorrID);

* SonicMQRegVBL::OnXmlMsg(xmlDocument : Automation "''.IDISPATCH";xmlProps : Automation "''.IDISPATCH")
codRegVBL.ParseXML(xmlDocument, SonicMQRegVBL.MessageId);

Codeunit2 ------------------------------------------------------------------------
ParseXML(varVar : Variant;MsgID : Text[1024])

GlobErrCode :='';
GlobErrText :='';
GlobVBKBID :='';
CLEAR(Cont);

IF NOT ISCLEAR(xmldomdocument) THEN CLEAR(xmldomdocument);
IF NOT ISCLEAR(XMLResp) THEN CLEAR(XMLResp);

CREATE(xmldomdocument);
CREATE(XMLResp);
xmldomdocument.load(varVar);

xmldomdocument.setProperty('SelectionLanguage','XPath');
searchString := 'xmlns:cst=''http://www.company.com/crm/customers''';
tmpVariant := searchString;
xmldomdocument.setProperty('SelectionNamespaces',tmpVariant);

MessageID := MsgID;

s:='cst:RegisterVBL/cst:CustomerInfo';
pxmlroot:=xmldomdocument.selectSingleNode(s);

{...Some parsing goes here...}

ExtractCustInfoToBufferRegVBL(tmpSMQGetCustomerInfo, tmpContactAltAddress, tmpAkc,
  WorkMode, Cont."Dok. tipas", VarDocumentID, GlobVBKBID);
  
IF GlobErrCode <> '' THEN BEGIN
 IF recSMQGetCustomerInfo.GET(tmpSMQGetCustomerInfo.EntryNo) THEN recSMQGetCustomerInfo.DELETE;
 MakeRegVBLErrXMLDoc(XMLResp,GlobErrCode,GlobErrText,GlobVBKBID);
 codADASComm.SendXMLMsgRegVBL(XMLResp, XMLPropertiesDoc, MessageID);
 IF NOT ISCLEAR(xmldomdocument) THEN CLEAR(xmldomdocument);
 IF NOT ISCLEAR(XMLResp) THEN CLEAR(XMLResp);
 EXIT;
END;

{...Some more parsing goes here..}

IF GlobErrCode = '' THEN BEGIN
  MakeRegVBLRespXMLDoc(XMLResp, GlobVBKBID, Cont."No.");
  codADASComm.SendXMLMsgRegVBL(XMLResp, XMLPropertiesDoc, MessageID);
END;

IF NOT ISCLEAR(xmldomdocument) THEN CLEAR(xmldomdocument);
IF NOT ISCLEAR(XMLResp) THEN CLEAR(XMLResp);

{End OF Proc.}

Comments

  • kinekine Member Posts: 12,562
    And did you tried to clear the codeunit before using it?
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • hxrhxr Member Posts: 20
    Yes, but t didn't help.

    There are a lot of XMLDoc and XMLNode objects involved in codeunit2 (parsing),
    interesing is what i wrote above, that for ex. in begining of the procedure
    It can make xml and send it, but at the end of procedure it can't, seems like program
    does not reaches end of procedure and hangs... like some buffer overrun occurs..

    ](*,)
  • ta5ta5 Member Posts: 1,164
    Are you using NAS at the moment - or do you run the single instance codeunits in navision client for testing purposes?
    Thomas
  • hxrhxr Member Posts: 20
    I run single instance codeunit in Navision client for testing purpose.
    No NAS yet.. do You think it will behave differently with NAS?
    Any ideas?

    Thanks,
    hxr
  • ta5ta5 Member Posts: 1,164
    hxr wrote:
    do You think it will behave differently with NAS?
    Any ideas?

    Thanks,
    hxr

    No, in fact I would prefer to develop this way first. If possible try to strip of code blocks step by step to find out what exactly is the "bad" code.
    Thomas
  • hxrhxr Member Posts: 20
    yep, i did it.
    //Here i can create and send back xml messages a lot of times..
      SubRootSTR := '/cst:Contact';
      TMPpxmlroot:=xmldomdocument.selectSingleNode(s + SubRootSTR);
      IF NOT ISCLEAR(TMPpxmlroot) THEN REPEAT
          {Skiped}
            _CntAltAddr.Code := FORMAT(AltAddrID);
            _CntAltAddr."Company Name" := GetInsideNode('cst:SourceTypeCode', 30, TMPpxmlroot);
            _CntAltAddr."Company Name 2" := GetInsideNode('cst:ContactTypeCode', 30, TMPpxmlroot);
            _CntAltAddr.Address := GetInsideNode('cst:Address1', 30, TMPpxmlroot);
            _CntAltAddr."Address 2" := GetInsideNode('cst:Address2', 30, TMPpxmlroot);
          {skiped about 2-3 pages of parsing and assignments goes here..}
        END;
    
        TMPpxmlroot:=TMPpxmlroot.nextSibling;
      UNTIL ISCLEAR(TMPpxmlroot);
    
    //Here I can't send back, looks like program do not reach this place..
    //(for the socond transaction)
    

    Interesting is that, at least once everything works fine, even in this place,
    program can parse and send back xml response, but hangs on second try...
    I'll try to rewrite this nextSibling loop with NodeList object, but i'm not sure..

    My parsing (codeunit2) works fine without SonicMQ transport DLL.
    I have used Timer to check folder each 2 seconds for new XML file,
    parse it and save response xml to same folder. Everything worked good.
    Program successfully parsed 120 files and no hang up.

    The same situation with SonicMQ Transport DLL. It works fine without
    Navision. (Navision starts dll, but does not receive OnXmlMsg event and
    does not parse) So, DLL receives xml message and send response xml message back to
    SonicMQ, tried 100 transactions.

    But together they work unpredictable.. May be some kind of memory
    overrun occurs and Navision stops receiving OnXmlMsg event or even
    closes without any errors displayed.
    Actually i have seen few times C++ Run-Time error buffer overrun,
    finsql.exe.. must be terminated, but usually Navision just stops receiving XML
    (but works other forms and etc...)

    Mystigue..maybe SonicMQ Transport DLL needs to be modified to clear some kind
    of memory after each transaction or sth. like that, if it's possible..

    hxr
  • ta5ta5 Member Posts: 1,164
    Maybe you can try it in Nav 5.1 (just for testing). Btw: Which XML-Version are you using?
    Thomas
  • hxrhxr Member Posts: 20
    Unfortunately, i can't try it with Nav 5.1 because, my client doesn't have it :)
    and in my company there is no SonicMQ

    I use Microsoft XML v. 6.0, SonicMQ uses XML 2.0 i think,
    but actually OnXmlMsg event receives .IDispatch, which i take as Variant
    and later load to my XML 6.0 document object, which i parse, code is below:

    ParseXML(myVar : Variant; MsgID : Text[1024])
    IF NOT ISCLEAR(xmldomdocument) THEN CLEAR(xmldomdocument);
    CREATE(xmldomdocument);
    xmldomdocument.load(myVar);

    :-k may be i can try to load incoming xml as XML version 2.0 object,
    or even take it not by value, but by reference..

    hxr
Sign In or Register to comment.