studio status report: 2023-10
month 10 of 2023 was about finding foundational bugs π in Songhay.Player.ProgressiveAudio (and finally using Redis Cache)
No funny banter this month π Issues #13 and #14 are currently holding up the release of the b-roll audio player. These challenges have emerged in a month that looks like this:

The major progress of this month was day-job related: I architected an app feature requiring Azure Cache for Redis. This work bled into weekends π΅ but was well worth the desired accomplishment! Selected notes below should touch upon this grueling journey:
[[Azure Cache for Redis]]: IDistributedCache does not support SCAN and MGET but is still needed
The following table summarizes the [[Redis]] commands the #day-job needs:
| [[Redis]] command | IDC method | ICM/ID/IS method |
|---|---|---|
GET[π docs ] |
GetStringAsync[π docs ] |
StringGetAsync(string)[π GitHub ] |
DEL1[π docs ] |
RemoveAsync[π docs ] [π GitHub ] |
KeyDeleteAsync[π GitHub ] |
SET[π docs ] |
SetStringAsync[π docs ] |
StringSetAsync[π GitHub ] |
MGET[π docs ] |
π« | StringGetAsync(string[])[π GitHub ] |
SCAN[π docs ] |
π« | KeysAsync[π GitHub ] |
HGET[π docs ] |
π« | HashGetAsync[π GitHub ] |
1There is no MDEL command as the DEL command supports multiple optional keys.
GetStringAsync and SetStringAsync have an advantage over the ID equivalents because [[Microsoft]] abstracts away the ceremony around setting expiration dates.
welcome to Friday the 13th πΈ: when IDistributedCache writes a string into [[Redis]], it is actually writing a hash π #day-job
In order to support [[Redis]] cache entry expiration β [[Microsoft]] is entering hashes on our behalf when we expect strings to be written! This means that:
[!warning]
MGETcannot be used withIDistributedCache[[Redis]] cache entries because these entries are hashes. There are no [[Redis]] commands that are the hash-equivalent ofMGET.
It is an error to assume that HMGET [π docs ] is the equivalent of MGET. The hash getters of [[Redis]] are more concerned with returning multiple values from a single hash entry. I see no concern for returning an array of arrays: multiple hash values.
[[Songhay Player - Progressive Audio (Fβ―)]]: progressive audio features are actually needed for the progressive audio player π
The previous progressive audio player leveraged audio5js [π GitHub ] which correctly uses the canplay event [π GitHub ] while my design currently does notβnot even incorrectly π
[!error] Currently the [[Songhay Player - Progressive Audio (Fβ―)]] does not use the
canPlayevent [π docs ] which means large files that are not sufficiently downloaded fail to play (without any console error messages).
These are the minimum features needed based on the canPlay event:
- [x] the player controls should be disabled until the
canPlayevent fires orHTMLMediaElement.readyStateis greater than2(HAVE_FUTURE_DATAorHAVE_ENOUGH_DATA[π docs ]) - [x] when a playlist item is clicked the player controls should be disabled and the
canPlayevent should fire again and/orHTMLMediaElement.readyStateis checked again - [x] the playlist should be disabled until the current track
canPlayand/orHTMLMediaElement.readyStateis greater than2 - [x] data should be written to the console to track states (the
loadstartevent [π docs ] and theloadedmetadataevent [π docs ] should be tracked here)
Issue #14 is open for this.
design critique
Because I decided π to use a fucked up polling strategy in ProgressiveAudioUtility.startPlayAnimation I allowed myself to not care about HTMLMediaElement.readyState. I now consider this decision insane.
- [x] #14 add
PlayerAudioLoadStartEventandPlayerAudioCanPlayEventmessages π¨π - [x] #14 add
ProgressiveAudioModel.canPlayboolean π¨ - [x] #14 remove the polling strategy in
ProgressiveAudioUtility.startPlayAnimationπ¨ - [x] #14 remove
ProgressiveAudioUtility.toggleElementEnabledπ¨π₯ - [x] #14 use
ProgressiveAudioModel.canPlayboolean to drive the application ofpointer-events: nonefor the playlist π¨ππ
three new [[Jupyter]] notebooks to study [[JavaScript]] #day-job
- [[dotnet|.NET]]:
IDictionary<TKey,TValue>and JavaScriptβsMap[π GitHub ] - JavaScript date math [π GitHub ]
- [[jQuery]]:
.serializeArrayandFormData
βHow to list all routes in an [[ASP.NET]] Core applicationβ #day-job
https://www.meziantou.net/list-all-routes-in-an-asp-net-core-application.htm
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseRouting();
if (app.Environment.IsDevelopment())
{
app.MapGet("/debug/routes", (IEnumerable<EndpointDataSource> endpointSources) =>
string.Join("\n", endpointSources.SelectMany(source => source.Endpoints)));
}
app.Run();
the [[Daniel Ward]] presentation on [[xUnit]]
The big news from this [[Daniel Ward]] presentation is the surprise about [[xUnit]] collections:
How does xUnit.net decide which tests can run against each other in parallel? It uses a concept called test collections to make that decision.
By default, each test class is a unique test collection. Tests within the same test class will not run in parallel against each other.
Also see βShared Context between Testsβ π
[!warning] The [[xUnit]] documentation makes no mention of ordered testing.
[[Daniel Ward]] made no mention of ordered testing which may suggest that ordered tests are frowned upon or considered obsolete in the context of mocking and using containers with [[Respawn]].
I need to revisit this [[Daniel Ward]] video again for more detail #to-do
[[Microsoft]]: βWilliam A. Adams, Software Engineer, DEI Innovator, and Philanthropistβ
sketching out development projects
The current, unfinished public projects on GitHub:
- replace the Angular app in
http://kintespace.com/player.htmlwith a Bolero app ππ₯ - finish the β
SonghayCoreπ¦β¨ release 6.0.5β project - start the β
Songhay.Publications.Models6.0.0β π¦π project
The proposed project items:
- add kintΓ© space presentations support to
Songhay.Player.YouTubeπ¨ πβ¨ - generate Publication indices from SQLite for
Songhay.Publications.KinteSpace - generate a new repo with proposed name,
Songhay.Modules.Bolero.Indexβ¨π§ and add a GitHub Project - switch Studio from Material Design to Bulma π β‘οΈ πβ¨