mirror of
https://github.com/LukeHagar/jims-blog.git
synced 2025-12-07 12:37:47 +00:00
16 lines
20 KiB
HTML
16 lines
20 KiB
HTML
<!doctype html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta http-equiv=x-ua-compatible content="ie=edge"><link rel=icon href=/fav.png type=image/png><link rel=preconnect href=https://fonts.googleapis.com><link rel=preconnect href=https://fonts.gstatic.com crossorigin><link rel=preload as=style href="https://fonts.googleapis.com/css2?family=Alata&family=Lora&family=Muli:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&family=Roboto&family=Muli:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"><link rel=stylesheet href="https://fonts.googleapis.com/css2?family=Alata&family=Lora&family=Muli:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&family=Roboto&family=Muli:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" media=print onload='this.media="all"'><noscript><link href="https://fonts.googleapis.com/css2?family=Alata&family=Lora&family=Muli:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&family=Roboto&family=Muli:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel=stylesheet></noscript><link rel=stylesheet href=/css/font.css media=all><meta property="og:title" content="Debugging multiple Azure Functions apps at the same time"><meta property="og:description" content="Dentists don’t want you to know these 5 tips that show how easy it is to run multiple Azure Functions apps locally and debug them all at the same time!
|
|
Number 3 will shock you!
|
|
Enough ClickBait nonsense, on to the post.
|
|
I recently built a demo app that has two Azure Functions projects in it - one using the new V2 Functions runtime and written in C#, and one using the old V1 runtime so that it can access some ."><meta property="og:type" content="article"><meta property="og:url" content="https://jimbobbennett.dev/blogs/debugging-multiple-azure-functions-apps-at-the-same-time/"><meta property="og:image" content="https://jimbobbennett.dev/blogs/debugging-multiple-azure-functions-apps-at-the-same-time/banner.png"><meta property="article:section" content="blogs"><meta property="article:published_time" content="2018-11-13T17:52:15+00:00"><meta property="article:modified_time" content="2018-11-13T17:52:15+00:00"><meta property="og:site_name" content="JimBobBennett"><meta name=twitter:card content="summary_large_image"><meta name=twitter:image content="https://jimbobbennett.dev/blogs/debugging-multiple-azure-functions-apps-at-the-same-time/banner.png"><meta name=twitter:title content="Debugging multiple Azure Functions apps at the same time"><meta name=twitter:description content="Dentists don’t want you to know these 5 tips that show how easy it is to run multiple Azure Functions apps locally and debug them all at the same time!
|
|
Number 3 will shock you!
|
|
Enough ClickBait nonsense, on to the post.
|
|
I recently built a demo app that has two Azure Functions projects in it - one using the new V2 Functions runtime and written in C#, and one using the old V1 runtime so that it can access some ."><meta name=twitter:site content="@jimbobbennett"><meta name=twitter:creator content="@jimbobbennett"><link rel=stylesheet href=https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css integrity=sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3 crossorigin=anonymous><link rel=stylesheet href=/css/header.css media=all><link rel=stylesheet href=/css/footer.css media=all><link rel=stylesheet href=/css/theme.css media=all><link rel="shortcut icon" type=image/png href=/fav.png><link rel="shortcut icon" sizes=192x192 href=/fav.png><link rel=apple-touch-icon href=/fav.png><link rel=alternate type=application/rss+xml href=https://jimbobbennett.dev/index.xml title=JimBobBennett><script type=text/javascript>(function(e,t,n,s,o,i,a){e[n]=e[n]||function(){(e[n].q=e[n].q||[]).push(arguments)},i=t.createElement(s),i.async=1,i.src="https://www.clarity.ms/tag/"+o,a=t.getElementsByTagName(s)[0],a.parentNode.insertBefore(i,a)})(window,document,"clarity","script","dctc2ydykv")</script><style>:root{--text-color:#343a40;--text-secondary-color:#6c757d;--background-color:#000;--secondary-background-color:#64ffda1a;--primary-color:#007bff;--secondary-color:#f8f9fa;--text-color-dark:#e4e6eb;--text-secondary-color-dark:#b0b3b8;--background-color-dark:#000000;--secondary-background-color-dark:#212529;--primary-color-dark:#ffffff;--secondary-color-dark:#212529}body{background-color:#000;font-size:1rem;font-weight:400;line-height:1.5;text-align:left}</style><meta name=description content><link rel=stylesheet href=/css/index.css><link rel=stylesheet href=/css/single.css><link rel=stylesheet href=/css/projects.css media=all><script defer src=/fontawesome-5/all-5.15.4.js></script><title>Debugging multiple Azure Functions apps at the same time | JimBobBennett</title></head><body class=light onload=loading()><header><nav class="pt-3 navbar navbar-expand-lg"><div class="container-fluid mx-xs-2 mx-sm-5 mx-md-5 mx-lg-5"><a class="navbar-brand primary-font text-wrap" href=/><img src=/fav.png width=30 height=30 class="d-inline-block align-top">
|
|
JimBobBennett</a>
|
|
<button class=navbar-toggler type=button data-bs-toggle=collapse data-bs-target=#navbarContent aria-controls=navbarContent aria-expanded=false aria-label="Toggle navigation"><svg aria-hidden="true" height="24" viewBox="0 0 16 16" width="24" data-view-component="true"><path fill-rule="evenodd" d="M1 2.75A.75.75.0 011.75 2h12.5a.75.75.0 110 1.5H1.75A.75.75.0 011 2.75zm0 5A.75.75.0 011.75 7h12.5a.75.75.0 110 1.5H1.75A.75.75.0 011 7.75zM1.75 12a.75.75.0 100 1.5h12.5a.75.75.0 100-1.5H1.75z"/></svg></button><div class="collapse navbar-collapse text-wrap primary-font" id=navbarContent><ul class="navbar-nav ms-auto text-center"><li class="nav-item navbar-text"><a class=nav-link href=/ aria-label=home>Home</a></li><li class="nav-item navbar-text"><a class=nav-link href=/#about aria-label=about>About</a></li><li class="nav-item navbar-text"><a class=nav-link href=/#projects aria-label=projects>Recent Highlights</a></li><li class="nav-item navbar-text"><a class=nav-link href=/blogs title="Blog posts">Blog</a></li><li class="nav-item navbar-text"><a class=nav-link href=/videos title=Videos>Videos</a></li><li class="nav-item navbar-text"><a class=nav-link href=/livestreams title=Livestreams>Livestreams</a></li><li class="nav-item navbar-text"><a class=nav-link href=/conferences title=Conferences>Conferences</a></li><li class="nav-item navbar-text"><a class=nav-link href=/resume title=Resume>Resume</a></li></ul></div></div></nav></header><div id=content><section id=projects><div class="container pt-5" id=list-page><div class="row justify-content-center px-3 px-md-5"><h1 class="text-left pb-2 content">Debugging multiple Azure Functions apps at the same time</h1><div class="text-left content">Jim Bennett
|
|
<small>|</small>
|
|
Nov 13, 2018</div></div></div></section><section id=single><div class=container><div class="row justify-content-center"><div class="col-sm-12 col-md-12 col-lg-9"><div class=pr-lg-4><article class="page-content p-2"><p><strong>Dentists don’t want you to know these 5 tips that show how easy it is to run multiple Azure Functions apps locally and debug them all at the same time!</strong></p><p><strong>Number 3 will shock you!</strong></p><div class=image-div style=max-width:250px><p><img src=andre-guerra-676198-unsplash.jpg alt="Stock photo of a surprised child - probably surprised at the pointless clickbait title at the top of this post"></p></div><p>Enough ClickBait nonsense, on to the post.</p><p>I recently built a <a href=https://github.com/jimbobbennett/AzurePhotoSharer>demo app</a> that has two Azure Functions projects in it - one using the new V2 Functions runtime and written in C#, and one using the old V1 runtime so that it can access some .NET framework bits and written in F#.</p><p>One of the really cool features that Azure Functions offers is the ability to <a href="https://docs.microsoft.com/azure/azure-functions/functions-develop-local/?WT.mc_id=debugfunctionslocally-blog-jabenn">run your functions locally</a> with a full debugging experience, and this is supported in Visual Studio 2017 as well as VSCode.</p><blockquote><p>This post focuses on how to do this in VS2017. For VSCode, follow <a href="https://code.visualstudio.com/tutorials/functions-extension/run-app/?WT.mc_id=debugfunctionslocally-blog-jabenn">these instructions</a>.</p></blockquote><p>This post looks at:</p><ul><li>Debugging <a href=#OneApp>one function app</a></li><li>How to run <a href=#ManyApps>multiple function apps</a> at the same time</li><li>How to <a href=#DebugManyApps>debug multiple functions apps</a> at the same time using Visual Studio 2017</li></ul><a id=OneApp><h4 id=debugging-one-function-app>Debugging one Function app</h4></a><p>This is easy to try out yourself, just create a new Azure Functions app in Visual Studio, add a breakpoint in the HTTP trigger then start debugging. The Azure Function app will launch in a local functions host, and your trigger will be available locally on <code>http://localhost:7071/api/Function1</code> - so listening on port <code>7071</code>. You can launch your favorite browser, navigate to this URL and your breakpoint will be hit, giving a full debugging experience with watch, edit and continue and all the normal bells and whistles.</p><p>Create one of these:</p><div class=image-div style=max-width:600px><p><img src=2018-11-13_13-53-20.png alt="Creating a new Azure Functions project from the Visual C#->Cloud section of the File->New dialog"></p></div><p>Use these settings (V2, HTTP Trigger, Anonymous):</p><div class=image-div style=max-width:600px><p><img src=2018-11-13_13-54-12.png alt="Configuring the Azure Function to use V2, an HTTP trigger with anonymous access rights"></p></div><p>Stick a break point in the function:</p><div class=image-div style=max-width:600px><p><img src=2018-11-13_13-56-31.png alt="Adding a breakpoint to line 22"></p></div><p>Start debugging the function the same way as any normal app (you may need to grant firewall access). This will launch a console window with the functions host running - you’ll see some cool ASCII art then the functions output including the HTTP URLs for all HTTP triggers:</p><div class=image-div style=max-width:600px><p><img src=2018-11-13_14-00-39.png alt="The functions app running in a console window"></p></div><p>Now launch your favorite browser and navigate to the Function1 URL. The function will run and your breakpoint will be hit. This is a full debug session with edit and continue:</p><div class=image-div style=max-width:600px><p><img src=2018-11-13_14-02-14.png alt="The breakpoint being hit"></p></div><p>Click <strong>Continue</strong> and see the output of the function in your browser:</p><div class=image-div style=max-width:600px><p><img src=2018-11-13_14-12-18.png alt="The function output in your browser"></p></div><blockquote><p>There is also a storage emulator that you can run locally so you can read/write to blobs, tables and queues and even use triggers. Read more <a href="https://docs.microsoft.com/azure/storage/common/storage-use-emulator/?WT.mc_id=debugfunctionslocally-blog-jabenn">here</a>.</p></blockquote><a id=ManyApps><h4 id=running-multiple-function-apps-at-the-same-time>Running multiple Function apps at the same time</h4></a><p>Running one function app locally is cool, running multiple is even cooler!</p><div class=image-div style=max-width:600px><p><img src=2018-11-13_14-12-18-1.png alt="Stock photo of a cool looking rubber duck - cos why not!"></p></div><p>Add a new function app to your project, then run it without debugging using <em>Debug->Start without debugging</em>. This will spin up the local Azure Functions host and start listening on port <code>7071</code>.</p><p>Now the beady-eyed amongst you will notice this is the same port as the first functions app. By default the local functions host listens for HTTP requests on port <code>7071</code>, so if you now launch the first functions app it will fail - with a really weird error:</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sh data-lang=sh><span style=display:flex><span>Cannot access a disposed object.
|
|
</span></span><span style=display:flex><span>Object name: <span style=color:#e6db74>'IServiceProvider'</span>.
|
|
</span></span></code></pre></div><div class=image-div style=max-width:400px><p><img src=2018-11-13_15-17-57.png alt="The error shown when multiple local functions hosts run on the same port."></p></div><p>The fix for this is to tell the functions host to run on a different port, and this can be done by adding arguments to the command line that is run when the function app is debugged. Kill all the functions hosts, and open the properties for the second function app. Head to the <strong>Debug</strong> tab, and set the <em>Application arguments</em> to be:</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sh data-lang=sh><span style=display:flex><span>host start --pause-on-error --port <span style=color:#ae81ff>5860</span>
|
|
</span></span></code></pre></div><p>This will start the functions host listening on <code>port 5860</code>. You can use any port you wish for this of course.</p><blockquote><p>These settings are not saved in the project itself, just in your user settings so this won’t be in source control.</p></blockquote><p>Now if you run the second function app it will be listening on a different port:</p><div class=image-div style=max-width:600px><p><img src=2018-11-13_15-25-31.png alt="The Azure Functions local host running on port 5860"></p></div><a id=DebugManyApps><h4 id=debugging-multiple-function-apps-in-vs2017>Debugging multiple function apps in VS2017</h4></a><p>Running multiple is good, but debugging them is even gooderer!</p><div class=image-div style=max-width:600px><p><img src=rawpixel-974535-unsplash.jpg alt="Bad stock photo of people high-fiving"></p></div><p>Although Visual Studio 2017 can’t launch multiple apps at the same time, you can launch one then attach to the others. To do this:</p><ul><li>Put break points in the HTTP triggers for both function apps</li><li>Start the first function app without debugging</li><li>Start the second function app through the debugger</li><li>Attach the debugger to the first function app:<ul><li>Select <em>Debug->Attach to process…</em></li><li>Search for <em>func</em></li><li>One <code>func.exe</code> process will be greyed out - this is the one that is currently running through the debugger. Select the other one and click <strong>Attach</strong>.</li></ul></li></ul><div class=image-div style=max-width:600px><p><img src=2018-11-13_15-39-25.png alt="Finding the func process in the attach dialog"></p></div><p>You should now be able to open <code>http://localhost:7071/api/Function1</code> in your browser and hit the breakpoint in your first function app, and open <code>http://localhost:5860/api/Function1</code> to hit the breakpoint in the second function app.</p><blockquote><p>You don’t get edit and continue in the function app you attached to, only in the one run through the original debugger. If you want edit and continue make sure the function app you want to use this for is run through the debugger, and attach to the others.</p></blockquote><hr><p>Want to learn more about Azure Functions? Well we have a learning path for that as part of <a href="https://docs.microsoft.com/learn/?WT.mc_id=debugfunctionslocally-blog-jabenn">Microsoft Learn</a>. Check it out <a href="https://docs.microsoft.com/learn/paths/create-serverless-applications/?WT.mc_id=debugfunctionslocally-blog-jabenn">here</a>.</p><div class=image-div style=max-width:150px><a href="https://docs.microsoft.com/learn/paths/create-serverless-applications/?WT.mc_id=debugfunctionslocally-blog-jabenn"><p><img src=create-serverless-applications.svg alt="Create serverless applications learning path icon"></p></a></div></article></div></div><div class="col-sm-12 col-md-12 col-lg-3"><div class=sticky-sidebar><aside class=toc><h5>Table Of Contents</h5><div class=toc-content><nav id=TableOfContents><ul><li><ul><li></li></ul></li></ul></nav></div></aside><aside class=tags><h5>Tags</h5><ul class="tags-ul list-unstyled list-inline"><li class=list-inline-item><a href=https://jimbobbennett.dev/tags/technology target=_blank>Technology</a></li><li class=list-inline-item><a href=https://jimbobbennett.dev/tags/azure target=_blank>azure</a></li><li class=list-inline-item><a href=https://jimbobbennett.dev/tags/functions target=_blank>functions</a></li><li class=list-inline-item><a href=https://jimbobbennett.dev/tags/visual-studio target=_blank>Visual Studio</a></li><li class=list-inline-item><a href=https://jimbobbennett.dev/tags/debugging target=_blank>debugging</a></li></ul></aside></div></div></div><div class=row><div class="col-sm-12 col-md-12 col-lg-9 p-4"><div id=disqus_thread></div><script>var disqus_config=function(){this.page.url="https://jimbobbennett.dev/blogs/debugging-multiple-azure-functions-apps-at-the-same-time/",this.page.identifier="31873351bead0afe510633729fd5977d"};(function(){if(window.location.hostname=="localhost")return;var e=document,t=e.createElement("script");t.src="https://jimbobbennett.disqus.com/embed.js",t.setAttribute("data-timestamp",+new Date),(e.head||e.body).appendChild(t)})()</script><noscript>Please enable JavaScript to view the <a href=https://disqus.com/?ref_noscript>comments powered by Disqus.</a></noscript></div></div></div><button class="p-2 px-3" onclick=topFunction() id=topScroll>
|
|
<i class="fas fa-angle-up"></i></button></section><script>var topScroll=document.getElementById("topScroll");window.onscroll=function(){scrollFunction()};function scrollFunction(){document.body.scrollTop>20||document.documentElement.scrollTop>20?topScroll.style.display="block":topScroll.style.display="none"}function topFunction(){document.body.scrollTop=0,document.documentElement.scrollTop=0}</script></div><footer><div class="container py-4"><div class="row justify-content-center"><div class="col-md-4 text-center">© 2023 All Rights Reserved</div></div></div></div></footer><script src=https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js integrity=sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13 crossorigin=anonymous></script>
|
|
<script>document.body.className.includes("light")&&(document.body.classList.add("dark"),localStorage.setItem("pref-theme","dark"))</script><script>let loadingIcons;function loading(){myVar=setTimeout(showPage,100)}function showPage(){try{document.getElementById("loading-icons").style.display="block"}catch{}}</script><script>function createCopyButton(e,t){const n=document.createElement("button");n.className="copy-code-button",n.type="button",n.innerText="Copy",n.addEventListener("click",()=>copyCodeToClipboard(n,e,t)),addCopyButtonToDom(n,e)}async function copyCodeToClipboard(e,t,n){const s=t.querySelector("pre > code").innerText;try{n.writeText(s)}finally{codeWasCopied(e)}}function codeWasCopied(e){e.blur(),e.innerText="Copied!",setTimeout(function(){e.innerText="Copy"},2e3)}function addCopyButtonToDom(e,t){t.insertBefore(e,t.firstChild);const n=document.createElement("div");n.className="highlight-wrapper",t.parentNode.insertBefore(n,t),n.appendChild(t)}if(navigator&&navigator.clipboard)document.querySelectorAll(".highlight").forEach(e=>createCopyButton(e,navigator.clipboard));else{var script=document.createElement("script");script.src="https://cdnjs.cloudflare.com/ajax/libs/clipboard-polyfill/2.7.0/clipboard-polyfill.promise.js",script.integrity="sha256-waClS2re9NUbXRsryKoof+F9qc1gjjIhc2eT7ZbIv94=",script.crossOrigin="anonymous",script.onload=function(){addCopyButtons(clipboard)},document.querySelectorAll(".highlight").forEach(e=>createCopyButton(e,script)),document.body.appendChild(script)}</script></body></html> |