Simon Online

2022-03-16

Unsupported Architecture for fsevents with Oryx

I updated the version of the lock file on a project the other day in the hopes it might restore a little bit more quickly. However for some steps in my build an older version of NPM was being used. This older version didn’t have support for the new lock file version and while it is supposed to be compatible it seemed like optional dependencies like fsevents were causing a legit issue

npm WARN read-shrinkwrap This version of npm is compatible with lockfileVersion@1, but package-lock.json was generated for lockfileVersion@2. I'll try to do my best with it!
npm ERR! code EBADPLATFORM
npm ERR! notsup Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm ERR! notsup Valid OS:    darwin
npm ERR! notsup Valid Arch:  any
npm ERR! notsup Actual OS:   linux
npm ERR! notsup Actual Arch: x64

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2022-03-09T13_58_42_006Z-debug.log

In theory these fsevent things should be warnings because they are optional dependencies. Updating the version of node used by Oryx, the build engine for Azure Static Web Apps, listens to the version of node defined in package.config. Adding this section to the package.config fixed everything

"engines": {
    "node": ">=16.0",
    "npm": ">=8.0"
  },
2022-02-20

Exclude node_modules from Backblaze Backups on Windows

There are some articles out there about how to exclude node_modules from Backblaze backups on OSX but I couldn’t find anything about windows.

What you want to do is open up C:\ProgramData\Backblaze\bzdata\bzexcluderules_editable.xml and add a new rule.

<excludefname_rule plat="win" osVers="*"  ruleIsOptional="t" skipFirstCharThenStartsWith="*" contains_1="node_modules" contains_2="*" doesNotContain="*" endsWith="*" hasFileExtension="*" />

If you want to exclude .git folders too (they can also contain a lot of small files that are slow to backup) also add

<excludefname_rule plat="win" osVers="*"  ruleIsOptional="t" skipFirstCharThenStartsWith="*" contains_1=".git" contains_2="*" doesNotContain="*" endsWith="*" hasFileExtension="*" />
2022-02-18

Parsing Vue Router Path Parameters

In the vue router you can set up path parameters that are bound into the rendered component. For instance you might have a route like this:

{
    path: '/reports/:reportId/:reportName/:favorite',
    name: 'Reports',
    component: ReportView,
    props: true
}

This will bind the parameters reportId, reportName and favorite on the component. However when you drop into that component and look at the values passed in you will see that they are strings. Of course that makes sense, the router doesn’t really know if the things you pass in are strings or something else. Consider the route /reports/17/awesome report/false. Here reportId and favorite are going to be strings.

You can work around that by giving props in the router a function rather than just a boolean.

{
    path: '/reports/:reportId/:reportName/:favorite',
    name: 'Reports',
    component: ReportView,
    props: (route) => ({
      ...route.params,
      reportId: parseInt(route.params.reportId),
      favorite: route.params.favorite === 'true',
    })
  }
2022-02-16

Installing the AzFilesHybrid PowerShell Module

If you don’t do a lot of powershell then the instructions on how to install the AzFilesHybrid module can be lacking. Here is how to do it

  1. Download the module from https://github.com/Azure-Samples/azure-files-samples/releases
  2. Unzip the file downloaded in step 1
  3. Go into the folder and run the copy command
./CopyToPSPath.ps1
  1. Install the module with
    Install-Module -Name AzFilesHybrid -Force
    

With this module installed you can then run things like Join-AzStorageAccount to get a fileshare joined to the domain

Join-AzStorageAccount -ResourceGroupName "rg-azfileshare" -StorageAccountName "sa-azfileshare" -DomainName "somedomain.com" -DomainUserName "jane" -DomainUserPassword "password"
2022-01-27

Purge CDN in DevOps

In order to purge a cache in the build pipeline you can use some random task that some dude wrote or you can just use the Azure CLI.

Here is an example of what it would look like to purge the entire CDN top to bottom

- task: AzureCLI@2
  displayName: 'Invalidate CDN Cache'
  inputs:
    azureSubscription: 'Azure'
    scriptType: 'batch'
    scriptLocation: 'inlineScript'
    inlineScript: 'az cdn endpoint purge --content-paths "/*"  -n devascacdnendpoint -g devasca-rg --no-wait --profile-name devascacdn'
2021-12-15

Kafka and .NET - Part 3 - Finally at .NET

It has taken us 2 seemingly unrelated posts to get here but we finally made it to the point where we can actually run .NET and interact with Kafka. We need to create two basic programs: one that writes to Kafka and another that reads from it. There is a Kafka client for .NET available in nuget and that’s where our story will start.

Read More

2021-12-09

Kafka and .NET - Part 1 - What is Kafka?

C# Advent

This post is one among many which is part of 2021’s C# Advent. There are a ton of really great posts this year and some new bloggers to discover. I’d strongly encourage you to check it out.

Years ago I was talking to somebody, and I’m sorry I don’t recall who, that was bemoaning the lack of innovative data storage technologies in the .NET space. I honestly didn’t have an answer to that. We have RavenDB but I would avoid that if I possibly could. In the Java space there was Neo4J, Voldemort, Elasticsearch, Cassandra…

Fortunately, those of us who are ostensibly .NET developers don’t have to rely on a data storage tool being written in the same language we’re using to benefit from it. One of the technologies I’ve been looking at recently is Apache Kafka, which is another Java based data storage and routing tool. It is effectively a messaging system but Kafka adds persistence on top of that.

Read More

2021-11-24

Handling Nil in Nested Hashes in Ruby

Tony Hoare introduced Null in ALGOL W in 1965. He says that it was a billion dollar mistake. Fortunately, Ruby totally avoids this sticky problem by renaming null to nil. This is the same strategy that my kids use when I say “next person to ask for popcorn is going to do pushups” and they ask for “corn that has been popped”. If you’re navigating a nested hash, that is a hash that contains other hashes then you might get into a situation where you want to do something like

best_dessert = meals[:dinner][:dessert].find{ | dessert | {name: dessert.name, rating: dessert.rating } }.sort_by{ |a,b| b[:rating] }.first

There are a bunch of opportunities in there for nil to creep in. Maybe there are no dinners maybe no desserts… to handle these we can use a combination of dig (which searches a path in a hash and returns nil if the path doesn’t exist) and the safe navigation &. operator.

best_dessert = meals.dig(:dinner, :dessert)&.find{ | dessert | {name: dessert.name, rating: dessert.rating } }&.sort_by{ |a,b| b[:rating] }&.first

This combination of dig and &. allows us to get a nil out if nil appears anywhere in the chain without ending up in an error. We are calling the combination of dig and &. the 811 operator after https://call811.com/

2021-11-19

Choosing Power BI

If you’re a developer and you’re looking for a solution for reporting in your application then Power BI might be the right choice for you. However, there are tradeoffs that are worth considering before you dig in too much.

What is it?

The GitHub copilot I have running while writing this wants me to say that “Power BI is a platform for creating and managing data-driven reports. It’s a powerful tool that allows you to create reports that are easy to understand and use.” That sounds an awful lot like a sentence that an AI trained on Microsoft marketing data would say. It isn’t entirely inaccurate. For me Power BI is a combination for two different reporting tools which are pretty different from one another. The first is the one you see in all the marketing literature: Dashboard reports. These are nifty looking reports that are largely driven by visuals like maps or charts. Users can easily drill into aspects of the data by clicking on the charts or tables to filter the data and drill in. These reports aren’t great for people who like to see the underlying data and draw their own conclusions.

The second report type is Paginated Reports. These reports are basically a complete migration of the older SQL Server Reporting Services (SSRS) reports. There is limited support for cool graphics but if you need an Excel like view of the data then they are great. I’ve run into a few cases in the past where I’ve tried to convince users that they cannot possibly want a 90 page report and that they should use the dashboard report. But frequently users do legitimately want to print 90 pages and go at the report with a highlighter. One of my favorite sayings for these situations is that as a developer I make suggestions and users make decisions.

The desktop based tools for building these reports are all pretty good. The dashboard report tool in particular is excellent. It may be that your users don’t need to use online reporting and that providing them with a database connection and a copy of Power BI Desktop will be a good solution. The added advantage there is that the desktop tools are free to use. If you have a read only replica of your database then letting users develop their own reports doesn’t have much of a downside other than having to support people as they learn the system. A cool idea is to build projections or views inside your database to handle the complex joins in your data and remove that burden from the users.

If you want to embed the reports in your application there is facility for doing that through a JavaScript API. You do need to jump through some hoops to authenticate and generate tokens but that’s a lot easier than developing your own HTML based reports. There aren’t a whole lot of examples out there for how to do embeddeding and you will need to spend some time learning the security models.

The alternative to all this is to use one of the myriad of other reporting tools that are available. I’ve used Telerik Reporting quite a lot in the past and I can confidently say it is “not terrible”. That’s about as high of praise as you’re going to get from me for a reporting tool.

Cost

As with anything Microsoft the pricing for all this is convoluted and contently changing. This is my current understanding of it but you can likely get a better deal and understanding by talking to your sales representative.

  • Power BI Desktop: Free as in beer
  • Power BI Pro: Let’s you run dashboard reports online and embed them in your application (note that this doesn’t’ let you embed paginated reports) $9.99/month a users
  • Power BI Premium per user: This lets you run dashboard reports online and embed them in your application and also run paginated reports (note I didn’t say embed paginated reports) $20/month a user
  • Power BI Premium per capacity: Run and embed both report types. Open for as many users as you have. $4995/month. Yikes, that price sure jumps up

Being able to embed paginated reports was the killer feature for me that took the reporting cost from very reasonable to very expensive.