Skip to content

Commit 4158b05

Browse files
committed
review-1
1 parent f3647f5 commit 4158b05

8 files changed

+108
-115
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
### YamlMime:ModuleUnit
2-
uid: learn.advocates.azure-functions-and-signalr.7-exercise-host-a-static-website-using-a-storage-account
3-
metadata:
4-
title: Exercise - Use a storage account to host a static website
5-
description: Customize your storage account, publish your function app and view your application hosted in the cloud.
6-
ms.date: 01/22/2025
7-
author: craigshoemaker
8-
ms.author: cshoe
9-
ms.topic: unit
10-
ms.custom: vscode-azure-extension-update-completed
11-
title: Exercise - Use a storage account to host a static website
12-
durationInMinutes: 15
13-
content: |
14-
[!include[](includes/7-exercise-host-a-static-website-using-a-storage-account.md)]
15-
1+
### YamlMime:ModuleUnit
2+
uid: learn.advocates.azure-functions-and-signalr.7-exercise-host-a-static-website-using-a-storage-account
3+
metadata:
4+
title: Exercise - Use a storage account to host a static website
5+
description: Customize your storage account, publish your function app, and view your application hosted in the cloud.
6+
ms.date: 01/22/2025
7+
author: craigshoemaker
8+
ms.author: cshoe
9+
ms.topic: unit
10+
ms.custom: vscode-azure-extension-update-completed
11+
title: Exercise - Use a storage account to host a static website
12+
durationInMinutes: 15
13+
content: |
14+
[!include[](includes/7-exercise-host-a-static-website-using-a-storage-account.md)]
15+
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11

2-
As an engineer with Tailwind Traders, you've learned your company is planning to launch a new website that provides stock price information to customers. Recently, an intern created a website prototype for the new application and the Lead Architect has now asked you to step in and improve the solution. Your objective is to update the app to implement automatic updates of the stock price information, but ensure communication between the client and server happens only when data changes on the server.
2+
As an engineer with Tailwind Traders, you learned that your company is planning to launch a new website that provides stock price information to customers. Recently, an intern created a website prototype for the new application and the Lead Architect is asking you to step in and improve the solution. Your objective is to update the app to implement automatic updates of the stock price information, but ensure communication between the client and server happens only when data changes on the server.
33

44
## Prototype architecture
55

6-
The server prototype has 2 functions:
6+
The server prototype has two functions:
77

88
|Function name|Trigger type|Description|
99
|--|--|--|
1010
|**getStocks**|Azure Cosmos DB|The server is responsible for reading all data from the stocks table in the database and returning that data in an HTTP response whenever the client requests it.|
11-
|**setPrice**|Timer|A function to change the data in the database runs on a timer trigger. This simulates receiving changes from a backend system.|
11+
|**setPrice**|Timer|A function to change the data in the database runs on a timer trigger. This function simulates receiving changes from a backend system.|
1212

1313
As a prototype, the intern simulated the stock feed with a timer function, which updates every minute. The client website requests all the stocks from the `/api/getStocks` API endpoint every 5 seconds in an attempt to display near real time data. This client request isn't efficient. Instead of pulling the data from the server, it's more efficient for the server to push any new stock information.
1414

1515
## Tasks to be done
1616

1717
In this module, you will:
1818

19-
- Run the prototype: View the client application, which polls the server for all stocks on a regular interval
19+
- Run the prototype: View the client application, which polls the server for all stocks at a regular interval.
2020
- Improve the application: Implement a serverless Azure Functions app to broadcast changes to connected clients using SignalR Service to product near real-time updates.
2121
- Update the client JavaScript web application to connect to SignalR to get and display the messages.

learn-pr/advocates/automatic-update-of-a-webapp-using-azure-functions-and-signalr/includes/2-analyze-limitations-of-polling-in-a-web-app.md

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
![Polling-based web application.](../media/serverless-app-polling-concept.png)
22

3-
The application's current architecture reports stock information by fetching _all_ stock price information from the server based on a timer. This design is often called a polling-based design.
3+
The application's current architecture reports stock information by fetching *all* stock price information from the server based on a timer. This design is often called a polling-based design.
44

55
### Server
66

77
The stock price information is stored in an Azure Cosmos DB database. When triggered by an HTTP request, the function `getStocks` returns all rows from the database.
88

9-
109
:::code language="typescript" source="~/../microsoftdocs-mslearn-advocates-azure-functions-and-signalr/start/server/src/functions/getStocks.ts" :::
1110

12-
* **Get data**: The first section of code, **cosmosInput**, gets all the items in the `stocks` table, with the query `SELECT * from c`, in the `stocksdb` database in Cosmos DB.
13-
* **Return data**: The second section of code, **app.http**, receives that data into the function as an input in `context.extraInputs` then returns it as the response body back to the client.
14-
11+
- **Get data**: The first section of code, **cosmosInput**, gets all the items in the `stocks` table, with the query `SELECT * from c`, in the `stocksdb` database in Cosmos DB.
12+
- **Return data**: The second section of code, **app.http**, receives that data into the function as an input in `context.extraInputs` then returns it as the response body back to the client.
1513

1614
### Client
1715

@@ -29,17 +27,17 @@ The server and client code is relatively straightforward: get all data, display
2927

3028
## Analysis of prototype solution
3129

32-
As a Tailwind Traders engineer, you've identified some of the drawbacks of this timer-based polling approach.
30+
As a Tailwind Traders engineer, you identified some of the drawbacks in this timer-based polling approach.
3331

34-
* **Unnecessary API requests**: In the timer-based polling prototype, the client application contacts the server whether or not changes exist to the underlying data.
35-
* **Unnecessary page refreshes**: Once data is returned from the server, the entire list of stocks is updated on the web page, even if no data has changed. This polling mechanism is an inefficient solution.
36-
* **Polling intervals**: Selecting the best polling interval for your scenario is also a challenge. Polling forces you to make a choice between how much each call to the backend costs and how quickly you want your app to respond to new data. Delays often exist between the time that new data becomes available and the time that the app detects it. The following illustration shows the issue.
32+
- **Unnecessary API requests**: In the timer-based polling prototype, the client application contacts the server whether or not changes exist to the underlying data.
33+
- **Unnecessary page refreshes**: Once data is returned from the server, the entire list of stocks is updated on the web page, even if no data changes. This polling mechanism is an inefficient solution.
34+
- **Polling intervals**: Selecting the best polling interval for your scenario is also a challenge. Polling forces you to make a choice between how much each call to the backend costs and how quickly you want your app to respond to new data. Delays often exist between the time that new data becomes available and the time that the app detects it. The following illustration shows the issue.
3735

3836
![An illustration showing a timeline and a polling trigger checking for new data every five minutes. New data becomes available after seven minutes. The app isn't aware of the new data until the next poll, which occurs at 10 minutes.](../media/polling-example.png)
39-
37+
4038
In the worst case, the potential delay for detecting new data is equal to the polling interval. So why not use a smaller interval?
4139

42-
* **Amount of data**: As the application scales, the amount of data exchanged between the client and server becomes a problem. Each HTTP request header includes hundreds of bytes of data along with the session's cookie. All this overhead, especially when under heavy load, creates wasted resources and unnecessarily taxes the server.
40+
- **Amount of data**: As the application scales, the amount of data exchanged between the client and server becomes a problem. Each HTTP request header includes hundreds of bytes of data along with the session's cookie. All this overhead, especially when under heavy load, creates wasted resources and unnecessarily taxes the server.
4341

4442
Now that you're more familiar with the prototype, it's time to get the application running on your machine.
4543

@@ -52,6 +50,6 @@ In the *local.settings.json* file of the Functions App, the `Host` section inclu
5250

5351
This configuration allows a web application running at *localhost:3000* to make requests to the function app running at *localhost:7071*. The property `CORSCredentials` tells the function app to accept credential cookies from the request.
5452

55-
Cross-origin resource sharing (CORS) is an HTTP feature that enables a web application running under one domain to access resources in another domain. Web browsers implement a security restriction known as same-origin policy that prevents a web page from calling APIs in a different domain; CORS provides a secure way to allow one domain (the origin domain) to call APIs in another domain.
53+
Cross-origin resource sharing (CORS) is an HTTP feature that enables a web application running under one domain to access resources in another domain. Web browsers implement a security restriction known as same-origin policy that prevents a web page from calling APIs in a different domain; CORS provides a secure way to allow one domain (the origin domain) to call APIs in another domain.
5654

57-
When running locally, CORS is configured for you in the sample's local.settings.json file, which is never published. When you deploy the client app (unit 7), you have to also update the CORS settings in the function app to allow access from the client app.
55+
When you run locally, CORS is configured for you in the sample's local.settings.json file, which is never published. When you deploy the client app (unit 7), you have to also update the CORS settings in the function app to allow access from the client app.

learn-pr/advocates/automatic-update-of-a-webapp-using-azure-functions-and-signalr/includes/3-exercise-analyze-limitations-of-polling-in-a-web-app.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Before you change the prototype, you need to run it to validate the assumptions.
22

33
## Create Azure resources
44

5-
1. In a separate browser tab or window, fork the sample repository on GitHub with the following link: [mslearn-advocates.azure-functions-and-signalr](https://github.com/MicrosoftDocs/mslearn-advocates.azure-functions-and-signalr/fork). This allows you to push your changes to your own version of the source code. This is a required step in order to deploy the source code to Azure later in the module.
5+
1. In a separate browser tab or window, fork the sample repository on GitHub with the following link: [mslearn-advocates.azure-functions-and-signalr](https://github.com/MicrosoftDocs/mslearn-advocates.azure-functions-and-signalr/fork). This fork allows you to push your changes to your own version of the source code. This step is required in order to deploy the source code to Azure later in the module.
66

77
1. In the terminal, clone your forked repository. In the following command, replace `MicrosoftDocs` with your account:
88

@@ -40,7 +40,7 @@ Before you change the prototype, you need to run it to validate the assumptions.
4040

4141
This default subscription is used to create the Azure resources.
4242

43-
1. Create the Azure resources and upload the sample data to the database. The process may take a few minutes to complete.
43+
1. Create the Azure resources and upload the sample data to the database. The process can take a few minutes to complete.
4444

4545
```bash
4646
bash create-start-resources.sh "<YOUR-SUBSCRIPTION-NAME>"
@@ -69,7 +69,6 @@ Before you change the prototype, you need to run it to validate the assumptions.
6969
Seed data added. Symbol DEF
7070
Seed data added. Symbol GHI
7171
```
72-
7372
7473
1. In the terminal, navigate to the **root** folder.
7574
@@ -86,26 +85,24 @@ Before you change the prototype, you need to run it to validate the assumptions.
8685
cd start/server && npm install && cd ../..
8786
```
8887
89-
1. If the notification asks you to select an Azure functions app for the workspace, select `start/server`. This is the function app that you'll use to run the server-side code.
88+
1. If the notification asks you to select an Azure functions app for the workspace, select `start/server`. This is the function app that you'll use to run the server-side code.
9089

9190
1. If you receive a notification about installing the latest Azure Functions Core Tools, select **Install**.
9291

9392
## Get the client and server URLs
9493

95-
When running locally, the client and server applications need to know where to find each other. The URLs are:
94+
When you're running locally, the client and server applications need to know where to find each other. The URLs are:
9695
9796
- **Client**: http://localhost:3000
9897
- **Server**: http://localhost:7071
9998
100-
10199
## Update local settings for the Azure Functions app
102100
103101
Add the connection strings to the prototype's Azure Functions app.
104102

105103
1. Create the **./start/server/local.settings.json** file and paste in the following. This file has the configuration settings for the local functions project.
106104

107105
:::code language="json" source="~/../microsoftdocs-mslearn-advocates-azure-functions-and-signalr/start/server/sample.local.settings.json" :::
108-
109106

110107
1. Update the following variables with values you copied from above.
111108

@@ -128,7 +125,7 @@ BACKEND_URL=http://localhost:7071
128125
129126
## Run the server application
130127
131-
1. In the terminal, start the Azure Functions application.
128+
1. Start the Azure Functions application by entering the following command in the terminal.
132129
133130
```bash
134131
cd start/server && npm start
@@ -157,10 +154,10 @@ BACKEND_URL=http://localhost:7071
157154
158155
1. Arrange your browser windows so you can see the terminal and the prototype of the stock prices at the same time.
159156
1. In the prototype browser window, open the browser's developer tools. Notice the browser is making a request to the API every 5 seconds for all the data, even though the data hasn't changed.
160-
1. In the browser window, watch the output for the Azure Functions app. A single stock price changes every minute. When the price in the API changes, the next client fetch of all data includes that change.
157+
1. In the browser window, watch the output for the Azure Functions app. A single stock price changes every minute. When the price in the API changes, the next client fetch of all data includes that change.
161158
162159
:::image type="content" source="../media/visual-studio-code-terminal-output-stock-change.png" alt-text="Screenshot of Visual Studio Code terminal showing console output of the stock price change.":::
163160
164161
1. In both the terminals for client and server, stop the applications with <kbd>Ctrl</kbd> + <kbd>C</kbd> or kill the terminal by selecting the trashcan icon.
165162
166-
In this unit, you ran the prototype. While the client does run successfully, it isn't efficient. While each individual client may not notice this with such a small number of stocks, that will change as the number of stocks grows and the number of clients pull from the server. The prototype can be improved. Let's learn how in the next unit.
163+
In this unit, you ran the prototype. While the client does run successfully, it isn't efficient. While each individual client might not notice this with such a small number of stocks, that will change as the number of stocks grows and the number of clients pull from the server. The prototype can be improved. Let's learn how in the next unit.

0 commit comments

Comments
 (0)