Congratulations!

[Valid RSS] This is a valid RSS feed.

Recommendations

This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.

Source: http://feeds.feedburner.com/ElumenotionBlogPosts

  1. <?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
  2. xmlns:content="http://purl.org/rss/1.0/modules/content/"
  3. xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  4. xmlns:dc="http://purl.org/dc/elements/1.1/"
  5. xmlns:atom="http://www.w3.org/2005/Atom"
  6. xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  7. xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  8. >
  9.  
  10. <channel>
  11. <title>InstantQuick</title>
  12. <atom:link href="http://www.instantquick.com/index.php/feed" rel="self" type="application/rss+xml" />
  13. <link>http://www.instantquick.com</link>
  14. <description>Powering SharePoint customizations...</description>
  15. <lastBuildDate>Thu, 01 Nov 2018 12:46:39 +0000</lastBuildDate>
  16. <language>en-US</language>
  17. <sy:updatePeriod>hourly</sy:updatePeriod>
  18. <sy:updateFrequency>1</sy:updateFrequency>
  19. <generator>https://wordpress.org/?v=4.9.17</generator>
  20. <item>
  21. <title>Global Office 365 Developer Bootcamp Atlanta is Saturday Nov 3, 2018</title>
  22. <link>http://www.instantquick.com/index.php/global-office-365-developer-bootcamp-atlanta-is-saturday-nov-3-2018/?c=elumenotion-blog-archive/community-events</link>
  23. <pubDate>Thu, 01 Nov 2018 12:46:39 +0000</pubDate>
  24. <dc:creator><![CDATA[DouglasWare]]></dc:creator>
  25. <category><![CDATA[Community Events]]></category>
  26.  
  27. <guid isPermaLink="false">http://www.instantquick.com/?p=36974</guid>
  28. <description><![CDATA[The Global Office 365 Developer Bootcamp Atlanta is this Saturday! It&#8217;s not too late to register as there are a few slots left before we sell out. You can register here: https://www.eventbrite.com/e/global-office-365-developer-bootcamp-atlanta-registration-48832908544 The Global Office 365 Developer Bootcamp is a free, one-day, hands-on training event led by Microsoft MVPs with support from Microsoft and local &#8230; <a href="http://www.instantquick.com/index.php/global-office-365-developer-bootcamp-atlanta-is-saturday-nov-3-2018/?c=elumenotion-blog-archive/community-events" class="more-link">Continue reading <span class="screen-reader-text">Global Office 365 Developer Bootcamp Atlanta is Saturday Nov 3, 2018</span> <span class="meta-nav">&#8594;</span></a>]]></description>
  29. <content:encoded><![CDATA[<p><img src="http://www.instantquick.com/wp-content/uploads/2018/11/110118_1246_GlobalOffic1.png" alt=""/>
  30. </p>
  31. <p>The Global Office 365 Developer Bootcamp Atlanta is this Saturday! It&#8217;s not too late to register as there are a few slots left before we sell out.
  32. </p>
  33. <p>You can register here: <a href="https://www.eventbrite.com/e/global-office-365-developer-bootcamp-atlanta-registration-48832908544">https://www.eventbrite.com/e/global-office-365-developer-bootcamp-atlanta-registration-48832908544</a>
  34. </p>
  35. <p>The Global Office 365 Developer Bootcamp is a free, one-day, hands-on training event led by Microsoft MVPs with support from Microsoft and local community leaders. Developers worldwide are invited to attend a local bootcamp to learn the latest on the Office 365 platform with topics ranging from Microsoft Graph, SharePoint Framework, Microsoft Teams, Office Add-ins, Connectors and Actionable Messages. Developers can then apply these learnings to their existing products or solutions to achieve more right away or begin planning how to apply what they learn to their future projects.
  36. </p>
  37. <p>Watch the <a href="https://www.youtube.com/watch?v=V65ASGgZksw" target="_blank">video</a> to hear from Jeff Teper and Microsoft MVPs on 2018 Global Office 365 Developer Bootcamp.
  38. </p>
  39. <p><strong>Technologies covered</strong>: Microsoft Graph, Microsoft Teams, Office Add-ins, Connectors and Actionable Messages, and more. To be successful in this workshop, you should have a general understanding of Office 365, SharePoint, Microsoft Teams and an ability to code in C# or JavaScript.
  40. </p>
  41. <p><strong>Come Prepared</strong>:
  42. </p>
  43. <ul>
  44. <li>You will need to bring along your own laptops. We&#8217;ll help with any tools you need to download and install to get you up and running.
  45. </li>
  46. <li>An Office 365 Developer Tenant (<a href="https://developer.microsoft.com/en-us/office/dev-program" target="_blank">free</a>) to make the most out of these sessions.
  47. </li>
  48. <li>A basic understanding of Office 365 and Microsoft Azure is recommended.
  49. </li>
  50. </ul>
  51. <p><strong>Bootcamp Agenda (each session provides a brief topic intro and Hands on Labs)</strong>:
  52. </p>
  53. <p>8:00am &#8211; Doors Open &#8211; Registration, Coffee, Networking<br />8:45am &#8211; 9:00am Welcome and Introduction to the Global Office 365 Developer BootCamp<br />9:00am &#8211; 12:00pm Morning Sessions <br />12:00pm &#8211; 1:30pm Lunch <br />1:30pm &#8211; 4:30pm Afternoon Sessions <br />4:30pm &#8211; 5:00pm Closing
  54. </p>
  55. <p><strong>Sessions</strong>: Attendees can choose to attend the following sessions (each session repeated in AM and PM slots)
  56. </p>
  57. <ol>
  58. <li>Microsoft Teams Apps – Tabs, Connectors and Bots
  59. </li>
  60. <li>Microsoft Graph &amp; Actionable Messages
  61. </li>
  62. <li>Building Office Addins with Modern JavaScript
  63. </li>
  64. </ol>
  65. ]]></content:encoded>
  66. </item>
  67. <item>
  68. <title>Atlanta Code Camp 2018 is Saturday!</title>
  69. <link>http://www.instantquick.com/index.php/atlanta-code-camp-2018-is-saturday/?c=elumenotion-blog-archive/random-whatnot</link>
  70. <pubDate>Tue, 11 Sep 2018 14:48:26 +0000</pubDate>
  71. <dc:creator><![CDATA[DouglasWare]]></dc:creator>
  72. <category><![CDATA[Random Whatnot]]></category>
  73.  
  74. <guid isPermaLink="false">http://www.instantquick.com/?p=36954</guid>
  75. <description><![CDATA[This is always a great event and I am proud to be part of it. We would love to see you there at Kennesaw State University, Marietta Campus! Our website is here &#8211; https://www.atlantacodecamp.com/2018 and you should go there right now and register! Can&#8217;t make it? If you are into Office development, please register for &#8230; <a href="http://www.instantquick.com/index.php/atlanta-code-camp-2018-is-saturday/?c=elumenotion-blog-archive/random-whatnot" class="more-link">Continue reading <span class="screen-reader-text">Atlanta Code Camp 2018 is Saturday!</span> <span class="meta-nav">&#8594;</span></a>]]></description>
  76. <content:encoded><![CDATA[<p>This is always a great event and I am proud to be part of it. We would love to see you there at Kennesaw State University, <span style="text-decoration:underline"><strong>Marietta Campus</strong></span>!
  77. </p>
  78. <p>Our website is here &#8211; <a href="https://www.atlantacodecamp.com/2018">https://www.atlantacodecamp.com/2018</a> and you should go there right now and register!
  79. </p>
  80. <h3>Can&#8217;t make it?<br />
  81. </h3>
  82. <p>If you are into Office development, please register for the Office Developer Global Bootcamp (Atlanta Edition) on Nov 3. <br /><a href="https://www.eventbrite.com/e/global-office-365-developer-bootcamp-atlanta-registration-48832908544">https://www.eventbrite.com/e/global-office-365-developer-bootcamp-atlanta-registration-48832908544</a>
  83. </p>
  84. <p>&#8211;Doug Ware</p>
  85. ]]></content:encoded>
  86. </item>
  87. <item>
  88. <title>Understanding Azure Functions with Pictures of Lightning</title>
  89. <link>http://www.instantquick.com/index.php/understanding-azure-functions-with-pictures-of-lightning/?c=elumenotion-blog-archive/random-whatnot</link>
  90. <pubDate>Tue, 30 Jan 2018 23:10:53 +0000</pubDate>
  91. <dc:creator><![CDATA[DouglasWare]]></dc:creator>
  92. <category><![CDATA[Azure Functions]]></category>
  93. <category><![CDATA[Random Whatnot]]></category>
  94.  
  95. <guid isPermaLink="false">http://www.instantquick.com/?p=36804</guid>
  96. <description><![CDATA[Consider the Logo The Azure Functions logo is a lightning bolt. This is how lightning works in the real world according to this fourth grade science text. Much like the real world, Azure Functions can be described as an environment. We call this the Azure Functions Runtime. You can think of the system that creates &#8230; <a href="http://www.instantquick.com/index.php/understanding-azure-functions-with-pictures-of-lightning/?c=elumenotion-blog-archive/random-whatnot" class="more-link">Continue reading <span class="screen-reader-text">Understanding Azure Functions with Pictures of Lightning</span> <span class="meta-nav">&#8594;</span></a>]]></description>
  97. <content:encoded><![CDATA[<h1>Consider the Logo</h1>
  98. <p>The Azure Functions logo is a lightning bolt.
  99. </p>
  100. <div style="text-align: center"><img src="http://www.instantquick.com/wp-content/uploads/2018/01/013018_2310_Understandi1.png" alt=""/>
  101. </div>
  102. <p></p>
  103. <p>This is how lightning works in the real world according to this <a href="http://www.eduplace.com/kids/sla/4/lightning.html">fourth grade science text</a>.
  104. </p>
  105. <div style="text-align: center"><img src="http://www.instantquick.com/wp-content/uploads/2018/01/013018_2310_Understandi2.jpg" alt=""/>
  106. </div>
  107. <p></p>
  108. <p>Much like the real world, Azure Functions can be described as an environment. We call this the Azure Functions Runtime.
  109. </p>
  110. <div style="text-align: center"><img src="http://www.instantquick.com/wp-content/uploads/2018/01/013018_2310_Understandi3.png" alt=""/>
  111. </div>
  112. <p></p>
  113. <p>You can think of the system that creates lightning as a function of the environment.
  114. </p>
  115. <div style="text-align: center"><img src="http://www.instantquick.com/wp-content/uploads/2018/01/013018_2310_Understandi4.png" alt=""/>
  116. </div>
  117. <p></p>
  118. <p>The function happens in the environment when the right conditions are met causing an event that triggers the function (such as a file being uploaded to storage).
  119. </p>
  120. <div style="text-align: center"><img src="http://www.instantquick.com/wp-content/uploads/2018/01/013018_2310_Understandi5.png" alt=""/>
  121. </div>
  122. <p></p>
  123. <p>A binding is what provides the information from the triggered event to a function instance. (ok, this one is a bit of a stretchy analogy).
  124. </p>
  125. <div style="text-align: center"><img src="http://www.instantquick.com/wp-content/uploads/2018/01/013018_2310_Understandi6.png" alt=""/>
  126. </div>
  127. <p></p>
  128. <p>Execution is when it all comes together and the function runs.
  129. </p>
  130. <div style="text-align: center"><span style="color:#fc4242; font-family:Arial; font-size:32pt">DestroyTree(lightning);</span>
  131. </div>
  132. <div style="text-align: center"><img src="http://www.instantquick.com/wp-content/uploads/2018/01/013018_2310_Understandi7.jpg" alt=""/>
  133. </div>
  134. <p></p>
  135. <div>
  136.  </div>
  137. <h1>How Azure Consumption Pricing Saves Money Compared to Buying Servers<br />
  138. </h1>
  139. <div>You pay for the lightning bolts, not for the sky. With consumption-based pricing clear skies cost nothing but with infinite* scalability you can simulate Harvey AND Irma if needed.
  140. </div>
  141. <div>&#8211;Doug</div>
  142. ]]></content:encoded>
  143. </item>
  144. <item>
  145. <title>Five Tips for Organizing Functions in Azure Functions</title>
  146. <link>http://www.instantquick.com/index.php/five-tips-for-organizing-functions-in-azure-functions/?c=azure-functions</link>
  147. <pubDate>Mon, 22 Jan 2018 22:10:53 +0000</pubDate>
  148. <dc:creator><![CDATA[DouglasWare]]></dc:creator>
  149. <category><![CDATA[Azure Functions]]></category>
  150.  
  151. <guid isPermaLink="false">http://www.instantquick.com/?p=36714</guid>
  152. <description><![CDATA[A function is the primary concept in Azure Functions. However, in terms of and configuration and deployment the primary concept is the Azure Function App. The Function App is the runtime host that contains one or more functions. A Function App is the runtime configuration, application settings and runtime host shared by individual functions that &#8230; <a href="http://www.instantquick.com/index.php/five-tips-for-organizing-functions-in-azure-functions/?c=azure-functions" class="more-link">Continue reading <span class="screen-reader-text">Five Tips for Organizing Functions in Azure Functions</span> <span class="meta-nav">&#8594;</span></a>]]></description>
  153. <content:encoded><![CDATA[<p><a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference">A function is the primary concept in Azure Functions</a>. However, in terms of and configuration and deployment the primary concept is the <a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-how-to-use-azure-function-app-settings">Azure Function App</a>. The Function App is the runtime host that contains one or more functions. A Function App is the runtime configuration, application settings and runtime host shared by individual functions that collectively make up the function app&#8217;s runtime components.
  154. </p>
  155. <p>The organization of your function apps directly affect the performance, maintainability, and cost of solutions that take advantage of function apps.
  156. </p>
  157. <p>There really are no hard and fast rules about deciding how to organize your functions into function apps, but this post is about some of the things I personally take into account when I build my own function apps in no particular order.
  158. </p>
  159. <h1>1… First and foremost, aim strong cohesion and loose coupling<br />
  160. </h1>
  161. <p><a href="https://en.wikipedia.org/wiki/Cohesion_(computer_science)">Cohesion</a> means that the functions belong together. This one is easy! A function app with a grab bag of unrelated functions is a bad idea. With consumption based plans there is a negligible difference between one function app with five functions or five function apps with containing a single function. In either case you are charged based on invocations. However, it is possible for two functions to be logically cohesive but still choose to deploy the functions as separate function apps for reasons related to runtime performance or scalability needs.
  162. </p>
  163. <p><a href="https://en.wikipedia.org/wiki/Coupling_(computer_programming)">Coupling</a> is the degree to which the functions in a function app depend on each other and also the degree to which a function depends on the runtime host. In both cases the goal is to have none because that means we can deploy a function wherever we want and move it around easily and not just between function apps but also other types of runtime environment including AWS Lambda and traditional servers. However, if functions are highly cohesive, it makes sense to accept some coupling for shared management and configuration. There is no generic advantage to a grab-bag function, but there are disadvantages to isolating related functions into different function apps.
  164. </p>
  165. <h1>2… Organize according to usage patterns and performance profiles<br />
  166. </h1>
  167. <p>Azure function invocation is based on triggers. When something happens, the event trigger fires the function. This could be from a popular application calling a web service with a user who is eagerly waiting for a reply or it could be an event type that happens frequently but not continuously that runs a function that takes minutes to complete and uses significant resources.
  168. </p>
  169. <p>The <a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-scale">Scale Controller</a> monitors the rate of events and determines whether to scale in or out. Because these two functions have completely different runtime characteristics the result is unlikely to be optimal. Consider that, if the combination of unrelated performance profiles is difficult for software, how bad is it for the poor human!
  170. </p>
  171. <p>I feel pretty strongly that <a href="https://azure.microsoft.com/en-us/services/application-insights/"><strong>Application Insights</strong></a> is a must have addition to any function app. One thing I like about it is how useful it is out of the box.
  172. </p>
  173. <p>Mixing things that are fast with things that are slow makes it much less useful because are those spikes expected because the slow thing is happening or is it because the thing that should be fast is slow?
  174. </p>
  175. <h1>3… Don&#8217;t Deploy Functions Together Unless You Can Accept the Requirement to Version Them Together<br />
  176. </h1>
  177. <p>If you bundle functions together into a function app, always version and test the functions as a set. Build them together and deploy them together.
  178. </p>
  179. <p>This is my experience with C# and NuGet. I don&#8217;t know if this same advice applies in JavaScript (npm) or Java (idk) hosts, but I <span style="text-decoration:underline">imagine</span> similar issues.
  180. </p>
  181. <p>Imagine that you have multiple functions in a function app and you are using precompiled functions. In your implementation, each of your functions is implemented in its own .NET class library. You use NuGet and some function class libraries have shared dependencies that are indirect and could be different versions. In a normal .NET executable or like a console application or a web site. The final program folder when everything is built has an app.config or web.config file that specifies how to handle conflicts via a .NET feature known as <a href="https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/redirect-assembly-versionshttps:/docs.microsoft.com/en-us/dotnet/framework/configure-apps/redirect-assembly-versions">Assembly Binding Redirection</a>.
  182. </p>
  183. <p>Your function app might be broken from the start or work fine at first, but stop working after updating a NuGet package in one of the function assemblies with an exception &#8211;
  184. </p>
  185. <p>&#8220;Could not load file or assembly &#8216;…&#8217; or one of its dependencies. The system cannot find the file specified.&#8221;
  186. </p>
  187. <p>or maybe
  188. </p>
  189. <p>&#8220;Exception has been thrown by the target of an invocation. <strong>…</strong>: Method not found: <strong>…</strong>&#8221;
  190. </p>
  191. <p>The dots in both cases are whichever of the conflicting assemblies loads second because of the conflict.
  192. </p>
  193. <p>The easiest solution to this problem is to not have a conflict by resolving the conflict to a single version. If this can&#8217;t be done, moving the functions into their own function apps.
  194. </p>
  195. <h1>4… If you require a traditional app service plan, use a traditional app service plan<br />
  196. </h1>
  197. <p>A consumption plan is not always the best fit for every scenario. If you need a job that takes more than 10 minutes or a web service that should always be available in loaded instances (so as to never make a user wait for loading and scaling) use an App Service Plan instead of a consumption plan. In most cases it will not be worth the time to try to find ways to work around the known limits of the consumption plan. If you have significant free capacity, consider hosting other compute functionality in this app service plan, but <span style="text-decoration:underline"><strong>remember tip #2</strong></span>.
  198. </p>
  199. <p>But…
  200. </p>
  201. <h1>5… If you need auto-scaling or you don&#8217;t have a requirement that prevents it, use a consumption plan<br />
  202. </h1>
  203. <p>It is probably waaaay cheaper and more likely to be optimal than whatever manual tuning you try.</p>
  204. ]]></content:encoded>
  205. </item>
  206. <item>
  207. <title>Remote Debugging Azure Functions from Visual Studio Stops Working</title>
  208. <link>http://www.instantquick.com/index.php/remote-debugging-azure-functions-from-visual-studio-stops-working/?c=azure-functions</link>
  209. <pubDate>Wed, 10 Jan 2018 18:32:16 +0000</pubDate>
  210. <dc:creator><![CDATA[DouglasWare]]></dc:creator>
  211. <category><![CDATA[Azure Functions]]></category>
  212. <category><![CDATA[Serverless]]></category>
  213. <category><![CDATA[Visual Studio]]></category>
  214.  
  215. <guid isPermaLink="false">http://www.instantquick.com/?p=36694</guid>
  216. <description><![CDATA[…and what you can learn from it &#8220;The first thing you must keep in mind when you start using a serverless computing platform like Azure Functions is that everything is different, especially when things are obviously the same.&#8221;&#8211;Abraham Lincoln, 1863 If you develop Azure Functions with Visual Studio it is easy to debug a function &#8230; <a href="http://www.instantquick.com/index.php/remote-debugging-azure-functions-from-visual-studio-stops-working/?c=azure-functions" class="more-link">Continue reading <span class="screen-reader-text">Remote Debugging Azure Functions from Visual Studio Stops Working</span> <span class="meta-nav">&#8594;</span></a>]]></description>
  217. <content:encoded><![CDATA[<h1>…and what you can learn from it<br />
  218. </h1>
  219. <blockquote>
  220. <p><strong>&#8220;The first thing</strong> you must keep in mind when you start using a serverless computing platform like Azure Functions is that everything is different, especially when things are obviously the same.&#8221;<br />&#8211;Abraham Lincoln, 1863
  221. </p>
  222. </blockquote>
  223. <p><span style="color:black">If you develop Azure Functions with Visual Studio it is easy to debug a function app running in the cloud. All you have to do is right-click the function app in <strong>Server Explorer</strong> and you are in business.<br />
  224. </span></p>
  225. <p><img src="http://www.instantquick.com/wp-content/uploads/2018/01/011018_1832_RemoteDebug1.png" alt=""/>
  226. </p>
  227. <p>Although it is possible (and ultimately easier in many cases) to debug locally, remote debugging works well and is most convenient. If you choose a consumption plan to make it basically free (you totally did, you know you did!), eventually you may see the dreaded message <strong>&#8220;The breakpoint will not currently be hit. No symbols have been loaded for this document.&#8221;<br />
  228. </strong></p>
  229. <p>You and I both know that your first reaction to this problem will be to open your favorite search engine which might lead you to a site named Stack Overflow where you might find the following article: <a href="https://stackoverflow.com/questions/46764732/visual-studio-2017-remote-debugging-azure-api-app-the-breakpoint-will-not-curr">visual studio 2017 remote debugging azure api app: &#8220;The breakpoint will not currently be hit. No symbols have been loaded for this document.&#8221;</a><strong><br />
  230. </strong></p>
  231. <p>You will try the suggestion and it might work. You will also be see that it was a bug, but it&#8217;s been fixed until you check and realize you have that or some later update and think <strong>&#8220;this is a bug and they broke it again!&#8221;</strong>
  232. </p>
  233. <h2>It isn&#8217;t a bug and it probably won&#8217;t be fixed!<br />
  234. </h2>
  235. <p>A slightly different problem that might happen for the same reason is that the breakpoint will light up in the Visual Studio editor, but execution won&#8217;t stop, or it will stop some of the time but not other times. Maybe you&#8217;ll restart the function app and it will work for awhile.
  236. </p>
  237. <p><strong>&#8220;Ah-hah! I have found a bug,&#8221;</strong> you will think, and head to <a href="https://github.com/Azure/Azure-Functions/issues/538">github</a> to enter an issue such as this one: <a href="https://github.com/Azure/Azure-Functions/issues/538">Remote debugging woes #538</a>.
  238. </p>
  239. <p><img src="http://www.instantquick.com/wp-content/uploads/2018/01/011018_1832_RemoteDebug2.png" alt=""/>
  240. </p>
  241. <h2>The Cause and the Lessons Learned<br />
  242. </h2>
  243. <p>My experience with my first &#8216;development&#8217; function app came from the fact that I started with one function and kept adding them. Back then the tools were pretty limited and it was (again) an easy thing to do. I had a variety of triggers in that app and the one I was working on was long running and used much more capacity than a short running web service. If during my development testing I put it under load by sending more than a few messages into the queue at a time, Azure Functions would very helpfully scale my function and helpfully create more instances automatically. Once this happens there is no way to attach to the right instance other than by shear luck because there is no way <strong>in a default configuration</strong> to steer all requests to a single instance. Furthermore, there is isn&#8217;t any way for the Azure Functions host to identify that a particular random message you sent should be treated uniquely and routed to the one instance out of however many there for debugging.
  244. </p>
  245. <p>There are a few lessons I learned as a result if this experience that I can share. Here are my top 5.
  246. </p>
  247. <ol>
  248. <li>Never forget that in the default state of a consumption plan, there can (and probably will) be multiple instances.
  249. </li>
  250. <li>If you have more than one function in a function app, one of them might be causing the app to scale even if the one you want to debug has no or very little traffic.
  251. </li>
  252. <li>Good logging plus Application Insights are things use should strongly consider using throughout your application lifecycle. Logging, because you can&#8217;t assume you will be able to remotely debug all scenarios in development or even locally. And Application Insights because it makes it possible to understand and visualize complex and heavy load runtime behaviors.
  253. </li>
  254. <li>There are a number of configuration &#8216;knobs&#8217; you can turn that affect scaling behavior and the number of instances for a given function. I will be writing about this in more depth in a future post.
  255. </li>
  256. <li>There are a lot of things to consider when combining functions in a single app. I will also be writing about this in more depth in a future post.
  257. </li>
  258. </ol>
  259. <p>Thanks for reading!
  260. </p>
  261. <p>&#8211;Doug Ware
  262. </p>
  263. <p>P.S. Application Insights makes it easy to see how many instances are active. However, if you are not using Application Insights and prefer to bang rocks together, you can use Process Explorer from the Platform Features tab of the function app in the portal. If you click it and it takes a very long time to load, that is a good sign that there are a bunch of instances, but eventually it will usually display a list.
  264. </p>
  265. <p><img src="http://www.instantquick.com/wp-content/uploads/2018/01/011018_1832_RemoteDebug3.png" alt=""/>
  266. </p>
  267. <p>
  268.  </p>
  269. <p>
  270.  </p>
  271. ]]></content:encoded>
  272. </item>
  273. <item>
  274. <title>Some Real Performance Numbers from Some Real Azure Functions</title>
  275. <link>http://www.instantquick.com/index.php/some-real-performance-numbers-from-some-real-azure-functions/?c=azure-functions</link>
  276. <pubDate>Tue, 09 Jan 2018 21:25:41 +0000</pubDate>
  277. <dc:creator><![CDATA[DouglasWare]]></dc:creator>
  278. <category><![CDATA[Azure Functions]]></category>
  279. <category><![CDATA[Serverless]]></category>
  280.  
  281. <guid isPermaLink="false">http://www.instantquick.com/?p=36594</guid>
  282. <description><![CDATA[I&#8217;ve been using Azure Functions in various production systems since late 2016. If you wonder how real apps perform using a consumption plan with auto-scaling (which means pay as you go based on usage), I have some data for you! First up is the most commonly executed function in my busiest production installation of Azure &#8230; <a href="http://www.instantquick.com/index.php/some-real-performance-numbers-from-some-real-azure-functions/?c=azure-functions" class="more-link">Continue reading <span class="screen-reader-text">Some Real Performance Numbers from Some Real Azure Functions</span> <span class="meta-nav">&#8594;</span></a>]]></description>
  283. <content:encoded><![CDATA[<p>I&#8217;ve been using Azure Functions in various production systems since late 2016. If you wonder how real apps perform using a consumption plan with auto-scaling (which means pay as you go based on usage), I have some data for you!
  284. </p>
  285. <p><span style="font-size:22pt"><strong>First up</strong><br />
  286. </span>is the most commonly executed function in my busiest production installation of <a href="https://github.com/InstantQuick/AzureFunctionsForSharePoint"><strong>Azure Functions for SharePoint</strong></a>. The <a href="https://afspdocs.blob.core.windows.net/docs/articles/EventDispatch.html"><strong>EventDispatch</strong></a> function receives event notifications from various SharePoint Online tenants for a few different apps. When something of interest happens in a SharePoint site, Microsoft sends the EventDispatch function an HTTP POST request. EventDispatch process this message and drops the result into the Service Bus queue for whatever app that created the event receiver subscription.
  287. </p>
  288. <p>Over the last 8 days or so this function was triggered around 40,000 times a day at an error rate of about 4 per day.
  289. </p>
  290. <p><img src="http://www.instantquick.com/wp-content/uploads/2018/01/010918_2146_SomeRealPer1.png" alt=""/>
  291. </p>
  292. <p>SharePoint waits for a response from the event receiver for some events and a user experiences this as a delay when this kind of event fires. Therefore, EventDispatch needs to run quickly. One thing people new to Azure Functions sometimes notice is with consumption-based function apps is that functions triggered by web requests are slow during requests that cause Azure to load the function. Fortunately, the traffic to this function is steady. This means that the startup operation happens in a tiny percent of requests and performance is excellent.
  293. </p>
  294. <p>The following charts show what normal traffic looks like. Scouts honor! I opened the <a href="https://azure.microsoft.com/en-us/services/application-insights/">Application Insights</a> for this app and took a screenshot of the point in time sometimes there is much more traffic and other times there is much less.
  295. </p>
  296. <p><img src="http://www.instantquick.com/wp-content/uploads/2018/01/010918_2146_SomeRealPer2.png" alt=""/>
  297. </p>
  298. <p>This function app and its associated storage account costs me less around $10 a month. The storage account is around 60% of the total cost and there is room for some optimization.
  299. </p>
  300. <p><span style="font-size:22pt"><strong>Next up</strong></span> is application specific functionality hosted in a different function app in a different Azure tenant. This particular function app is a bit of a grab bag in terms of individual functions and has a lot of room for improvement in a couple of ways, the least of which is the mingling of a long-running process that introduces a few other issues which are a subject for another day and another post.
  301. </p>
  302. <p>The long running process fires periodically based on scheduled message delivery and that schedule causes all of the messages to begin delivery at the same time subject. On top of that, the way I wrote it is dumb and the job takes much longer to execute than it should. So, during the periods when it runs it forces the function app to scale and load on a lot of servers. The numbers are pretty grim.
  303. </p>
  304. <p><img src="http://www.instantquick.com/wp-content/uploads/2018/01/010918_2146_SomeRealPer3.png" alt=""/>
  305. </p>
  306. <p>That high server count represents instances of the app, and it is wasted consumption that costs money. One thing I have noticed is that instances are slow to unwind.
  307. </p>
  308. <p>Nevertheless, this badly written function inside this grab-bag app still only costs around $45 a month. I haven&#8217;t fixed it because the cost is too low to justify fixing it.</p>
  309. ]]></content:encoded>
  310. </item>
  311. <item>
  312. <title>Task Runner Explorer is the Best Visual Studio Feature You Probably Aren’t Using</title>
  313. <link>http://www.instantquick.com/index.php/task-runner-explorer-is-the-best-visual-studio-feature-you-probably-arent-using/?c=elumenotion-blog-archive/random-whatnot</link>
  314. <pubDate>Thu, 26 Jan 2017 13:37:24 +0000</pubDate>
  315. <dc:creator><![CDATA[DouglasWare]]></dc:creator>
  316. <category><![CDATA[Random Whatnot]]></category>
  317. <category><![CDATA[Visual Studio]]></category>
  318.  
  319. <guid isPermaLink="false">http://www.instantquick.com/?p=36511</guid>
  320. <description><![CDATA[TL;DR – There is a handy feature in VS 2015 called Task Runner Explorer that you can use to run PowerShell or batch commands to do just about anything. You can also bind these to build events. A task runner is a program that runs tasks. If you&#8217;ve been doing much web development these past &#8230; <a href="http://www.instantquick.com/index.php/task-runner-explorer-is-the-best-visual-studio-feature-you-probably-arent-using/?c=elumenotion-blog-archive/random-whatnot" class="more-link">Continue reading <span class="screen-reader-text">Task Runner Explorer is the Best Visual Studio Feature You Probably Aren’t Using</span> <span class="meta-nav">&#8594;</span></a>]]></description>
  321. <content:encoded><![CDATA[<p><strong>TL;DR – There is a handy feature in VS 2015 called Task Runner Explorer that you can use to run PowerShell or batch commands to do just about anything. You can also bind these to build events.</strong></p>
  322. <p>A <em>task runner </em>is a program that runs tasks. If you&#8217;ve been doing much web development these past couple of years you are probably familiar with this concept and popular task runners like <a href="http://gruntjs.com/">Grunt</a> and <a href="http://gulpjs.com/">Gulp</a>. In fact one or both of these might be essential to your development workflow. And, since many web developers consider these to be essential tools, the Visual Studio team released the <a href="https://marketplace.visualstudio.com/items?itemName=MadsKristensen.TaskRunnerExplorer">Task Runner Explorer extension for Visual Studio 2013</a> and later made <a href="https://blogs.msdn.microsoft.com/webdev/2016/01/06/task-runners-in-visual-studio-2015/">Task Runner Explorer</a> an out of box feature in Visual Studio 2015.</p>
  323. <p>If you aren&#8217;t aware that this feature exists, you aren&#8217;t alone! I took a poll on twitter.</p>
  324. <p><img src="http://www.instantquick.com/wp-content/uploads/2017/01/012617_1337_TaskRunnerE1.png" alt="" /></p>
  325. <p>&lt;sarcasm&gt;I was a bit surprised by this as the feature is prominently available by going to <strong>View | Other Windows | Task Runner Explorer</strong>.&lt;/sarcasm&gt;</p>
  326. <p><img src="http://www.instantquick.com/wp-content/uploads/2017/01/012617_1337_TaskRunnerE2.png" alt="" /></p>
  327. <h2>JavaScript Task Runner? No Thanks!</h2>
  328. <p>If your work isn&#8217;t mostly JavaScript, using a JavaScript based task runner probably sounds pretty unappealing. Happily there is an extension that supports .exe, .cmd, .bat, .ps1 and .psm1 files called <a href="https://marketplace.visualstudio.com/items?itemName=MadsKristensen.CommandTaskRunner">Command Task Runner</a>.</p>
  329. <p>We use this in the <a href="https://github.com/InstantQuick/AzureFunctionsForSharePoint">Azure Functions for SharePoint</a> project to <a href="https://github.com/InstantQuick/AzureFunctionsForSharePoint/blob/master/deploy.ps1">automate deployment at build time</a> by binding the script to the build event.</p>
  330. <p><img src="http://www.instantquick.com/wp-content/uploads/2017/01/012617_1337_TaskRunnerE3.png" alt="" /></p>
  331. <p>The deploy script is complicated, but there are a couple others that are pretty simple and are not bound to any events. We run them manually and I think they illustrate best why this tool is something that belongs in your everyday toolkit.</p>
  332. <p>For example, each Azure Function for SharePoint relies on a config.json file. It would be an error-prone pain to create them by hand or by copying an existing configuration and so <a href="https://github.com/InstantQuick/AzureFunctionsForSharePoint/blob/master/makeConfigJson.ps1">we have a script that creates a new config</a> and puts it on the clipboard:</p>
  333. <pre><code>$scriptdir <span style="color: black;"><span style="color: darkgray;">= $PSScriptRoot
  334. </span></span></code><code><span style="color: darkgray;">[<span style="color: teal;">Reflection.Assembly<span style="color: darkgray;">]::<span style="color: black;">LoadFrom(<span style="color: darkred;">"</span>$scriptdir<span style="color: darkred;">\AzureFunctionsForSharePoint.Core\bin\Debug\AzureFunctionsForSharePoint.Core.dll"<span style="color: black;">)
  335. </span></span></span></span></span></span></code><code>$config <span style="color: darkgray;">=</span> <span style="color: blue;">New-Object</span> <span style="color: black;"><span style="color: blueviolet;">AzureFunctionsForSharePoint.Core.ClientConfiguration
  336.  
  337. </span></span></code><code><span style="color: darkgreen;">#Pretty print output to the PowerShell host window
  338. </span></code><code><span style="color: blue;">ConvertTo-Json</span> <span style="color: navy;">-InputObject $config</span> <span style="color: navy;">-Depth</span> <span style="color: black;"><span style="color: purple;">4
  339.  
  340. </span></span></code><code><span style="color: darkgreen;">#Send to clipboard
  341. </span></code><code><span style="color: blue;">ConvertTo-Json</span> <span style="color: navy;">-InputObject $config</span> <span style="color: navy;">-Depth</span> <span style="color: purple;">4</span> <span style="color: navy;">-Compress</span> <span style="color: darkgray;">|</span> <span style="color: black;"><span style="color: blue;">clip</span></span>
  342. </code></pre>
  343. <p>When a new client config.json is needed, all one must do is run the command from Task Runner Explorer.</p>
  344. <p><img src="http://www.instantquick.com/wp-content/uploads/2017/01/012617_1337_TaskRunnerE4.png" alt="" /></p>
  345. <p>Pretty cool eh?</p>
  346. <p>&#8211;Doug Ware</p>
  347. ]]></content:encoded>
  348. </item>
  349. <item>
  350. <title>Introducing Azure Functions for SharePoint</title>
  351. <link>http://www.instantquick.com/index.php/introducing-azure-functions-for-sharepoint/?c=elumenotion-blog-archive/sharepoint-2013-and-office-365-apps</link>
  352. <comments>http://www.instantquick.com/index.php/introducing-azure-functions-for-sharepoint/?c=elumenotion-blog-archive/sharepoint-2013-and-office-365-apps#comments</comments>
  353. <pubDate>Sat, 14 Jan 2017 21:06:30 +0000</pubDate>
  354. <dc:creator><![CDATA[DouglasWare]]></dc:creator>
  355. <category><![CDATA[Azure Functions]]></category>
  356. <category><![CDATA[SharePoint 2013 and Office 365 Apps]]></category>
  357.  
  358. <guid isPermaLink="false">http://www.instantquick.com/?p=36451</guid>
  359. <description><![CDATA[I&#8217;m excited to announce the first public release of Azure Functions for SharePoint, a powerful but inexpensive to operate open source backbone for SharePoint add-ins. We&#8217;ve been using Azure Functions in production for a while now, and I love it! I&#8217;ll be speaking about Azure Functions next Saturday, January 21, 2017 at Cloud Saturday Atlanta. &#8230; <a href="http://www.instantquick.com/index.php/introducing-azure-functions-for-sharepoint/?c=elumenotion-blog-archive/sharepoint-2013-and-office-365-apps" class="more-link">Continue reading <span class="screen-reader-text">Introducing Azure Functions for SharePoint</span> <span class="meta-nav">&#8594;</span></a>]]></description>
  360. <content:encoded><![CDATA[<p>I&#8217;m excited to announce the first public release of <a href="https://afspdocs.blob.core.windows.net/docs/index.html">Azure Functions for SharePoint</a><span style="color:#333333">, a powerful but inexpensive to operate open source backbone for SharePoint add-ins. We&#8217;ve been using Azure Functions in production for a while now, and I love it!<br />
  361. </span></p>
  362. <p>I&#8217;ll be speaking about Azure Functions next Saturday, January 21, 2017 at <a href="https://cloudsaturdayatlanta.com/">Cloud Saturday Atlanta</a>. You should come!
  363. </p>
  364. <h2>About Azure Functions for SharePoint<br />
  365. </h2>
  366. <p>AzureFunctionsForSharePoint is a multi-tenant, multi-add-in back-end for SharePoint add-ins built on <a href="https://azure.microsoft.com/en-us/services/functions/">Azure Functions</a>. The goal of this project is to provide the minimal set of functions necessary to support the common scenarios shared by most SharePoint provider hosted add-ins cheaply and reliably.
  367. </p>
  368. <p>Features include:
  369. </p>
  370. <ul>
  371. <li>Centralized Identity and ACS token management
  372. </li>
  373. <li>Installation and provisioning of add-in components to SharePoint
  374. </li>
  375. <li>
  376. <div>Remote event dispatching to add-in specific back-end services via message queues including
  377. </div>
  378. <ul>
  379. <li>App installation
  380. </li>
  381. <li>App launch
  382. </li>
  383. <li>SharePoint Remote Events
  384. </li>
  385. </ul>
  386. </li>
  387. </ul>
  388. <h2>Navigating the Documentation<br />
  389. </h2>
  390. <p>These documents consist of <a href="https://afspdocs.blob.core.windows.net/docs/articles/intro.html">articles</a> that explain what the functions do, how to set up the hosting environment, and how to use the functions in your add-ins and <a href="https://afspdocs.blob.core.windows.net/docs/api/index.html">API documentation for .NET developers</a> linked to the source code in <a href="https://github.com/InstantQuick/AzureFunctionsForSharePoint">GitHub</a>.
  391. </p>
  392. <h2>A Note on Terminology<br />
  393. </h2>
  394. <p>These documents use the term <strong>client</strong> to refer to a given SharePoint add-in. A client is identified using its <strong>client ID</strong> which is the GUID that identifies the add-in&#8217;s ACS client ID in the <a href="https://msdn.microsoft.com/en-us/library/office/fp179918.aspx">SharePoint add-in&#8217;s AppManifest.xml</a>.
  395. </p>
  396. <h2>Functions<br />
  397. </h2>
  398. <p>There are three functions in this function app.
  399. </p>
  400. <ol>
  401. <li><a href="https://afspdocs.blob.core.windows.net/docs/articles/AppLaunch.html">AppLaunch</a>
  402. </li>
  403. <li><a href="https://afspdocs.blob.core.windows.net/docs/articles/EventDispatch.html">EventDispatch</a>
  404. </li>
  405. <li><a href="https://afspdocs.blob.core.windows.net/docs/articles/GetAccessToken.html">GetAccessToken</a>
  406. </li>
  407. </ol>
  408. <h2>Setup Guide<br />
  409. </h2>
  410. <p>We&#8217;re working on full automation with an ARM template, etc. The Visual Studio Solution includes a PowerShell script you can use with Task Runner Explorer and <a href="https://marketplace.visualstudio.com/items?itemName=MadsKristensen.CommandTaskRunner">Command Task Runner</a>. Until then, create a function app and copy the contents of this <a href="https://github.com/InstantQuick/AzureFunctionsForSharePoint/raw/master/AzureFunctionsForSharePointWWWRoot.zip">zip file</a> into the function app&#8217;s wwwroot folder.
  411. </p>
  412. <h2>Configuring the Function App<br />
  413. </h2>
  414. <p>Until the automation is fully baked, you can use this video to guide you through the relatively easy setup of the function app.
  415. </p>
  416. <p><a href="https://youtu.be/MsPlqNNkqXM"><img src="http://www.instantquick.com/wp-content/uploads/2017/01/011417_2106_Introducing1.png" alt="" border="0"/></a>
  417. </p>
  418. <h2>Configuring SharePoint Add-ins to use the Function App<br />
  419. </h2>
  420. <p>Azure Functions for SharePoint is multi-tenant in that it can service add-ins installed broadly across SharePoint Online and also because the back-end processes that respond to client specific events in SharePoint or rely on Azure Functions for SharePoint for security token management can be located anywhere with a connection to the Internet.
  421. </p>
  422. <p>See the <a href="https://afspdocs.blob.core.windows.net/docs/articles/ClientConfiguration.html">Client Configuration Guide</a> for more information.
  423. </p>
  424. <h2>Using the Function App to Support Custom Back-ends<br />
  425. </h2>
  426. <p>It is possible to use Azure Functions for SharePoint to deliver pure client-side solutions, i.e. HTML/JS. However, many add-ins must support scenarios that are difficult or impossible to achieve through pure JavaScript. Azure Functions for SharePoint supports custom back-ends in two ways:
  427. </p>
  428. <ol>
  429. <li>Notification of add-in and SharePoint events via Azure Service Bus queues via the <a href="https://afspdocs.blob.core.windows.net/docs/articles/EventDispatch.html">EventDispatch Function</a>
  430. </li>
  431. <li>A REST service that provides security access tokens for registered clients via the <a href="https://afspdocs.blob.core.windows.net/docs/articles/GetAccessToken.html">GetAccessToken Function</a>
  432. </li>
  433. </ol>
  434. <p>In both cases the client back-end receives all the information it needs to connect to SharePoint as either the user or as an app-only identity with full control. The function app does the actual authorization flow and its client configuration is the only place where the client secret is stored.
  435. </p>
  436. <p>Your custom back-ends can live anywhere from the same Function App where you deployed Azure Functions for SharePoint to completely different Azure tenancies or on-premises servers. All that is required is that the back-end can read Azure Service Bus Queues and access the REST services via the Internet. Aside from these requirements, the back-end can run on any platform and be written in any language.
  437. </p>
  438. <p>That said, if you are using .NET, this project included an assembly named <a href="https://afspdocs.blob.core.windows.net/docs/api/AzureFunctionsForSharePoint.Common.html">AzureFunctionsForSharePoint.Common</a> that you can use to make things even easier!
  439. </p>
  440. <h2>API Docs<br />
  441. </h2>
  442. <p>Complete documentation of the Azure Functions for SharePoint API see the <a href="https://afspdocs.blob.core.windows.net/docs/api/index.html">API Guide</a>.
  443. </p>
  444. <h2>Want to Contribute to this Project?<br />
  445. </h2>
  446. <p>We&#8217;re still working on that too, but please reach out to me if you want to help!
  447. </p>
  448. <p>&#8211;Doug</p>
  449. ]]></content:encoded>
  450. <wfw:commentRss>http://www.instantquick.com/index.php/introducing-azure-functions-for-sharepoint/?c=elumenotion-blog-archive/sharepoint-2013-and-office-365-apps/feed</wfw:commentRss>
  451. <slash:comments>11</slash:comments>
  452. </item>
  453. <item>
  454. <title>Receiving BrokeredMessages Instead of Strings with Service Bus Queue Triggers</title>
  455. <link>http://www.instantquick.com/index.php/receiving-brokeredmessages-instead-of-strings-with-service-bus-queue-triggers/?c=azure-functions</link>
  456. <pubDate>Tue, 13 Dec 2016 21:23:06 +0000</pubDate>
  457. <dc:creator><![CDATA[DouglasWare]]></dc:creator>
  458. <category><![CDATA[Azure Functions]]></category>
  459.  
  460. <guid isPermaLink="false">http://www.instantquick.com/?p=36271</guid>
  461. <description><![CDATA[When you create a new Azure Function with a Service Bus queue trigger, the initial run.csx takes a string as input and looks like this: The benefit of this is that the function infrastructure hides all of the complexity of the service bus from you making everything nice and simple. However, I like to get &#8230; <a href="http://www.instantquick.com/index.php/receiving-brokeredmessages-instead-of-strings-with-service-bus-queue-triggers/?c=azure-functions" class="more-link">Continue reading <span class="screen-reader-text">Receiving BrokeredMessages Instead of Strings with Service Bus Queue Triggers</span> <span class="meta-nav">&#8594;</span></a>]]></description>
  462. <content:encoded><![CDATA[<p>When you create a new Azure Function with a Service Bus queue trigger, the initial run.csx takes a string as input and looks like this:
  463. </p>
  464. <p><img src="http://www.instantquick.com/wp-content/uploads/2016/12/121316_2139_ReceivingBr1.png" alt=""/>
  465. </p>
  466. <p>The benefit of this is that the function infrastructure hides all of the complexity of the service bus from you making everything nice and simple. However, I like to get the real message object instead of its payload because the messages properties support a number of useful scenarios. Among these properties is the message&#8217;s ContentType which is useful when the bus delivers more than one type of message.
  467. </p>
  468. <p>It isn&#8217;t obvious from the documentation how to get the brokered message instead of a simple string, and there is a wrinkle involved if you like to do as I do and <a href="http://www.instantquick.com/index.php/an-azure-functions-design-pattern-for-your-consideration">deliver the bulk of your functionality in complied assemblies</a>.
  469. </p>
  470. <h2>Scenario #1 – C# Script Only<br />
  471. </h2>
  472. <p>As your function is being triggered by a service bus message, it makes sense that <a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-csharp">Microsoft.Azure.ServiceBus.dll is loaded by default</a>. You don&#8217;t need to do anything other than reference it and change the method signature and you can leave your function.json file alone. In this case I changed the binding in function.json so that the name is <strong>receivedMessage</strong> instead of <strong>myQueueItem</strong>, but that&#8217;s only because I felt like it! <span style="font-family:Wingdings">J</span>
  473. </p>
  474. <p>You can write your function as follows:
  475. </p>
  476. <p>
  477. <img src="http://www.instantquick.com/wp-content/uploads/2016/12/121316_2139_ReceivingBr2.png" alt=""/>
  478. </p>
  479. <p>Notice that the assembly import line does not include an extension. If you include one, you will get a compile error!
  480. </p>
  481. <h2>Scenario #2 – Compiled Assemblies<br />
  482. </h2>
  483. <p>If you are using compiled assemblies, the story is a little more nuanced and also potentially more dangerous because the potential for a version mismatch exists.
  484. </p>
  485. <p>Assemblies deployed to the function go into the <strong>bin</strong> folder below the <strong>run.csx</strong> file. Generally, what this entails is copying all of the build output from your project to <strong>bin</strong>. When you do this, it becomes possible to reference the assembly using the <strong>dll</strong> file extension as follows:
  486. </p>
  487. <p><img src="http://www.instantquick.com/wp-content/uploads/2016/12/121316_2139_ReceivingBr3.png" alt=""/>
  488. </p>
  489. <p>This compiles because the assembly is in <strong>bin</strong>. You can still leave the file extension out. But, should you?
  490. </p>
  491. <p>To test this out I made a little test assembly that references a very old version of Microsoft.ServiceBus.dll; version 1.8.0.0. It returns a string that contains the assembly name along with the message&#8217;s content type.
  492. </p>
  493. <p><img src="http://www.instantquick.com/wp-content/uploads/2016/12/121316_2139_ReceivingBr4.png" alt=""/>
  494. </p>
  495. <p>The calling function logs the assembly name and then the output of the compiled function.
  496. </p>
  497. <p><img src="http://www.instantquick.com/wp-content/uploads/2016/12/121316_2139_ReceivingBr5.png" alt=""/>
  498. </p>
  499. <p>Somewhat surprisingly, this works and the output of the function&#8217;s compilation and execution looks like this:
  500. </p>
  501. <p><img src="http://www.instantquick.com/wp-content/uploads/2016/12/121316_2139_ReceivingBr6.png" alt=""/>
  502. </p>
  503. <p>As expected, everything is using the version of the assembly that was loaded by Azure Functions (3.0.0.0) and not the version referenced by the compiled project (1.8.0.0). I actually expected to get a runtime error or at the very least a warning!
  504. </p>
  505. <p>If I remove the file extension, it still works, but at least this time I get a warning!
  506. </p>
  507. <p><img src="http://www.instantquick.com/wp-content/uploads/2016/12/121316_2139_ReceivingBr7.png" alt=""/>
  508. </p>
  509. <h2>The Moral of the Story<br />
  510. </h2>
  511. <p>That this works at all has a lot to do with the fact that what I am using of the BrokeredMessage class is compatible between versions 1.8 and 3.0. Had I written the test differently, it would not have worked.
  512. </p>
  513. <p>There is clearly some danger here that requires a function developer to know when they are using assemblies that will already be loaded and have the potential to not match the build. The function compilation does not recompile the deployed assemblies and has no way to know about this potential runtime mismatch, but it can know that what the C# Script file is using conflicts with what is in the bin folder as long as you leave the file extension off of the reference.
  514. </p>
  515. <p>&#8211;Doug Ware</p>
  516. ]]></content:encoded>
  517. </item>
  518. <item>
  519. <title>An Azure Functions Design Pattern for Your Consideration</title>
  520. <link>http://www.instantquick.com/index.php/an-azure-functions-design-pattern-for-your-consideration/?c=azure-functions</link>
  521. <comments>http://www.instantquick.com/index.php/an-azure-functions-design-pattern-for-your-consideration/?c=azure-functions#comments</comments>
  522. <pubDate>Fri, 09 Dec 2016 21:11:21 +0000</pubDate>
  523. <dc:creator><![CDATA[DouglasWare]]></dc:creator>
  524. <category><![CDATA[Azure Functions]]></category>
  525.  
  526. <guid isPermaLink="false">http://www.instantquick.com/?p=36141</guid>
  527. <description><![CDATA[Without question, Azure Functions is my favorite new offering from Microsoft in 2016. One reason I like it so much is that it is extremely flexible, scalable and inexpensive, making it useful in a wide range of scenarios. One reason for this is that you can create functions using your choice of nine different languages &#8230; <a href="http://www.instantquick.com/index.php/an-azure-functions-design-pattern-for-your-consideration/?c=azure-functions" class="more-link">Continue reading <span class="screen-reader-text">An Azure Functions Design Pattern for Your Consideration</span> <span class="meta-nav">&#8594;</span></a>]]></description>
  528. <content:encoded><![CDATA[<p>Without question, <a href="https://azure.microsoft.com/en-us/services/functions/">Azure Functions</a> is my favorite new offering from Microsoft in 2016. One reason I like it so much is that it is extremely flexible, scalable and inexpensive, making it useful in a wide range of scenarios. One reason for this is that you can create functions using your choice of <a href="https://github.com/Microsoft/azure-docs/blob/master/articles/azure-functions/functions-compare-logic-apps-ms-flow-webjobs.md">nine different languages</a> (many of these are experimental as of this writing). Naturally, each of these languages has its own nuances.</p>
  529. <p>Here at InstantQuick we have several functions in production based upon C#. Naturally, the <a href="https://github.com/Microsoft/azure-docs/blob/master/articles/azure-functions/functions-reference-csharp.md">documentation for C#</a> is comparatively good, there is some <a href="https://github.com/Microsoft/azure-docs/blob/master/articles/azure-functions/functions-best-practices.md">best practices guidance</a>, and there are <a href="https://blogs.msdn.microsoft.com/webdev/2016/12/01/visual-studio-tools-for-azure-functions/">tools for Visual Studio</a> in preview. However, in each of these cases, the primary focus is C# Script, not C# compiled to assembly dll files. Fortunately, the documentation does describe how to load assemblies in a variety of ways.</p>
  530. <h2>Minimizing the Use of CSX</h2>
  531. <p>The file extension of a C# Script file is <strong>CSX</strong>. By default a C# based function has a single CSX file named <strong>run.csx</strong>. You can, however, reference other C# Script files and <a href="https://peteskelly.com/loading-shared-csx-files-in-azure-functions/">share C# Script files between functions</a>. So, you can theoretically build a complex solution using nothing but C# Script and for very small functions written to augment something like a <a href="https://azure.microsoft.com/en-us/services/logic-apps/">Logic App</a> C# Script makes perfect sense. However, in our case, and I suspect in many others, we want to deliver the bulk of our functionality as built assemblies for a few important reasons.</p>
  532. <ol>
  533. <li>We are moving existing functionality previously developed in a traditional manner to functions</li>
  534. <li>Sometimes, functions aren&#8217;t an appropriate delivery vehicle and we want to host the functionality in traditional cloud services or on premises</li>
  535. <li>The tooling for <strong>CS</strong> files is, at the moment, much better than the tooling for <strong>CSX</strong> files</li>
  536. </ol>
  537. <h2>Pattern for run.csx</h2>
  538. <p>Most of our <strong>run.csx</strong> files look like this:</p>
  539. <pre><code><span style="color: gray;">#r "AppLaunch.dll"
  540. </span></code><code><span style="color: gray;">#r "FunctionsCore.dll"
  541. </span></code><code><span style="color: blue;">using<span style="color: black;"> System.Net;
  542. </span></span></code><code><span style="color: blue;">using<span style="color: black;"> System.Configuration;
  543. </span></span></code><code><span style="color: blue;">using<span style="color: black;"> System.Net.Http.Formatting;
  544. </span></span></code><code><span style="color: blue;">using<span style="color: black;"> AppLaunch;
  545.  
  546. </span></span></code><code><span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: black;"><span style="color: blue;">async<span style="color: black;"> Task&lt;HttpResponseMessage&gt; Run(HttpRequestMessage req, TraceWriter log)
  547. </span></span></span></code><code><span style="color: black;">{
  548. </span></code><code><span style="color: black;">   Log(log, </span>$"C# HTTP trigger function processed a request! RequestUri=<span style="color: black;">{req.RequestUri}</span>"<span style="color: black;">);
  549. </span></code>   var<span style="color: black;"> func = <span style="color: blue;">new<span style="color: black;"> AppLaunchHandler(req);
  550. </span></span></span><code><span style="color: black;">   func.FunctionNotify += (sender, args) =&gt; Log(log, args.Message);
  551. </span></code>   var<span style="color: black;"> appLauncherFunctionArgs = <span style="color: blue;">new<span style="color: black;"> AppLauncherFunctionArgs()
  552. </span></span></span><code><span style="color: black;">   {
  553. </span></code><code><span style="color: black;">      StorageAccount = ConfigurationManager.AppSettings[</span>"ConfigurationStorageAccount"<span style="color: black;">],
  554. </span></code><code><span style="color: black;">      StorageAccountKey = ConfigurationManager.AppSettings[</span>"ConfigurationStorageAccountKey"<span style="color: black;">]
  555. </span></code><code><span style="color: black;">   };
  556. </span></code>   return<span style="color: black;"> func.Execute(appLauncherFunctionArgs);
  557. </span><code><span style="color: black;">}
  558.  
  559. </span></code><code><span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: black;"><span style="color: blue;">void<span style="color: black;"> Log(TraceWriter log, <span style="color: blue;">string<span style="color: black;"> message)
  560. </span></span></span></span></span></code><code><span style="color: black;">{
  561. </span></code><code><span style="color: black;">   log.Info(message);
  562. </span></code><code><span style="color: black;">}</span>
  563. </code></pre>
  564. <p>The code does only five things</p>
  565. <ol style="margin-left: 40pt;">
  566. <li>Load the assemblies that do the actual work</li>
  567. <li>Receive the input from the function&#8217;s trigger via its bindings – this includes a TraceWriter for logging</li>
  568. <li>Gets the configuration from the Function App&#8217;s configuration settings</li>
  569. <li>Invokes the code that does the real work, passing the function input and the configuration values and returning its output</li>
  570. <li>Receive logging notifications as events and log them via the TraceWriter</li>
  571. </ol>
  572. <h2>Avoiding Dependencies on Azure Functions</h2>
  573. <p>The very first function I wrote included a dependency on the <a href="https://docs.microsoft.com/en-us/azure/app-service-web/websites-dotnet-webjobs-sdk">Web Jobs SDK</a> for logging. Since one of our primary needs is to be able to host the functionality outside of Azure Functions, that wasn&#8217;t something I could keep doing. The workers should be delivered as plain old class libraries with minimal dependency on the runtime environment. To that end I wrote a simple little base class that uses an event to raise notifications. This allows the hosting environment to deal with that information in whatever way is needed.</p>
  574. <p>The base class and event look delegate like this:</p>
  575. <pre><code><span style="color: blue;">namespace</span> FunctionsCore
  576. </code><code>{
  577. </code>   public <code><span style="color: blue;">delegate</span> <span style="color: blue;">void</span> <span style="color: #2b91af;">FunctionNotificationEventHandler</span>(</code>object sender, <span style="color: #2b91af;">FunctionNotificationEventArgs</span> eventArgs);
  578.  
  579.   public <code><span style="color: blue;">class</span> <span style="color: #2b91af;">FunctionNotificationEventArgs</span> : <span style="color: #2b91af;">EventArgs</span>
  580. </code><code>   {
  581. </code>      public <code><span style="color: blue;">string</span> Message { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
  582. </code><code>   }
  583. </code>  
  584.   public <code><span style="color: blue;">class</span> <span style="color: #2b91af;">FunctionBase</span>
  585. </code><code>   {
  586. </code>      public <code><span style="color: blue;">event</span> <span style="color: #2b91af;">FunctionNotificationEventHandler</span> FunctionNotify;
  587.  
  588. </code>      public <code><span style="color: blue;">void</span> Log(<span style="color: blue;">string</span> message)
  589. </code><code>      {
  590. </code><code>         FunctionNotify?.Invoke(<span style="color: blue;">this</span>, <span style="color: blue;">new</span> <span style="color: #2b91af;">FunctionNotificationEventArgs</span> { Message = message });
  591. </code><code>      }
  592. </code><code>   }
  593. </code><code>}
  594. </code></pre>
  595. <p>A subclass can then simply notify the caller of anything interesting via <strong>Log</strong> function as follows.</p>
  596. <pre><code><span style="color: black;">Log(</span>$"Error creating view <span style="color: black;">{ex}</span>"<span style="color: black;">);
  597. </span></code></pre>
  598. <h2>How Much Logging is Too Much Logging?</h2>
  599. <p>The SDK&#8217;s best practices guidance notes that excessive amounts of logging can slow your function down. I suppose there may be times when that is a concern, but most of our functions are not interactive and still execute in the range of sub-second to a few seconds. The cost savings we get from using a consumption plan instead of dedicated cores is so dramatic that whatever extra CPU time the logging causes is a non-issue. So, my opinion is that minimizing the logging is a premature optimization and not great advice.</p>
  600. <h2>Deployment</h2>
  601. <p>The final piece of the puzzle is how the deployment works. The current preview <a href="https://blogs.msdn.microsoft.com/webdev/2016/12/01/visual-studio-tools-for-azure-functions/">tools for Visual Studio</a> are not especially helpful when it comes to working with regular old C#, and that is being generous. Instead, we use plain old class library projects, <a href="https://webtooling.visualstudio.com/task-runners/">Visual Studio&#8217;s Task Runners</a> with the <a href="https://marketplace.visualstudio.com/items?itemName=MadsKristensen.CommandTaskRunner">Command Task Runner</a>, and PowerShell scripts. The full script that can also create the Function App via Azure Resource Manager is a work in progress, but when it&#8217;s done, I&#8217;ll write another blog post and publish the project template to GitHub.</p>
  602. <p>&#8211;Doug Ware</p>
  603. ]]></content:encoded>
  604. <wfw:commentRss>http://www.instantquick.com/index.php/an-azure-functions-design-pattern-for-your-consideration/?c=azure-functions/feed</wfw:commentRss>
  605. <slash:comments>2</slash:comments>
  606. </item>
  607. </channel>
  608. </rss>
  609.  

If you would like to create a banner that links to this page (i.e. this validation result), do the following:

  1. Download the "valid RSS" banner.

  2. Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)

  3. Add this HTML to your page (change the image src attribute if necessary):

If you would like to create a text link instead, here is the URL you can use:

http://www.feedvalidator.org/check.cgi?url=http%3A//feeds.feedburner.com/ElumenotionBlogPosts

Copyright © 2002-9 Sam Ruby, Mark Pilgrim, Joseph Walton, and Phil Ringnalda