nmarus / node-ews

A simple JSON wrapper for the Exchange Web Services (EWS) SOAP API.
MIT License
116 stars 52 forks source link

UpdateItem calls take an excessively long time (5-17 seconds) #58

Closed zarend closed 7 years ago

zarend commented 7 years ago

In my application it takes a long time to make calls to node-ews because parsing the javascript object into soap xml is slow. The worst offender is UpdateItem which spends 5-17 seconds converting the object to xml. Any thoughts on how to combat this. I know this is an issue with node-soap. Any thought to using a faster library?

I can't make our customers wait 17 seconds to update the descriptions their calendar calendar items, and I would really appreciate help with this.

see also https://github.com/CumberlandGroup/node-ews/issues/17

Here is an example request:

  "attributes": {
    "ConflictResolution": "AlwaysOverwrite",
    "SendMeetingInvitationsOrCancellations": "SendToChangedAndSaveCopy"
  },
  "ItemChanges": {
    "ItemChange": {
      "ItemId": {
        "attributes": {
          "Id": "AAMkAGI0MGNiODlkLTIyZDctNDk0ZS04ZDE0LWQ0MjM3NjY4NDEwNgBGAAAAAADyy9tCz3czRKC9BEcqsw4bBwD0GQKYODa9T6eBwEWaUM/rAAAAAAENAAD0GQKYODa9T6eBwEWaUM/rAADyWJ3JAAA="
        }
      },
      "Updates": {
        "SetItemField": [
          {
            "FieldURI": {
              "attributes": {
                "FieldURI": "item:Subject"
              }
            },
            "CalendarItem": {
              "Subject": "shit2"
            }
          },
          {
            "FieldURI": {
              "attributes": {
                "FieldURI": "item:Sensitivity"
              }
            },
            "CalendarItem": {
              "Sensitivity": "Normal"
            }
          },
          {
            "FieldURI": {
              "attributes": {
                "FieldURI": "item:Body"
              }
            },
            "CalendarItem": {
              "Body": {
                "attributes": {
                  "BodyType": "Text"
                },
                "$value": "fuck shitasdfjkl;ajsdkflasjdfklas;dfjkalsd;fajlskd;fjaksld;fjkasd;fajskdl;fjaskld;fjaskdfjas;ldfjk\najskdfl;ajskdlf;ajsdklf;jaskdl;fjaskld;fjaksl;dfjklas;dfjkjsdfkasdjfklasdjflkasdf\nasdjkfl fuck you exchange\nasdjfkasldf"
              }
            }
          },
          {
            "FieldURI": {
              "attributes": {
                "FieldURI": "item:ReminderIsSet"
              }
            },
            "CalendarItem": {
              "ReminderIsSet": "false"
            }
          },
          {
            "FieldURI": {
              "attributes": {
                "FieldURI": "calendar:Start"
              }
            },
            "CalendarItem": {
              "Start": "2017-08-23T02:00:00-07:00"
            }
          },
          {
            "FieldURI": {
              "attributes": {
                "FieldURI": "calendar:End"
              }
            },
            "CalendarItem": {
              "End": "2017-08-23T02:30:00-07:00"
            }
          },
          {
            "FieldURI": {
              "attributes": {
                "FieldURI": "calendar:IsAllDayEvent"
              }
            },
            "CalendarItem": {
              "IsAllDayEvent": "false"
            }
          },
          {
            "FieldURI": {
              "attributes": {
                "FieldURI": "calendar:Location"
              }
            },
            "CalendarItem": {
              "Location": ""
            }
          }
        ]
      }
    }
  }
});
kcastrotech commented 7 years ago

Check out issue #41 where they used the node soap $xml key (https://github.com/vpulim/node-soap#overriding-the-xml-key) to override the xml generator and manually populate the content. Would mean a little work on your end to build the function or loop but could be faster.

zarend commented 7 years ago

I don't want to have to write out the xml for every request because that would defeat the purpose of using this library.

zarend commented 7 years ago

The problem is that converting the object into soap xml takes too long, and this is not the only operation that is slow.

zarend commented 7 years ago

https://github.com/vpulim/node-soap/pull/855/files#diff-0e69590ba3779ce36d55f98da7266b97R1977

@nmarus how does your fix in that work? My new plan is to resurrect that PR, but add a test for it, and write in a way that it is not as exchange specific (such as pass a parameter for finding the child schema a different way)

nmarus commented 7 years ago

Check out #17

The options at this point are to rewrite this lib to use another soap processor which I have been looking into, or as you mention, try a node-soap PR that is not MS wsdl specific as our workaround in #17 did.

Try node-ews 3.0.6 from npm, or try editing the package.json file of recent release to use the forked version of noad-soap with the workaround from vpulim/node-soap/pull/855.

"soap": "https://github.com/cumberlandgroup/node-soap/tarball/master"

Curious if that increases your performance.

zarend commented 7 years ago

Good suggestion – node-ews@3.0.6 works fine for me. I will also attempt making a fix in node-soap.

nmarus commented 7 years ago

Thanks for the feedback. Not sure to classify this as a "bug" or not. We can revert to the forked version of node-soap in the meantime. Further feedback welcome.

zarend commented 7 years ago

I'm stuck on trying to fix node-soap, discussion is in the node-soap gitter/

https://gitter.im/vpulim/node-soap

I'm gonna try using strongloop https://strongloop.com/strongblog/soap-into-rest-apis-with-loopback-node-js/

zarend commented 7 years ago

Didn't get anywhere with loopback, but I found a fix in node-soap. Need to figure out how to write a unit/integration test for it, because node-soap doesn't except pr's that don't have tests.

zarend commented 7 years ago

https://github.com/vpulim/node-soap/pull/968

^ PR to fix node-soap