Transaction integrity improved

In my previous post, I proposed some enhancements to improve Shufflizer’s transaction integrity. These are done and in production now. They are:

  1. The count of songs is confirmed on download and upload
  2. A temporary backup copy of the playlist is uploaded when doing same-playlist upload, and then deleted only if the same-playlist upload succeeds

I just wound up doing more callbacks

Most of the enhancements needed procedural (aka. synchronous) processing. “Don’t do the following step, and don’t accept user input, until the current step finishes ok.” I looked for something in ReactiveX’s JavaScript implementation to do this (RXJS), but did not find one. Perhaps JavaScript’s await would have done it, but I realized that I could:

  • make steps run in series using the usual approach – callbacks
  • prevent user input with something I already had – the loading spinner

So I proceeded with additional layers of callbacks and moved my command that closes the loading spinner to the bottom layer.

What I mean by a callback is a procedure that is called after the Observable, which is asynchronous, returns a value. In this example deletePlaylist “calls back” to getPlaylists. getPlaylists does not run until deletePlaylist returns a value:


this.spotSvc.deletePlaylist(b_plId,accessToken).subscribe(()=>this.getPlaylists(userId, userCountry, accessToken));

Transaction integrity

We do not have ACID transaction integrity

Shufflizer is built on the Spotify Web API. This API does not provide ACID transaction integrity. If the user’s computer crashes in the middle of an upload, or if the user simply shuts the window in the middle of an upload, the uploaded playlist will be incomplete. If the user has two sessions going (ie. two separate windows on the same device or perhaps on different devices) and is making changes to playlists in each, it is possible that uploading could lose or duplicate songs.

When uploading to a new playlist these concerns are not a big deal, but Shufflizer’s default is to upload to the same playlist. Plus Shufflizer is meant for big playlists. The bigger the playlist the bigger the bummer if it gets ruined. (It is possible to enlist the help of Spotify technical support personnel to restore a playlist to a prior state, but obviously this is an undesirable last resort.)

Here are some things that Shufflizer could do to reduce risk

Playlist initial download:
  • After downloading a playlist for edit, confirm that the count of songs reported by Spotify agrees with the count of songs downloaded.

Same-playlist upload:
  1. first upload as a new playlist, creating a temporary backup copy
  2. then do the normal upload, rewriting the original playlist
  3. now confirm that the count of songs reported by Spotify agrees with the count of songs uploaded
  4. if all is well, delete the new playlist (the temporary backup copy)

With these measures in place, if something goes wrong the user will wind up with two versions of the playlist. Either the original playlist will be good or the backup version will be good, or even both could be good depending on the nature of the outage. It’s unlikely that both will be bad.

Why not just make Shufflizer always upload to a new playlist? Followers and clutter. Same-playlist upload retains a playlist’s followers. Same-playlist upload avoids the clutter of a great many similar playlists that would result from frequent use of Shufflizer.

ReactiveX Observables

I will begin working on these enhancements. I tagged this as a TypeScript and Angular blog entry because I think this will take me a bit deeper into ReactiveX techniques. Because I am working in Angular, all of the Spotify API REST interaction is accomplished with ReactiveX Observables.