The Daily Parker

Politics, Weather, Photography, and the Dog

The roof repairs continue

Today they got through about half of our flat roof which doubles as an upstairs patio. Imagine how much noise all this made:

Note that all the crap on the roof off to my left was at the other end of the balcony while they laid down the material directly under me. They timed it so they had the power saw going exactly when I had a Teams meeting for work. But they did got a lot of it done, and they should reconnect my A/C units just in time for next week's heat wave.

Free time resumes tomorrow

During the weeks around our Spring Concert, like during the first couple of weeks of December, I have almost no free time. The Beethoven performance also took away an entire day. Yesterday I had hoped to finish a bit of code linking my home weather station to Weather Now, but alas, I studied German instead.

Plus, with the aforementioned Spring Concerts on Friday and today, I felt that Cassie needed some couch time. (We both sit on the couch while I read or watch TV and she gets non-stop pats. It's good for both of us.) She'll get more couch time tonight, don't worry. But she'll also be home alone for about 7 hours today.

I don't have rehearsal tomorrow, and in fact I have no responsibilities beyond my normal day job until next Saturday, so I should finish the coding soon. (I also have a task for an old client that will take me a dozen or so hours, and I really need to start that before my trip.)

In the hour I have before Cassie's next walk and me driving out to Oak Park, I need to study more German and some Czech. In the former we're now discussing how the bear and the mouse need to an apartment („Der Bär und die Maus brauchen eine Wohnung”, for what purpose I can only imagine), and in the latter, whether I eat salt („Jíš sůl?”) and that they have good coffee („Kávu mají dobrou”). Clearly I have more work to do in Czech.

Twenty Five Years

The Daily Parker began as a joke-of-the-day engine at the newly-established braverman.org on 13 May 1998. This will be my 8,907th post since 1998 and my 8,710th since 13 November 2005. And according to a quick SQL Server query I just ran, The Daily Parker contains 15,043,497 bytes of text and HTML.

A large portion of posts just curate the news and opinions that I've read during the day. But sometimes I actually employ thought and creativity, as in these favorites from the past 25 years:

Also interesting is how I can chart key events in my life just by looking at how often I posted:

Right now, I'm predicting the 10,000th post on 5 August 2025. Keep reading and find out.

Weather Now update

I just released a couple of minor fixes to Weather Now. Build 8126 has slightly tidier top and nav bars, and I can configure the front page "latest weather" list on the fly. Previously the list lived in a static application config file that I could only change by redeploying the app.

Enjoy.

Reading while the CI build churns

I'm chasing down a bug that caused what we in the biz call "unexpected results" and the end-users call "wrong." I've fixed it in both our API and our UI, but in order to test it, I need the API built in our dev/test environment. That takes about 18 minutes. Plenty of time to read all of this:

Finally, the Times explains how last year's 257 traffic fatalities in New York City undermine the claims that "Vision Zero" is working. But Strong Towns already told you that.

OK, build succeeded, fix is now in Dev/Test...on with the show!

Who could have predicted this?

As professional narcissist Elon Musk threatened, on Thursday Twitter abruptly ended their verified "blue check" program. Suddenly, Twitter users had no way to know for sure whether tens of thousands of government agencies, celebrities, journalists, and other people whose jobs depend to some extent on their credibility, were who their Twitter accounts purported to be.

It only took two days for someone to hoax the City of Chicago:

Impostors posing as Chicago government officials, including Mayor Lori Lightfoot, posted a series of tweets early Friday morning falsely claiming that North Jean Baptiste Point DuSable Lake Shore Drive is being permanently closed.

The accounts posting the false tweets claimed to be Lightfoot, the Chicago Department of Transportation and the Illinois Department of Transportation. Their posts were seen by well over 100,000 people early in the day, according to Twitter data.

The impersonation effort came just a day after Twitter removed verification from accounts that had been previously verified for the purpose of credibility. Twitter CEO Elon Musk’s controversial decision to remove the “legacy” verifications took away the authenticated status of all three of the impersonated accounts.

Before Friday, the usernames of the true mayoral account, CDOT account and IDOT account had all previously appeared alongside a blue check mark signaling that the accounts had been proved to actually represent the authorities they claimed to represent. However, those check marks were taken away Thursday because of Musk’s decision.

New York City's government also had their own problem.

But this highlights a real problem: in a disaster, or an election, how will people know what information is real? I think "by not using Twitter" seems like the right answer but I also don't think Twitter will fully die by next November.

I didn't publish on Twitter very much before. Today, I'm just standing on shore, watching the ship sink. But it's a big ship, and its sinking will foul the environment for a long time.

Clear, cool April morning

The clouds have moved off to the east, so it's a bit warmer and a lot sunnier than yesterday. I still have to wait for an automated build to run. For some reason (which I will have to track down after lunch), our CI builds have gone from 22 minutes to 37. Somewhere in the 90 kB of logs I'll find out why.

Meanwhile, happy Fox News On Trial Day:

Finally, I've started reading The Odyssey, so I applaud National Geographic's article this month on the history of the ancient world in which Homer set the poem.

And hey, a bug

Not five minutes after my last post, I discovered a completely borked feature, caused by a change to the way Azure.Data.Tables executes queries.

The Daily Temperatures feature stores data in the same table as the History feature. Each row represents a weather report, where the table partition key is the weather station identifier and the row key is the date and time of the report. So, for example, the first row of data for Chicago-O'Hare in the 2023 table has a partition key of KORD and a row key of 20230101-0051.

Climate records use a row key of "Climate-" and the date. So yesterday's climate data for Chicago-O'Hare has a partition key of KORD and a row key of "Climate-20230415". Easy to remember, and easy to construct queries.

To that end, the original (.NET 6) code looked like this:

var query = 
	from entity in table.CreateQuery<ClimateRecordTableServiceEntity>()
	where entity.PartitionKey == locationId
		&& string.Compare(entity.RowKey, lowerRowKey, StringComparison.InvariantCultureIgnoreCase) >= 0
		&& string.Compare(entity.RowKey, upperRowKey, StringComparison.InvariantCultureIgnoreCase) <= 0
	select entity;

When I upgraded to .NET 7, I naïvely just changed the first line, to this:

var query = 
	from entity in table.Query<ClimateRecordTableServiceEntity>()
	where entity.PartitionKey == locationId
		&& string.Compare(entity.RowKey, lowerRowKey, StringComparison.InvariantCultureIgnoreCase) >= 0
		&& string.Compare(entity.RowKey, upperRowKey, StringComparison.InvariantCultureIgnoreCase) <= 0
	select entity;

When confronted with a 30-day query, though, it spun off into the abyss and crashed the whole app.

The correct code looks like this:

var query = table.QueryAsync<ClimateRecordTableServiceEntity>(entity =>
	entity.PartitionKey == locationId
		&& string.Compare(entity.RowKey, lowerRowKey, StringComparison.InvariantCultureIgnoreCase) >= 0
		&& string.Compare(entity.RowKey, upperRowKey, StringComparison.InvariantCultureIgnoreCase) <= 0);

See, now the filter part of the query goes inside the method call. (There's an extra step in reading the async results back, too.)

So the effect of the naïve fix was to hit the table 30 times getting back the entire partition each time. Remember that all of the weather reports go into the table? So, yeah, the 2023 table already has something like 7.5 million rows, or about 2,500 in each partition. So it tried to read 75,000 rows just to bring back 30. Oopsi.

I'm deploying the fix now.

New Weather Now build

It took a few weeks at odd hours, but I have finally deployed the latest version of Weather Now (5.0.8507). I didn't update anything visual, but all the plumbing got a refresh. It's now running in .NET 7 (until November, when .NET 8 comes out), and I did a top-to-bottom review of its asynchronous code.

The app now runs noticeably faster, and I believe the corrections to the async bits will cure the nagging (but invisible) problem of thread exhaustion that happened from time to time.

Now I can start making some other fixes and adding some long-missing features. Really, I just needed to get back into the swing of it.