# Tuesday, December 4, 2018

Joey DeFrancesco TrioJazz musicians are famous for playing the notes around the melody, adding their own interpretation of a tune. But the tremolo of Joey DeFrancesco's organ does much of that for him.

the Joey DeFrancesco Trio brought played a delightful set Sunday night at the Jazz Showcase in Chicago's South Loop. Most songs began with a mellow feel, then increased in energy until each was swinging and/or rocking.

Like most great band leaders, DeFrancesco knows to find and showcase great musicians. In this trio, it was saxophonist Victor North, whose solos captivated the audience. Drummer Khary Shahee was solid throughout and seemed determined to play every solo with his eyes closed.

David and JoeyThe Trio played a mix of originals ("Blues in Three", "Trip Mode") and arrangements of other composers tunes, including an extended version of Cole Porter's classic "Night and Day".  One highlight was the beautiful melody of "Easy to Remember" and the final song of the night – an up-tempo, frenzied piece in which each member of the band tried to outperform one another in turn.

It wasn't a long set - maybe 75 minutes - and the second set was canceled due to low ticket sales; but those who came out saw an excellent performance.

Tuesday, December 4, 2018 9:28:00 AM (GMT Standard Time, UTC+00:00)
# Monday, December 3, 2018

Episode 540

Bill Wagner on Nullable Reference Types

C# 8 will have support for Nullable reference types, which will allow you to know better when you need to check for null in your variables. Bill explains the syntax and implication of this upcoming language feature.

Monday, December 3, 2018 9:04:00 AM (GMT Standard Time, UTC+00:00)
# Sunday, December 2, 2018

Today I am grateful to pay off some sleep debt the past few days.

Today I am grateful for a warm day in December.

Today I am grateful that I live 1 block from a grocery store.

Today I am grateful for floor seats to see an exciting DePaul - CSU basketball game last night on my first visit to WinTrust Arena.

Today I am grateful that the severe back pain that began earlier this month is almost entirely gone.

Today I am grateful for a hot bath on a cold evening.

Today I am grateful that my toilet is finally fixed.

Today I m grateful to stay home and watch college football on a Saturday.

Today I am grateful for. a slow drive across Michigan with frequent stops yesterday.

Today I am grateful to spend Thanksgiving with my family.

Today I am grateful for my first visit to the UK.

Today I am grateful
-for a guided walking tour of historic London yesterday morning
-for a visit to the UK National Gallery yesterday afternoon
-to my new manager for traveling to London to meet me for dinner last night

Today I am grateful for lunch with Andy yesterday.

Today I am grateful to meet up with 2 old friends in a foreign country: James at lunch; and Tobiasz at dinner.

Today I am grateful to speak at #GangConf in Detroit yesterday.

Today I am grateful for:
-Lunch with Suzanne and Darcy yesterday
-Ondrej and Desi letting me stay at their home last night

Today I am grateful for my first acupuncture session yesterday.

Today I am grateful for all 4 seasons.

Today I am grateful for Taco Tuesday at Flaco's.

Today I am grateful for an independent press.

Today I am grateful for a day in Milwaukee with friends.

Today I am grateful for my first-ever visit to a chiropractor yesterday.

Today I am grateful to work from on the first very cold day of the season.

Today I am grateful for the opportunity to mentor startups and entrepreneurs at The University of Chicago Polsky Exchange the past 4 years.

Today I am grateful to see The Jeff Lorber Fusion in concert last night at The Promontory.

Today I am grateful for the opportunity to vote yesterday.

Today I am grateful for a tour yesterday of Epic Systems, one of the most creatively-designed campuses I've seen.

Sunday, December 2, 2018 6:38:13 PM (GMT Standard Time, UTC+00:00)
# Saturday, December 1, 2018

BridesheadRevisitedIn his first year at University, Charles Ryder meets Sebastian Flyte and is immediately attracted to him. Sebastian is handsome, rich, charming, and carefree and the two of them quickly become inseparable, drinking together at every opportunity.

Sebastian invites Charles home to Brideshead Castle. Sebastian describes the palatial estate as "It's where my family lives". Despite the barriers Sebastian erects between himself and his family, the Flytes almost immediately accept Charles as one of their own.

The family is an interesting mix of characters - the beautiful and intelligent Julia, who looks and sounds much like Sebastian; the idealistic Cordelia; the strong and pious mother Lady Marchmain; and the father Lord Marchmain, who abandoned his family to live with his mistress in Venice. Sebastian spends much of his time at home drinking to excess, despite his family's efforts to prevent him from doing so.

Eventually, Sebastian's drinking becomes so severe that his family has no idea how to help him; and he leaves home, largely exiting the story except in secondhand reports.

But Charles and the Flytes remain and Brideshead Revisited by Evelyn Waugh is their story.

The Flytes are very wealthy and part of the upper social strata of English aristocracy. But they are also Roman Catholic, which is a rarity in Anglican England and which affects both how they view the world.

The story follows Charles through 3 phases of his life - framed by a wartime visit to an abandoned Brideshead, which sparks his memories of his life with the Flytes.

In Part 1 ("Et In Arcadia Ego"), Charles and Sebastian meet and form a very close relationship. Some critics have described this as a homosexual relationship. I'm inclined to believe it is not because Waugh never mentions anything physical between the two and he does explicitly introduce other homosexuals into the narrative. Regardless, Sebastian and Charles become close enough that they end up spending all their free time together and eventually stop seeing their other friends - a pattern into which romantic couples often fall. There is no question of the love they feel for one another. It is in this part that Charles begins to bond with the Flyte family.

In Part 2 ("Brideshead Deserted"), the characters drift apart. Sebastian is an alcoholic and has left the family and traveled to Africa. Charles marries and becomes a successful painter. The other Flytes go out in the world, seeking careers and love. It concludes with Charles reconnecting with and falling in love with Sebastian's married sister Julia. Each agrees to divorce their spouse to be free to marry one another.

In Part 3 ("A Twitch Upon the Thread"), most of the family returns to Brideshead, including the dying Lord Marchmain and deal with their changing lives. The Catholicism of the Flyte family takes center stage in this section, particularly when contrasted with the agnostic Charles and Lord Marchmain.

Brideshead is about the English idle rich between the world wars; about the British caste system; about the decline of the aristocracy; about personal responsibility; about religion and its influence on moral choices; about sexuality; and about love and friendship.

Charles is an outsider in the aristocratic world of the Flytes; but he is not a dispassionate observer. He injects himself fully into the family and they embrace him. Some even love him. But the family is filled with drama and conflict. And Charles becomes part of it.

Most of the characters deteriorate as the novel progresses. Even Brideshead Manor itself falls into disrepair as the family abandons it to pursue interests elsewhere. In the beginning, most characters possess the optimism of youth; but, by Part 3, they have either aged poorly, become disillusioned, or squandered their lives as a wandering alcoholic. Still, there is optimism in this novel. And some are at least partially saved by an epiphany and a religious conversion late in life.

Brideshead Revisited is a complex story that reminds us that life is a journey that takes us both forward and backward and that we have control over where it takes us. It is a personal story told by Charles and his recollections force him at last to reconsider his life.

Saturday, December 1, 2018 9:52:00 AM (GMT Standard Time, UTC+00:00)
# Friday, November 30, 2018

Given an Azure Function, you may wish to change the URL that points to this function. There are several reasons to do this:

  1. Make the URL simpler
  2. Make the URL more readable
  3. Make the URL conform to your organization's standards

To reassign a Function's URL, you will need to know the existing URL. To find this, select the Function and click the "Get function URL" link, as shown in Fig. 1.

Fig. 1

The Function URL dialog displays, as shown in Fig. 2.

Fig. 2

Click the [Copy] icon to copy this URL to your clipboard. You may wish to paste this into a text document or another safe place for later use.

Each Azure Function App contains a "Proxies" section, as shown in Fig. 3.

Fig. 3

Click the [+] icon to display the "New proxy" blade, as shown in Fig. 4.

Fig. 4

At the "Name" field, enter a name to identify this proxy. I like to include the name of the original function in this name, to make it easy to track to its source.

At the "Route template" field, enter a template for the new URL. This is everything after the "https://" and the domain name. If the function accepts parameters, you will need to add these and surround them with curly brackets: "{" and "}".

At the "Allowed HTTP methods" dropdown, select "All methods" or check only those methods you wish your new URL to support.

At the "Backend URL" field, enter the full original URL copied earlier to your clipboard. If the function accepts parameters, you will need to add these and surround them with curly brackets: "{" and "}". The parameter name here must match the parameter name in the "Route template" field.

An example

For example, if I created a Function with an HTTPTrigger and accepted all the defaults (as described here), you will have a function that accepts a querystring parameter of "name" and outputs "Hello, " followed by the value of name.

My original function URL looked similar to the following:


So, I entered the following values into the "New Proxy" blade:

Name: HttpTrigger1Proxy
Route template: welcome/{name}
Allowed HTTP methods: All methods
Backend URL: https://dgtestfa.azurewebsites.net/api/HttpTrigger1?code=idLURPj58mZrDdkAh9LkTkkz2JZRmp6/ru/DQ5RbotDpCtg/WY/pRw==&name={name}

With these settings, I can send a GET or POST request to the following url:


and receive the expected response:

Hello, David

This new URL is much simpler and easier to remember than the original one.

In this article, I showed you how to create a proxy that redirects from a new URL to an existing Azure Function.

Friday, November 30, 2018 9:43:00 AM (GMT Standard Time, UTC+00:00)
# Thursday, November 29, 2018

GCast 24:

Azure Function CosmosDB Binding

Using the CosmosDB binding in an Azure Function allows you to read and write documents in an Azure CosmosDB database without writing code.

Thursday, November 29, 2018 9:22:00 AM (GMT Standard Time, UTC+00:00)
# Wednesday, November 28, 2018

Setting up continuous deployment of an Azure Function from GitHub  is straightforward.

In this article, I already had an Azure Function (created using Visual Studio) in a GitHub  repository and an empty Azure Function App.

See this article for information on GitHub

See this article to learn how to create an Azure Function App.

Open the Azure Function App in the Azure portal, as shown in Fig. 1.

Fig. 1

Click the "Platform features" link (Fig. 2) to display the "Platform features" page, as shown in Fig. 3.

Fig. 2

Fig. 3

Under "Code Deployment", click the "Deployment Center" link to open the "Deployment Center" page, as shown in Fig. 4.

Fig. 4

On the "Deployment Center" page, select the "GitHub " tile and click the [Continue] button, as shown in Fig. 5.

Fig. 5

The wizard advances to the "Configure" page of the "Deployment Center" wizard, as shown in Fig. 6.

Fig. 6

At the "Organization" dropdown, select the GitHub  account where your code resides. If you don't see the account, you may need to give your Azure account permission to view your GitHub  repository.

At the "Repository" dropdown, select the code repository containing your Azure Functions.

At the "Branch" dropdown, select the code branch you wish to deploy whenever a change is pushed to the repository. I almost always select "master" for this.

Click the [Continue] button to advance to the "Summary" page of the "Deployment Center" wizard, as shown in Fig. 7.

Fig. 7

On the "Summary" page, review your choices and click the [Finish] button if they are correct. (If they are not correct, click the [Back] button and make the necessary corrections.

In a few minutes, the function or functions in your repository will appear under your Function App in the Azure portal, as shown in Fig. 8.

Fig. 8

Any future changes pushed to the repository will automatically be added to the Function App.

For example, I can open my Visual Studio project and add a second function, as shown in Fig. 9

Fig. 9

After testing the change, I can push it to my GitHub  repository with the following commands:

git add .
git commit -m "Added a new function"
git push origin master

Listing 1

Because a webhook was added to my GitHub  repository, this change will be pushed to my Azure Function App. Fig. 10 shows the Function app a few minutes after I pushed my change to GitHub .

Fig. 10

In this article, you learned how to configure continuous deployment of your Azure Function App from a GitHub repository.

Wednesday, November 28, 2018 8:33:00 AM (GMT Standard Time, UTC+00:00)
# Tuesday, November 27, 2018

In a recent article, I showed how to create a Durable Azure Function. If you are unfamiliar with Durable Functions, I recommend you read that article first.

In that article, the Durable Function called 3 Activity Functions in sequence. No Function executed until the Function before it completed. Sometimes, it is important that Functions execute in a certain order. But sometimes it does not matter in which order a Function executes - only that they each complete successfully before another Activity Function is called. In these cases, executing sequentially is a waste of time. It is more efficient to execute these Azure Functions in parallel.

In this article, I will show how to create a durable function that executes three Activity Functions in parallel; then waits for all 3 to complete before executing a fourth function.
Fig. 1 illustrates this pattern.

Fig. 1
As we noted in the earlier article, a Durable function is triggered by a starter function, which is in turn triggered by an HTTP request, database change, timer, or any of the many triggers supported by Azure Functions, as shown in Fig. 2.

Fig. 2

I created 4 Activity Functions that do nothing more than write a couple messages to the log (I use LogWarning, because it causes the text to display in yellow, making it easier to find); delay a few seconds (to simulate a long-running task); and return a string consisting of the input string, concatenated with the name of the current function. The functions are nearly identical: Only the Function Name, the message, and the length of delay are different.

The 4 functions are shown below:

    public static class Function1
         public static async Task<string> Run(
             [ActivityTrigger] string msg,
             ILogger log)
             log.LogWarning("This is Function 1");
             await Task.Delay(15000);
             log.LogWarning("Function 1 completed");
             msg += "Function 1";
            return msg;

Listing 1

    public static class Function2 
        public static async Task<string> Run( 
            [ActivityTrigger] string msg, 
            ILogger log) 
             log.LogWarning("This is Function 2"); 
            await Task.Delay(10000); 
            log.LogWarning("Function 2 completed"); 
            msg += "Function 2"; 
            return msg; 

Listing 2

    public static class Function3 
        public static async Task<string> Run( 
            [ActivityTrigger] string msg, 
            ILogger log) 
            log.LogWarning("This is Function 3"); 
            await Task.Delay(5000); 
             log.LogWarning("Function 3 completed"); 
            msg += "Function 3"; 
            return msg; 

Listing 3

    public static class Function4 
        public static async Task<string> Run( 
             [ActivityTrigger] string msg, 
            ILogger log) 
            log.LogWarning("This is Function 4"); 
             int secondsDelay = new Random().Next(8, 12); 
            await Task.Delay(1000); 
            log.LogInformation("Function 4 completed"); 
            msg += "\n\rFunction 4"; 
            return msg; 

Listing 4

We use the Parallel Task library to launch the first 3 functions and have them run in parallel; then, wait until each of the first 3 complete before executing the 4th Activity Function.

Listing 5 shows this code in our Durable Orchestration function.

    public static class DurableFunction1 
         public static async Task<IActionResult> Run( 
            [OrchestrationTrigger] DurableOrchestrationContext ctx, 
            ILogger log) 
            var msg = "Durable Function: "; 
            var parallelTasks = new List<Task<string>>(); 
             Task<string> task1 = ctx.CallActivityAsync<string>("Function1", msg); 
            Task<string> task2 = ctx.CallActivityAsync<string>("Function2", msg); 
            Task<string> task3 = ctx.CallActivityAsync<string>("Function3", msg); 

            await Task.WhenAll(parallelTasks);

            // All 3 Activity functions finished 
            msg = task1.Result + "\n\r" + task2.Result + "\n\r" + task3.Result;

            // Use LogWarning, so it shows up in Yellow, making it easier to spot 
            log.LogWarning($"All 3 Activity functions completed for orchestration {ctx.InstanceId}!");

            msg = await ctx.CallActivityAsync<string>("Function4", msg); 

            return new OkObjectResult(msg); 

Listing 5

We create a new List of Tasks and add each activity to that list:

var msg = "Durable Function: ";
var parallelTasks = new List<Task<string>>();
Task<string> task1 = ctx.CallActivityAsync<string>("Function1", msg);
Task<string> task2 = ctx.CallActivityAsync<string>("Function2", msg);
Task<string> task3 = ctx.CallActivityAsync<string>("Function3", msg);

The following line tells the system to wait until all 3 tasks in that list are completed.

await Task.WhenAll(parallelTasks);

When all 3 tasks complete, we resume the program flow, calling the 4th Activity and logging the output:

log.LogWarning($"All 3 Activity functions completed for orchestration {ctx.InstanceId}!");
msg = await ctx.CallActivityAsync<string>("Function4", msg);

As in the previous article, we launch this Durable Orchestration Function with a starter function (in this case a function with an HTTP trigger), as shown in Listing 6 below.

    public static class StarterFunction1 
        public static async Task<HttpResponseMessage> Run( 
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] 
            HttpRequestMessage req, 
            [OrchestrationClient] DurableOrchestrationClient starter, 
            TraceWriter log) 
             log.Info("About to start orchestration");

            var orchestrationId = await starter.StartNewAsync("DurableFunction1", log); 
            return starter.CreateCheckStatusResponse(req, orchestrationId); 

Testing the Orchestration

We can test this orchestration by running the solution, which displays the HTTP Trigger URL, as shown in Fig. 3

Fig. 3

We can then open a browser, type the HTTP Trigger URL in the address bar, and press [ENTER] to trigger the function, as shown in Fig. 4

Fig. 4

Switch back to the function output to view the messages as they scroll past. You should see output from each of the first 3 functions (although not necessarily in the order called), followed by a message indicating the first 3 are complete; then output from Function 4. This is shown in Fig. 5.

Fig. 5

You can view this project under “Durable Functions” in this GitHub repository.

In this article, I showed how to create a Durable Orchestration Function that launches activity functions that run in parallel.

Tuesday, November 27, 2018 7:29:00 AM (GMT Standard Time, UTC+00:00)
# Monday, November 26, 2018

Episode 539

Brady Gaster on Marketing Azure

Brady Gaster helps to build and coordinate many of the Azure demos you see on stage at large technical conferences. He talks about how his team tells a story with tools and code.

Monday, November 26, 2018 7:22:00 AM (GMT Standard Time, UTC+00:00)
# Sunday, November 25, 2018

FearTrumpInTheWhiteHouseI have read a lot of biographies in my life and many of those focused on the lives of U.S. presidents; but it's rare for me to read a book about a sitting president. I made an exception with Fear: Trump in the White House - partly because it was written by Pulitzer Prize winner Bob Woodward, whose books I've always admired; and partly because Donald Trump's presidency - on which this focuses - is different from any other presidency.

So less than two years into his term, I am reading about Trump's ascent to power.

Woodward describes some of the positives of the Trump presidency. For example, he spends a lot of time discussing a decisive and successful strike on a Syrian air base in response to Syrian President Assad's use of chemical weapons on children, in violation of international law.

But Trump supporters will probably not remember the positive coverage, because there are so many unfavourable descriptions of the President. After the first third of Fear, Woodward's descriptions of Mr. Trump are largely unflattering.

The title of the book comes from a Donald Trump quote: "Real power is fear.", a sentiment he has expressed multiple times.

Entering the White House, Donald Trump had very little understanding of the most basic principles of economics or policy or politics or governing.

For example, he repeatedly suggested that printing more money was a viable solution to the deficit. 

Worse, Trump had no interest in correcting his misconceptions. After trying unsuccessfully to educate Trump on the fact that the U.S. had years ago moved from a manufacturing-based economy to a service based economy, a frustrated advisor asked the president "Why do you have these views?" to which Mr. Trump replied, "I just always have."

He displayed similar ignorance and stubbornness in other matters.

He repeatedly insisted to his advisors that the U.S. should not spend money defending other countries and resisted the argument that doing so was an investment in American security. For example, forward-positioned American troops in South Korea reduce the alert time of a potential North Korean nuclear launch from 15 minutes down to 7 seconds. His generals and economic advisors praised this as a good investment. Despite this, Trump would raise the issue every few months, arguing that the U.S. was wasting money in South Korea.

He repeatedly insisted on huge increases in tariffs, despite advice from his economic advisors that doing so would damage the economy.

Donald Trump takes pride in his decisive action, but he often does so without seeking advice or ignoring expert advice.

He pushed hard for withdrawing from Paris Climate Accord with little consultation about the legality and impact.

He declared via Twitter that transgenders would not be allowed in the military - a major policy decision that broke a campaign promise and defied existing laws. He justified it by grossly overestimating the cost and impact transgender soldiers had on the military. The military refused to enforce this ban and it ultimately failed after an expensive court battle.

In choosing his advisors and staff, Donald Trump values personal loyalty to Donald Trump over experience, intelligence, or other qualifications.

Once hired, he ruled his people by intimidation and bullying, often publicly insulting his staff. He took delight in setting one staff member against another. The result is an abundance of infighting within the White House, which made it difficult for everyone to act in a unified manner.

The advisors in the administration do everything in their power to mitigate Trump's worse impulses. Since reasoning often fails, they often deliberately delayed executing on a directive or they stole papers from the president's desk to prevent him from signing an order or even thinking about it.

This worked because the president's attention span is short, and he has no list of things to accomplish - neither on paper nor in his head. When a paper was removed from his desk, he often did not miss it.

In one of the lowest points in the Trump presidency, the president refused to condemn Nazis and Klansmen marching in Charlottesville, VA, chanting racists slogans, such as "Jews will not replace us". Trump's initial response placed blame "on both sides". His advisors finally convinced him to deliver a speech a few days later, explicitly condemning the white supremacist groups; but Trump almost immediately regretted doing so, complaining that it made him look weak. A few days later, he reverted to his equivalency argument stating there were "very fine people on both sides". His handling of the incident drew praise from Ku Klux Klan leader David Duke and almost universal criticism from non-racists in both political parties.

Fear largely paints a picture of a petty, impetuous, ill-tempered, easily distracted, stubborn, president with little ability to listen or learn

The president's pre-conceived notions (often based on ignorance), his poor listening skills, and his frequent refusal to consider opposing viewpoints often made life frustrating for his advisors, many of whom left shortly after taking the position.

Not surprisingly, Donald Trump himself declared the book "fake", even without reading it. And Trump supporters often close their mind to anything critical of their hero, labeling any criticism - fair or otherwise as "fake news". But several things reinforce the credibility of this book. One is Woodward's reputation: He has won two Pulitzer Prizes and has written critical of public figures in both major parties. The other is that the picture Woodward paints of the president in private is consistent with the image Trump projects through Twitter and his rallies. He has never shied away from personal attacks or name-calling; he frequently overstates his own abilities in speeches, claiming to be the best in the world at multiple skills; and his closest associates have publicly attacked on another.

Woodward conducted hundreds of hours of interviews for this book. He does not identify many of his sources, but it's not difficult to guess some of them, particularly when he reports on a private conversation between Trump and one other person. Woodward requested an interview with the president, but never received a reply.

The author writes in the straightforward style of a professional journalist. Woodward seldom asserts his own opinion. Instead, he quotes the opinions of others in the administration.

Woodward closes the book with a disagreement between Trump and his lawyer about whether the President should testify as part of Special Prosecutor Robert Mueller's investigation into alleged collusion between the Trump campaign and Russia. Trump insists he would be an excellent witness. His lawyer tries to tactfully discourage Trump from testifying (he even threatens to resign as his lawyer) because he knows that Trump is a habitual liar and will almost certainly commit perjury during any sworn testimony.

As I write this review, my hope is that Donald Trump will notice it and label me an enemy, as he does with so many who disagree with him.


Sunday, November 25, 2018 7:02:00 AM (GMT Standard Time, UTC+00:00)