{"id":354,"date":"2009-09-20T19:47:28","date_gmt":"2009-09-21T03:47:28","guid":{"rendered":"http:\/\/www.ericfeminella.com\/blog\/?p=354"},"modified":"2012-03-04T23:32:06","modified_gmt":"2012-03-05T04:32:06","slug":"instrumenting-remote-procedure-calls-rpc","status":"publish","type":"post","link":"https:\/\/www.ericfeminella.com\/blog\/2009\/09\/20\/instrumenting-remote-procedure-calls-rpc\/","title":{"rendered":"Simple RPC Instrumentation in Flex"},"content":{"rendered":"<p>On occasion developers may find a need to quickly measure the time it takes for a request to a remote service to return a response back to the client without the need to employ an automated testing tool to perform the instrumentation. This information can prove quite valuable for performing application diagnostics on the client and, when measured in terms of code execution, monitoring at the execution level will always be a bit more precise than that which can be measured by using a Network proxy alone, such as <a href=\"http:\/\/www.charlesproxy.com\/\" target=\"_blank\">Charles<\/a> or <a href=\"http:\/\/www.fiddler2.com\/fiddler2\/\" target=\"_blank\">Fiddler<\/a>, etc.<\/p>\n<p>Obviously there are numerous solutions which can be implemented to monitor the elapsed time of a service invocation, however it was my goal to provide a unified solution which could easily be implemented into existing client code without significant refactorings being required.<\/p>\n<p>In order to achieve this I first needed to consider what the typical implementation of a service invocation is in order to isolate the<br \/>\ncommonality. From there it is only a matter of determining a solution that meets the objective in the most non intrusive manner possible.<\/p>\n<p>To begin let us consider what a &#8220;typical&#8221; service invocation might look like for the three most common services available in the Flex Framework; <a href=\"http:\/\/livedocs.adobe.com\/flex\/3\/langref\/mx\/rpc\/http\/HTTPService.html\" target=\"_blank\">HTTPService<\/a>, <a href=\"http:\/\/livedocs.adobe.com\/flex\/3\/langref\/mx\/rpc\/remoting\/mxml\/RemoteObject.html\" target=\"_blank\">RemoteObject<\/a> and <a href=\"http:\/\/livedocs.adobe.com\/flex\/3\/langref\/mx\/rpc\/soap\/WebService.html\" target=\"_blank\">WebService<\/a>.<\/p>\n<pre lang=\"actionscript\">\r\n\r\n\/\/ HTTPService\r\nvar call:AsyncToken = service.send(...);\r\ncall.addResponder( this );\r\n\r\n\/\/ RemoteObject\r\nvar call:AsyncToken = service.someMethod(...);\r\ncall.addResponder( this );\r\n\r\n\/\/ WebService\r\nvar call:AsyncToken = service.someOperation(...);\r\ncall.addResponder( this );\r\n<\/pre>\n<p>Based on the 3 above  implementations we can deduce that the common API used when performing a service invocation is <a href=\"http:\/\/livedocs.adobe.com\/flex\/3\/langref\/mx\/rpc\/AsyncToken.html\" target=\"_blank\">AsyncToken<\/a>. So to provide a unified solution for all three common Services we could either extend AsyncToken or provider an API which wraps AsyncToken. For my needs I chose to implement an API which simply monitors an AsyncToken from which the duration of an invocation can be determined, thus I wrote an RPCDiagnostics API which can be &#8220;plugged&#8221; into an AsyncToken client implementation.<\/p>\n<p>RPCDiagnostics provides basic performance analysis of a Remote Procedure Call by providing a message which displays information about the operation duration via a standard <a href=\"http:\/\/livedocs.adobe.com\/flex\/3\/langref\/package.html#trace%28%29\" target=\"_blank\">trace<\/a> call. In addition, an event listener of type <code>RPCDiagnosticsEvent<\/code> can be added to facilitate custom diagnostics and Logging. <\/p>\n<p>RPCDiagnostics can easily be implemented as an addition to an existing <code>AsyncToken<\/code> or in place of an <code>AsyncToken<\/code>. The following examples demonstrate both implementations.<\/p>\n<p>Implementing <code>RPCDiagnostics<\/code> onto an existing <code>AsyncToken<\/code>:<\/p>\n<pre lang=\"actionscript\">\r\n\r\nvar call:AsyncToken = null;\r\ncall = RPCDiagnostics.monitorToken(service.send(),\"methodName\");\r\ncall.addResponder( ... );\r\n<\/pre>\n<p>Implementing <code>RPCDiagnostics<\/code> in place of an <code>AsyncToken<\/code>:<\/p>\n<pre lang=\"actionscript\">\r\n\r\nvar call:RPCDiagnostics = null;\r\ncall = new RPCDiagnostics( service.send(), \"methodName\" );\r\ncall.addResponder( ... );\r\n<\/pre>\n<p>Implementing a listener to an RPCDiagnostics instance:<\/p>\n<pre lang=\"actionscript\">\r\n\r\nvar call:RPCDiagnostics = null;\r\ncall = new RPCDiagnostics( service.send(), \"operationName\" );\r\ncall.addResponder( ... );\r\ncall.addEventListener( RPCDiagnosticsEvent.EXECUTION_COMPLETE, \r\n                       handler);\r\n<\/pre>\n<p>The RPCDiagnostics API and dependencies can be downloaded via the Open Source AS3 APIs page or from the below links:<\/p>\n<p><a href=\"http:\/\/code.ericfeminella.com\/classes\/as3\/RPCDiagnostics.as.html\" target=\"_blank\">RPCDiagnostics<\/a><br \/>\n<a href=\"http:\/\/code.ericfeminella.com\/classes\/as3\/RPCDiagnosticsEvent.as.html\" target=\"_blank\">RPCDiagnosticsEvent<\/a><br \/>\n<a href=\"http:\/\/code.ericfeminella.com\/classes\/as3\/Execution.as.html\" target=\"_blank\">Execution<\/a> <\/p>\n","protected":false},"excerpt":{"rendered":"<p>On occasion developers may find a need to quickly measure the time it takes for a request to a remote service to return a response back to the client without the need to employ an automated testing tool to perform the instrumentation. This information can prove quite valuable for performing application diagnostics on the client and, when measured in terms&#8230; <a class=\"read-more\" href=\"https:\/\/www.ericfeminella.com\/blog\/2009\/09\/20\/instrumenting-remote-procedure-calls-rpc\/\">Continue Reading<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[42,31,35],"tags":[],"class_list":["post-354","post","type-post","status-publish","format-standard","hentry","category-apis","category-oop","category-software-engineering"],"jetpack_publicize_connections":[],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/posts\/354","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/comments?post=354"}],"version-history":[{"count":0,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/posts\/354\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/media?parent=354"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/categories?post=354"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/tags?post=354"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}