Saturday, July 15, 2023

Sidechain compression with Cakewalk

I use the Cakewalk DAW (Digital Audio Workstation) for my musical "experiments". For one composition recently, I wanted to have a "cheesy" DJ intro and a "You've been listening to..." outro. Both of these voice parts would be over the playing song, so I needed to the track itself to "quiet down" when a voice part was active. 

I thought about using volume automation, but that's clumsy and the song itself has quite a few tracks. So it became obvious that using side chain compression was going to be the best approach.

So I've got n tracks that should lower in volume (get compressed) when a voice track is active. It's actually easy to do in Cakewalk once you know how!

First, create a new stereo bus with a compressor in the fx bin (I used the standard Sonitus compressor), and send it out to the master bus. I called it sidechain (perhaps because I lack imagination 😄).

Next, ensure that all tracks and other buses that you want to be compressed are routed through the new sidechain bus. Here's an image of bus to bus, the "Rhythm" and "Bass" buses routed to "sidechain":

Here's an image for some tracks, some of which go direct to the sidechain bus, others routed through intermediate buses - "solo break" goes direct, "Rhythm-R" goes via the "Rhythm" bus, which then goes to the "sidechain" bus: 


The key to making it work is making the the voice track an input to the compressor on the stereo "sidechain" bus. Cakewalk exposes the sidechain input of the compressor as a "send". So if I click on the "Send" plus sign in the voice track, and select the compressor sidechain input menu item, this sets up that association.



As you can see, the voice track goes straight to the master bus. Finally, a few tweaks of the compressor to change the threshold, attack and release times, ratio and knee, and you're done:


There is another way to add a compressor to the bus, without using an existing VST, and it may give more pleasing results depending on your circumstances. The Pro channel 'rack' associated with all tracks and buses allows the addition of a PC4K-S-Type compressor, which has a side chain enable switch; see image below, you can enable that compressor and send the controlling track to its input.





Tuesday, October 4, 2022

Rock Dog: a JUCE multi faceted VST3 plugin

I have been using JUCE  for a while now, and have built a few plugins, including a "multi faceted" one (this post) and a DSP impulse response processing one, which is not yet released.

Rock Dog I did have as the subject of a Kickstarter campaign, which unfortunately failed to raise the funds I wanted to help improve it further -- I needed some financial injection to allow me to start modelling physical (non linear response) hardware (still open to funding of course!).  

The original Kickstarter campaign video is here.

With Rock Dog I tried to make it a more interesting plugin, by including features I didn't see often discussed in JUCE forums, including:

  • Providing a range of features and ensuring that soft real time DSP requirements were met
  • UI themes and run time switching between them
  • Saving and loading named presets based on current plugin state
  • Multiple switchable distortion fx
  • Serially chained reverb (if activated in the plugin)
  • Combine the use of juce::dsp modules as well as custom algorithm implementations
  • Reading/Writing to the file system in a system independent manner
  • Use of "space saving" context menus
I hadn't used C++ for quite some time (JUCE is only C++) so that took a while to reacquaint myself with, but it wasn't too tortuous. As a committed amateur musician, using the Cakewalk DAW, I have found it quite pleasing to use my own plugins within the context of a DAW.

The only thing I have not managed to do yet is build a MacOS version - when I get around to uploading the project into my public github repo then I'll have a crack at a github action for that. There is a Windows version available.

And to finish, some screenshots.

Standard theme plugin:


 

















And with a different theme activated:




















Loading a preset you'd previously saved:



















Changing a loaded distortion effect:




Saturday, May 21, 2022

atan mini processor

 void AtanMiniProcessor::processBlock(juce::AudioBuffer<float>& buffer, int inputChannels, int outputChannels, ProcessParameters& p) {  
   ScopedNoDenormals noDenormals;  
   for (auto i = inputChannels; i < outputChannels; ++i)  
     buffer.clear(i, 0, buffer.getNumSamples());  
   for (int channel = 0; channel < inputChannels; ++channel) {  
     auto* channelData = buffer.getWritePointer(channel);  
     for (int sample = 0; sample < buffer.getNumSamples(); sample++) {  
       float cleanSig = *channelData;  
       *channelData *= p.drive * p.range;  
       *channelData = (((((2.0f / float_Pi) * atan(*channelData)) * p.blend) + (cleanSig * (1.0f - p.blend))) / 2) * p.volume;  
       channelData++;  
     }  
   }  
 }  

Saturday, April 24, 2021

The (garden) bed of Theseus

I suppose it's not even random, just contextual. 

We have some raised garden beds, notionally described as chattels GB-1 and GB-2. GB-2 has been built to a less than desirable standard, with the original builder not bothering to line the interior with polythene or other suitable barrier material to avoid internal "bed rot".

As some of the panels were rotted through and become friable, I had occasion to break out some tools, old fence palings and patchwork fix the bed, as shown in the picture. It's not a stunningly professional job, but it does the trick and in reality the vegetables aren't going to care.



And, as I sawed and hammered away, the philosophical condundrum that is The Ship Of Theseus sprang to mind. Has GB-2 retained its identity?

In terms of chattels, utility, occupied dimensions, GB-2 is in all respects unchanged at the macro level. However, it looks different, weighs slightly more, has more nails, screws, so therefore is technically a different object.

Has GB-2 retained its identity? Yes, with four dimensional theory applied. But in all senses practical, not really. I find much of the issue to be confounded by the application of frames of reference that are by their very nature incomplete, unsuitable or so broadly swept as to obscure rather than illuminate. Once we lapse into the truly metaphysical, I fear poor GB-2 may be consigned almost to a non existence.

Even every day chores may bring philosophical wonder. If Bertrand Russell could obsess over the place of a table in philosophy, nature, mind and others, then GB-2 has as much right to be considered.

Saturday, January 23, 2021

Brevity or obfuscation in c#

Having a look at the Blazorise github source, I encountered this method:

     protected override string FormatValueAsString( IReadOnlyList<TValue> value )  
     {  
       if ( value == null || value.Count == 0 )  
         return string.Empty;  
       if ( Multiple )  
       {  
         return string.Empty;  
       }  
       else  
       {  
         if ( value[0] == null )  
           return string.Empty;  
         return value[0].ToString();  
       }  
     }  
Doesn't that seem like a lot of code for some simple behaviour ? I've seen development styles like this before, often with the argument that it's easy to read. I suppose that is true. 

But it also misses the point -- you are not using the c# language and libraries to their full extent...this does:
     protected override string FormatValueAsString(IReadOnlyList<TValue> values)  {  
          var result = values?.FirstOrDefault()?.ToString();  
          return result == null || Multiple ? string.Empty : result;  
     }  
It's shorter, loses no meaning, uses LINQ acceptably and has one return statement instead of four. I also took the liberty of removing the strange spacing around the method argument and naming it more appropriately. And using the K&R statement styling. 

However, at the expense of some readability, but with a better performance profile, you could write:
     protected override string FormatValueAsString(IReadOnlyList<TValue> values)    
         =>  Multiple ? string.Empty : values?.FirstOrDefault()?.ToString() ?? string.Empty;  

If I was being picky:
  • I'd have a left a QA comment asking if the method name was really appropriate -- it's borderline IMO. 
  • The shorter implementations allow for the possibility that the ToString() method of TValue might return null (a defect in that case) - you can't discount that as a possibility, and it would possibly break the caller of the method
  • An engineering approach might include a pre-condition that 'values' cannot be null
  • A post condition would be that the return result is always not null
  • The use of 'Multiple' looks a little forced - without delving further, could this test even be avoided altogether and be outside?
I'm very much a fan of internal as well as external quality. 

Monday, September 21, 2020

Badass Bass II Bridge

I've got a well set up Fender Jazz Bass (US); nice low action, totally true neck - in short, a veritable slap and pop monster. But I always thought the stock Fender bridges were a bit cheap and flimsy looking, and not fit for the high quality instruments that we know Fenders are.

So I recently had a Badass Bass II bridge fitted, by Weta Guitars. And what did I expect? Many pundits suggest longer sustain, "efficient sound coupling" (whatever that is supposed to be) and improved balance. It's a drop in replacement, so I suppose you could fit one yourself, but I didn't want to take the risk.

About a year in, I must admit I'm not noticing a huge difference. You feel the additional heft at the bridge end of the bass of course, but only for a bit as you acclimatise. Where it does work for me is appearance - it just looks the part. Perhaps this is a case of form over function.



 

Thursday, July 30, 2020

Azure Cosmos DB - Partition keys


General
Just come out of a gig where Cosmos DB was the persistence engine of choice, using the SQL API. If you don't know much about Cosmos, see here.

Partition keys
One of the architectural decisions made by Microsoft confuses me. They have a notion of a logical partition, which can have a maximum size of 10GB. It is expected that your Cosmos DB usage, assuming non trivial, has to arrange for objects/documents to be partitioned across multiple logical containers.

Therein lies the rub. Cosmos DB won't do any of this partitioning for you, it is entirely up to you to arrive at some satisfactory scheme, which involves your implementation generating a partition key that potentially reflects some guidelines that Microsoft share.

For the domain I was in, a number of external organisations submitted many documents to the client, and these submissions would be distributed over a number of years, and easily exceed the 10GB logical partition limit. One of the key guidelines from Microsoft is to avoid 'hot partitions' - that is, a partition that gets used heavily to the exclusion of almost any other. This has quite serious performance implications.

So, given we don't want hot partitions, that rules out using a partition key that uses the year for any submission, as there is a strong locality of reference in play - that is, the external organisations tend to focus on the most recent temporal activity and hence Cosmos action would tend to focus on one partition for a year!

In the end, knowing that each external organisation had a unique 'organisation number', and using a sequence/modulo scheme, an effective partitioning approach was implemented. It's operation is simple, and works as below:

  • An external organisation submits a JSON document via a REST API
  • On receipt, a Cosmos stored document is found or created based on the organisation number
  • This document has a sequence number and a modulo. We calculate sequence mod modulo.
  • We increment the sequence, and save the organisation specific document
  • We now have a pro forma partition key, for organisation 7633, we might have: 7633-1, 7633-2 and so on

What this provides is for bounded yet not meaningfully limited partition counts. By judicious selection of modulo (in the case of my client, this was an integer), scalability is "assured". 

Wednesday, January 16, 2019

Angular versus Blazor - working SPA examples compared

Overview

Most of us have observed the ascent of Angular (in all its versions) over the last few years. I enjoy working with Angular, but it does feel on occasion that it complicates matters for little gain. Sure, compared to KnockoutJS and ExtJS it works very well, but something always nags a little.

I have been following the evolution of Blazor with interest. I won't describe it in detail, but its use of WASM, Mono and the ability to create an SPA with (mostly just) c#, is appealing. All the usual arguments in favour of such an approach apply. It's only an alpha framework, but I thought it might instructive/amusing to attempt to re-create an SPA I have using just Blazor, and compare the results.

The SPA

I have more than a passing interest in esoteric languages, and wrote one myself (WARP) for a laugh.

The SPA has these features:

  • Routing 
  • Use of MEF discovered language interpreters via a trivial.NET Core API
  • The ability to switch between languages 
  • Enter source code for a particular language that is dispatched to the API for execution
  • Respond to 'interrupts' received from the API, which signal that a user is required to enter input of some kind
  • Display output as it is received from the API execution of the source code supplied
  • The ability cancel execution if a program is slow (esoteric languages tend to be interpreted and seemingly simple tasks can be glacial in terms of execution speed)
  • Display a summary of the language as simple text
  • Provide an off site link to examine the language in greater detail
There is a project on GitHub with full source. Note that web sockets are used to communicate between client and server. Notes on building and running are at the end of this post.

Angular SPA
Angular 7 is used as the base framework,  using  the angular2-websocket module, which still seems the best for web sockets. It's all hosted in VS 2017, and uses ng build (not webpack or similar). It's reasonably straightforward.

Blazor SPA
Built with Blazor.Browser 0.7.0 (client) and Blazor.Server 0.7.0 (server). Given the 3 models of Blazor deployment, the one chosen is an ASP.NET Core model.


Screen grabs
A couple of screen grabs, noting that I did not attempt to make the UI's identical. The images show the execution of a prime number 'finder' written in WARP, both given a start point of 199.

Angular


Blazor



Differences
There are some subtle differences, aside from the not so subtle use of c# and Razor as opposed to Typescript and HTML.

Binding
The source code text area (see screen grabs below) should be an 'instant' binding, that is, any key press should affect the state of the Run button. If you have not entered source code, you can't run obviously, but as soon as you enter one character, that is possibly a viable esoteric program.

In Angular, using a plain form, it's easy enough, using ngModel, and required and disabled attributes:

 <div class="row">  
      <div class="col-12">  
           <textarea cols="80" rows="10"   
             [(ngModel)]="sourceCode" style="min-width: 100%;"   
             name="sourceCode" required [disabled]="running">  
           </textarea>  
         </div>  
 </div>  
 <p></p>  
 <div class="row">  
    <div class="col-12">  
      <button type="submit" class="btn btn-primary"   
         [disabled]="!executionForm.form.valid || running">  
            Run  
       </button>&nbsp;    
       <button type="button" class="btn btn-danger"   
           (click)="cancel()" [disabled]="!running">  
            Cancel  
        </button>    
      </div>  
  </div>   

It was almost as straightforward in Blazor, but with a quirk:

 <div class="row">  
     <div class="col-12">  
         <textarea cols="80" rows="10" bind="@SourceCode" style="min-width: 100%;"  
              name="sourceCode" required   
              onkeyup="this.dispatchEvent(new Event('change', { 'bubbles': true }));">   
         </textarea>  
     </div>  
 </div>  
 <p></p>  
 <div class="row">  
     <div class="col-12">  
         <button type="submit" class="btn btn-primary" onclick="@Run"   
               disabled='@(NotRunnable || Running)'>  
             Run  
         </button>&nbsp;  
         <button type="button" class="btn btn-danger"   
             disabled="@(Running == false)" onclick="@StopExecution">  
             Cancel  
         </button>  
     </div>  
 </div>  

Now the disabled attributes behaviour is fine, just a bit of Razor. But the part I didn't like or want is the addition of an onkeyup handler on the textarea. However, without this, the source code only updates when the textarea loses focus, which is not the behaviour that the Angular SPA has (and is the correct behaviour).

Attributes
If you are not used to Razor the attribute usage looks a little strange. It's also not semi abstracted in the way that Angular is (compare 'click' with 'onclick'). But I can't say that it bothers me that much.

Sharing code
These SPA's are very simple, and really only have one shared type across them, an object called LanguageMetadata (which is a simple data object that holds an example of a language that is supported by the ELTB service/API). With Blazor, I can share that between client and server, by having a separate class library project referenced by both of them. However, with Angular, I have to define an interface (well, I don't, but it is nicer to do so) - so I haven't shared anything, I have copied something.

For these SPA's, it's not a big deal. But for more complex projects (and I've worked on some) the possible sharing approach of Blazor could be exceptionally useful.

Http client
Angular makes a lot of noise about it's use of Rx and Observables - and yes, it is very appealing (just came off a project where Rx.NET was used heavily). Blazor can afford to take a different approach, using a 'standard' HttpClient with an async call.

It certainly has a more natural look and feel (excuse the hard coded URL's - it's just an example after all!):

Angular

  supportedLanguages() {  
   return this  
    ._http  
    .get(this.formUrl(false))  
    .pipe(map((data: any[]) => {  
     return <LanguageDescription[]>data  
    }));  
  }  

Blazor
 protected override async Task OnInitAsync() {  
     LanguageMetadata.All =   
        await httpClient.GetJsonAsync<List<LanguageMetadata>>   
            ("http://localhost:55444/api/EsotericLanguage/SupportedLanguages");  
 }  

When I look at it, the Ng approach with pipe and map just looks a little fussy.

Web sockets
Not all of the .Net API's you might want exist in Mono. One such is the web sockets API, which underpins the implementation of both versions of the SPA. I couldn't use something like SignalR (it is supported by Blazor), as I have distinct request/response semantics when user input is required for an executing piece of esoterica.

My understanding is that support is coming, but the Javascript interop of Blazor allowed me to solve the issue relatively quickly. Unfortunately, it meant writing some raw JS to do so, as below:

 window.websocketInterop = {  
     socket: null,  
     connect: function (url, helper, msg) {  
         console.log("Connecting");  
         socket = new WebSocket(url);  
         socket.onopen = function (evt) {  
             msg && socket.send(msg);  
         }  
         socket.onmessage = function (event) {  
             console.debug("WebSocket message received:", event);  
             helper.invokeMethod("OnMessage", event.data);  
         };  
         socket.onclose = function (evt) {  
             console.log("Socket closed. Notify this..");  
             helper.invokeMethod("OnChannelClose");  
         }  
         console.log("Connected and ready....");  
     },  
     send: function (msg) {  
         console.log("Sending:" + msg);  
         socket.send(msg);  
     },  
     close: function () {  
         console.log("Closing socket on demand");  
         socket && socket.close();  
     }  
 };  

(This is not anywhere near a production implementation).

The interop parts are seen in the cshtml file, InterpreterContent.cshmtl. For example, when the esoteric source code is sent (after pressing the Run button), it invokes the JS function 'webSocketInterop.connect' defined previously, sending it a url to connect to, a DotNetRefObject and the actual source code as the first message to dispatch on the web socket:

 async Task Run() {  
         Output = string.Empty;  
         Running = true;  
         await JSRuntime.Current.InvokeAsync<object>  
                ("websocketInterop.connect",   
                InterpreterServiceUrl,   
                new DotNetObjectRef(this),   
                $"|{Language}|{SourceCode}");  
         StateHasChanged();  
 }  

The DotNetRefObject encapsulates 'this' for this implementation, and allows the JS to call back into the 'this' instance. For example, when the socket is closed by the interpreter service (as it does when execution has completed),  the JS calls
 
             helper.invokeMethod("OnChannelClose");  
 
which is defined in the cshtml file as:

 
     [JSInvokable]  
     public void OnChannelClose() {  
         Running = false;  
         StateHasChanged();  
 }  

with JSInvokable making it available to JS, and when called, sets Running to false, which will update the UI such that the Run button is now enabled, and the Cancel button disabled. Note the use of StateHasChanged, which propagates state change notification.

It's a double edged sword - the interop is well done, simple, works. But it should be a feature that is used infrequently.

Source code organization
One of the frequent criticisms of the Razor world is that it lets you mix in code and HTML freely, giving it a somewhat 'classic ASP' feel if one is not careful. The SPA Blazor implementation is an example of that, I haven't attempted to make it modular or separate it out particularly.

But for established Razor shops, with good or reasonable practice, this is easy to address.

Less code
I definitely ended up with less code in the Blazor version. It's much easier to understand, builds quicker and means my c# knowledge can be used directly in the main. 

Unit testing
I didn't implement any unit tests for the purpose of this exercise, it's not destined for production after all. Angular et al have good tools in this area, Jasmine, Karma and so on. But Blazor allows for componentization which will support unit tests easily enough. Probably a draw in this regard.

Summary
Blazor is indeed an interesting concept; currently incomplete, not ready for production and a little slow on initial use. But the promise is there, but I suppose we'll have to wait and see if MS continue with it, because as many others have noted, this is the sort of project that can arrive with a muted fanfare, gain some traction and then disappear.

Being standards based helps its case, as the Silverlight debacle might illustrate. The considerable ecosystems of Angular, React and others might keep it at bay for a while if it makes it to full production use, but I think there is room for it.

Building and running from GitHub If you fancy building and running the examples, once cloned or downloaded from GitHub, and built - you then have to unzip the file API\ELTB-Services\interpreters-netcoreapp2.1.zip and move the assemblies therein to API\ELTB-Services\bin\Debug\netcoreapp2.1.

This is because the interpreter service relies on these to exist and be discoverable by MEF, and I didn't go to the trouble of fully integrating a build.

Thursday, April 27, 2017

Auto generating asp.net core OData v4 controllers from an entity framework code first model

Even though I am no great fan of OData (leaky abstractions and all), I found myself in the position of thinking how I could make it work with asp.net core and entity framework core (there are many posts around that say it cannot be done).

The project that eventuated from these thoughts is on Github.

I fell back on T4 again, as especially for REST API's created with OData in the asp.net world, you'll likely have an entity framework code first model. And writing controllers and repositories by hand for such a well documented protocol as OData seems rather tedious - and ripe for automation.

In summary, interrogating a DbContext, any exposed DbSet<> objects would represent resource collections; from there, the entity type of the DbSet<> has properties that may or may not be exposed as parts of the API, as well as navigation properties that may also be exposed.

The project as it stands now uses:
  • Microsoft.AspNetCore.OData.vNext 6.0.2-alpha-rtm as the OData framework
  • Visual Studio 2017
  • EntityFrameworkCore 1.1.1
  • Asp.net core 1.1.1
  • Asp.net core Mvc 1.1.2 
And generates:
  • OData v4 controllers for each resource collection
  • Repositories for each entity type that is exposed 
  • Proxies for each repository, that intercept pre and post events for CUD actions, and allow for optional delegation to user specified intervention proxies
Attributes are also implemented that allow the generation process to be modified, examples:

Attribute Semantics
ApiExclusion Exclude a DbSet<> from the API
ApiResourceCollection Supply a specific name to a ResourceCollection
ApiExposedResourceProperty Expose a specific entity property as a resource property
ApiNullifyOnCreate Request that property be nullified when the enclosing object is being created

From the example EF project, below is a DbContext marked up with attributes as desired by the author, excluding a couple of resource collections and renaming one:

 public class CompanyContext : DbContext, ICompanyContext {  
   
   public CompanyContext(DbContextOptions<CompanyContext> options) : base(options) {  
   }  
   
   public DbSet<Product> Products { get; set; }  
   
   [ApiExclusion]  
   public DbSet<Campaign> Campaigns { get; set; }  
   
   public DbSet<Supplier> Suppliers { get; set; }  
   
   [ApiResourceCollection(Name = "Clients")]  
   public DbSet<Customer> Customers { get; set; }  
   
   public DbSet<Order> Orders { get; set; }  
   
   [ApiExclusion]  
   public DbSet<OrderLine> OrderLines { get; set; }  
   
 }  

And likewise, for the Customer entity, some markup that exposes some properties as first class 'path' citizens of an API, and ensures that one must be null when an object of type customer is being created via the API:

 public class Customer {  
   
     public Customer() {  
       Orders = new List<Order>();  
     }  
   
     public int CustomerId { get; set; }  
   
     [ApiExposedResourceProperty]  
     [MaxLength(128)]  
     public string Name { get; set; }  
   
     [ApiNullifyOnCreate]  
     [ApiExposedResourceProperty]  
     public virtual ICollection<Order> Orders { get; set; }  
   
 }  

The OData controller generated for the Customers resource collection (which has been renamed 'Clients' by attribute usage) is:

 [EnableQuery(Order = (int)AllowedQueryOptions.All)]  
 [ODataRoute("Clients")]  
 public class ClientsController : BaseController<ICompanyContext, EF.Example.Customer, System.Int32, IBaseRepository<ICompanyContext, EF.Example.Customer, System.Int32>> {  
   
   public ClientsController(IBaseRepository<ICompanyContext, EF.Example.Customer, System.Int32> repo) : base(repo) {  
   }  
   
   [HttpGet("({key})/Name")]  
   public async Task<IActionResult> GetName(System.Int32 key) {  
     var entity = await Repository.FindAsync(key);  
     return entity == null ? (IActionResult)NotFound() : new ObjectResult(entity.Name);  
   }  
   
   [HttpGet("({key})/Orders")]  
   public async Task<IActionResult> GetOrders(System.Int32 key) {  
     var entity = await Repository.FindAsync(key, "Orders");  
     return entity == null ? (IActionResult)NotFound() : new ObjectResult(entity.Orders);  
   }  
   
 }  

The included BaseController performs most of the basic actions required. And then there is the repository generated, with again, a base type doing most of the useful work:

 public partial class ClientsRepository : BaseRepository<ICompanyContext, EF.Example.Customer, System.Int32>, IBaseRepository<ICompanyContext, EF.Example.Customer, System.Int32> {  
   
     public ClientsRepository(ICompanyContext ctx, IProxy<ICompanyContext, EF.Example.Customer> proxy = null) : base(ctx, proxy) {  
     }  
   
     protected override async Task<EF.Example.Customer> GetAsync(IQueryable<EF.Example.Customer> query, System.Int32 key) {  
       return await query.FirstOrDefaultAsync(obj => obj.CustomerId == key);  
     }  
   
     protected override DbSet<EF.Example.Customer> Set { get { return Context.Customers; } }  
   
     public override System.Int32 GetKeyFromEntity(EF.Example.Customer e) {  
       return e.CustomerId;  
     }  
   
   }  

Wednesday, April 19, 2017

Text template engine for generating content

I implemented this a while ago for the startup, been meaning to publish it to github, and now have - here. It was used to support a multitude of text templates that had to be transformed to become part of email message content - and a way to do that which was flexible was required.

The idea is trivial, treat a stream of bytes/characters as containing substitution tokens and rewrite those tokens using a supplied context. Also includes iteration, expression support, context switching and a few other minor aspects.

It's a VS 2017, C# solution, targeting .netcoreapp 1.1 and .net 4.6+.

Once set up, transformation is ultra trivial, assuming a text template and some domain object being supplied to the pro forma method shown below:

        private string GenerateMessage<TObject>(string doc, TObject ctx) {
            ParseResult res = Parser.Parse(doc);
            EvaluationContext ec = EvaluationContext.From(ctx);
            var ctx = res.Execute(ExecutionContext.Build(ec));
            return ctx.context.ToString();
        }




Tuesday, January 3, 2017

REST API with a legacy database (no foreign keys!) - a T4 and mini DSL solution

Overview
Encountered yet again; a legacy database, with no foreign keys, hundreds of tables, that formed the backbone of a REST API (CRUD style), supporting expansions and the like.

It wasn't that there were not identifiable relationships between objects, just the the way the database was generated meant that they were not captured in the database schema. But expansions had to be supported in an OData like fashion. So, assuming you had a resource collection called Blogs, and each Blog object had sub resources of Author and Readers, you should be able to issue a request like the following for a Blog with an id of 17:

http://..../api/Blogs/17?expand=Author,Readers

and expect a response to include expansions for Author and Readers.

That's easy then. Just use entity framework mapping/fluent API to configure an independent association with any referenced objects. Well, that can work and often does. But it does not cope well when some selected OData abstractions are included in the mix - and I was using these to expose some required filtering capabilities to consumers of the REST API. Simply put, when you were creating an ODataQueryContext using the ODataConventionModelBuilder type, independent associations cause it to implode in a most unpleasant fashion.

So, if I can't use independent associations, and each resource may have 1..n associations which are realised using joins, I can:
  • Write a mega query that always returns everything for a resource, all expansions included
  • Write specific queries by hand for performance reasons, as the need arises
  • Generate code that map expansions to specific implementations
Writing by hand was going to be tedious, especially as some of the resources involved had 4 or more expansions.

When I thought about the possible expansions for a resource, and how they can be associated to that resource, using non FK joins, it became apparent that I was dealing with a power set of possibilities.

For the Blogs example, with expansions of Author and Readers, I'd have the power set:

{ {}, {Author}, {Readers} {Author, Readers} }

So the idea that formed was:
  • Use a mini DSL to capture, for a resource, its base database query, and how to provision any expansions
  • Process that DSL to generate pro forma implementations
  • Use a T4 text template to generate C# code
I solved this in one way for a client, but then completely rewrote it at home because I thought it may be of use generally. I then extended that with a T4 template that generates an MVC 6 REST API...meaning all the common patterns that you typically see in a REST API were represented.

The actual VS 2015 C# solution is on Github. The implementation itself is a bit more sophisticated than described here, for reasons of brevity.

DSL 
The purpose of the DSL input file is to describe resources, their associated database base query, and any expansions and how they are realised. There are two formats supported - plain text and JSON.

An elided text file example for Blogs is:

1:  tag=Blogs  
2:  singular-tag=Blog  
3:  model=Blog  
4:  # API usage  
5:  restResourceIdProperty=BlogId  
6:  restResourceIdPropertyType=int  
7:  #  
8:  baseQuery=  
9:  (await ctx.Blogs  
10:  .AsNoTracking()  
11:  .Where(expr)  
12:  .Select(b => new { Blog = b })  
13:  {joins}  
14:  {extraWhere}  
15:  .OrderBy(a => a.Blog.BlogId)  
16:  .Skip(skip)   
17:  .Take(top)  
18:  .ToListAsync())  
19:  #  
20:  expansion=Posts  
21:  IEnumerable<Post>  
22:  .GroupJoin(ctx.Posts, a => a.Blog.NonKeyField, post => post.NonKeyField, {selector})  
23:  #   
24:  expansion=Readers  
25:  IEnumerable<Party>  
26:  .GroupJoin(ctx.Parties.Where(r => r.Disposition == "reader"),   
27:     a => a.Blog.NonKeyField, party => party.NonKeyField, {selector})  
28:  #   
29:  expansion=Author  
30:  Party  
31:  .Join(ctx.Parties, a => a.Blog.NonKeyField, party => party.NonKeyField, {selector})  
32:  .Where(p => p.Author.Disposition == "author")  

Relevant lines:

  • Line 1: starts a resource definition
  • Lines 5-6: allow this DSL instance to be used to generate a REST API
  • Lines 8-18: The base query to find blogs, along with specific markup that will be changed the DSL processor (e.g. {selector}, {joins} and so on)
  • Lines 24-27: A definition of an expansion - linking a reader to a blog if a Party entity has a disposition of "reader" and the column "NonKeyField" of a Blog object matches the same column in a Party object. The expansion results in an IEnumerable<Party> object.
  • Lines 29-32: an Author expansion, this time (line 32) including a predicate to apply

Example class
After running the T4 template over the DSL file, a c# file is produced that includes a number of classes that implement the intent of the DSL instance.

The Blogs class (as generated) starts like this:

1:  public partial class BlogsQueryHandler : BaseQueryHandling {   
2:    
3:    protected override string TagName { get; } = "Blogs";  
4:    
5:    public const string ExpandPosts = "Posts";  
6:    public const string ExpandAuthor = "Author";  
7:    public const string ExpandReaders = "Readers";  
8:      
9:    public override IEnumerable<string> SupportedExpansions   
10:          { get; } = new [] { "Posts", "Author", "Readers"};  
11:    

Points:

  • Line 1: The Blogs query handler class subtypes a base type generated in the T4 that provides some common to be inherited behaviour for all generated classes
  • Lines 5-7: All the expansions defined in the DSL instance are exposed
  • Lines 9-10: An enumerable of all supported expansions is likewise created

Example method
Harking back to the power set comment, a method is generated for each of the sub sets of the power set that represents the query necessary to realize the intent of the expansion (or lack thereof).

Part of pre-T4 activity generates queries for each sub set using the content of the DSL instance. Methods are named accordingly (there are a number of configuration options in the T4 file, I'm showing the default options at work).

As below, the method name generated in T4 for getting blogs with the Author expansion applied is Get_Blogs_Author (and similarly, Get_Blogs, Get_Blogs_Readers, Get_Blogs_Author_Readers).


1:  private async Task<IEnumerable<CompositeBlog>>   
2:    Get_Blogs_Author(  
3:     BloggingContext ctx,   
4:     Expression<Func<Blog, bool>> expr,   
5:     int top,   
6:     int skip) {   
7:      return   
8:          (await ctx.Blogs  
9:          .AsNoTracking()  
10:          .Where(expr)  
11:          .Select(obj => new { Blog = obj })  
12:          .Join(ctx.Parties,   
13:              a => a.Blog.NonKeyField,   
14:              party => party.NonKeyField,   
15:              (a, author) => new { a.Blog, Author = author})  
16:          .Where(p => p.Author.Disposition == "author")  
17:          .OrderBy(a => a.Blog.BlogId)  
18:          .Skip(skip)  
19:          .Take(top)  
20:          .ToListAsync())  
21:          .Select(a => CompositeBlog.Accept(a.Blog, author: a.Author));  
22:    }  

Some comments:

  • Line 1: Declared privately as more general methods will use the implementation
  • Line 3: The EF context type is part of T4 options configuration
  • Line 4: Any 'root' resource expression to be applied
  • Lines 5-6: Any paging options supplied externally
  • Lines 7-25: The generated query, returning an enumerable of CompositeBlog, a class generated by DSL processing, that can hold the results of expansions and the root object

Generated 'top level' methods
As the generated 'expanded' methods are declared privately, I expose 'top level' methods. This makes the use of the generated class easier, since you pass in the expansions to use, and reflection is used to locate the appropriate implementation to invoke.

Two variants are generated per resource class - one for a collection of resources, one for a specific resource. The 'collection' style entry point is:

1:  public async Task<IEnumerable<CompositeBlog>>  
2:            GetBlogsWithExpansion(  
3:               BloggingContext ctx,   
4:               Expression<Func<Blog, bool>> expr = null,   
5:               int top = 10,   
6:               int skip = 0,   
7:               IEnumerable<string> expansions = null) {   
8:    return await GetMultipleObjectsWithExpansion<CompositeBlog, Blog>  
9:                 (ctx, expr, expansions, top, skip);  
10:  }  
11:    
12:    

Comments:

  • Lines 3-7: The EF context to use, along with a base expression (expr) and paging requirements and any expansions to be applied
  • Lines 8-9: Call a method defined in the BaseQueryHandler generated class to find the correct implementation and execute

Example use
Imagine this closely connected to a REST API surface (there is a T4 template that can do this, that integrates with Swashbuckle as well). The paging, expansions and filter (expression)  requirements will passed in with a request from an API consumer, and after being sanitised, will be in turn given to a generated query handler class. So the example given is what one might call contrived.

A concrete test example appears below:

1:  using (BloggingContext ctx = new BloggingContext()) {  
2:   var handler = new BlogsQueryHandler();  
3:   var result = await handler.GetBlogsWithExpansion(  
4:             ctx,   
5:             b => b.BlogId > 100,   
6:             10,   
7:             10,   
8:             BlogsQueryHandler.ExpandAuthor,   
9:             BlogsQueryHandler.ExpandReaders);  
10:   // .. Do something with the result  
11:  }  

Comments:

  • Line 1: Create a context to use
  • Line 2: Create an instance of the generated class
  • Line 3: Call the collection entry point of the generated class
  • Lines 4-7: Supply the EF context, an expression and top and skip specifications 
  • Lines 8-9: Add in some expansions

Customisation
The T4 template has a 'header' section that allows for various options to be changed. I won't go into detail, but it is possible to change the base namespace for generated classes, the EF context type needs to be correct, whether a JSON or text format DSL file is being used, whether the 'advanced' DSL form is used - and so on. The GitHub page supplies more detail.


 // ****** Options for generation ******   
 // Namespaces to include (for EF model and so on)  
 var includeNamespaces = new List<string> { "EF.Model" };  
 // The type of the EF context  
 var contextType = "BloggingContext";   
 // Base namespace for all generated objects  
 var baseNamespace = "Complex.Omnibus.Autogenerated.ExpansionHandling";  
 // The DSL instance file extension of interest (txt or json)  
 var srcFormat = "json";  
 // True i the advanced form of a DSL instance template should be used  
 var useAdvancedFormDSL = true;  
 // Form the dsl instance file name to use  
 var dslFile = "dsl-instance" + (useAdvancedFormDSL ? "-advanced" : string.Empty) + ".";  
 // Default top if none supplied  
 var defaultTop = 10;  
 // Default skip if none supplied  
 var defaultSkip = 0;  
 // True if the expansions passed in shold be checked  
 var checkExpansions = true;  
 // If true, then expansions should be title cased e.g. posts should be Posts, readers should be Readers and so on  
 var expansionsAreTitleCased = true;  
 // ****** Options for generation ******   

Friday, October 21, 2016

Angular 2: Creating decorators for property interception

As part of 'polishing' the esoteric languages testbed Angular 2 SPA, I thought it might be useful to allow for storage of entered source code to be auto-magically persisted. This lead me on a small journey into the ng2 decorator mechanisms, which are surprisingly easy to implement and reminiscent of c# attributes, but without the static limitations.

.Net Core MVC hosted solution on GitHub. Node package source also on GitHub.

The essence of the idea was to be able to decorate a property of a type and have any setting of its value to be automatically persisted - along with a suitable getter implementation.

Sort of as shown below, meaning both the language and sourceCode properties should be persistent. The @LocalStorage decoration implies strongly that this persistence should be in HTML 5 local storage.

1:  export class ExecutionComponent {  
2:    @LocalStorage('ELTB') language: string;  
3:    @LocalStorage('ELTB') sourceCode: string;
4:    programOutput = '';  
5:    programInput = '';  
6:    running = false;   
7:    inputRequired = false;  
8:    
9:    constructor(private _esolangService: EsolangService) {  
10:      console.log('built EC');  
11:    }  
12:  }  

So, how do you achieve this? There are plenty of detailed articles around for how to implement a decorator (at the class, property etc level), so I'm not going to describe it in detail.

It's easier just to present the code below, which has these main points of interest (note that this is aggregated code for presentation purposes from the node package source for this project):

  • Lines 2-7: Define an interface that represents the 'shape' of an object that can act as an interceptor for property gets and sets
  • Lines 9-14: Another interface, that defines the contract for an options type; one that can be passed as part of the decorator if it is required to achieve more finely grained behaviour, supply a factory for creating DelegatedPropertyAction instances and so on
  • Lines 16-35: the local storage decorator function entry point, that can be called with a union of types; either a string or an object that implements the AccessorOptions interface
  • Lines 37-39: a decorator function entry point for allowing general property interception e.g. as in @PropertyInterceptor('{ storagePrefix: "_", createJsonOverride: false}). An example is show later on.
  • Lines 41-82: A function that returns a function that implements the general property interception behaviour, with its behaviour directed somewhat by an instance of  AccessorOptions
  • Lines 85-113: An implementation of a DelegatedPropertyAction that gets and sets based on local storage


1:    
2:  export interface DelegatedPropertyAction {  
3:    propertyKey: string;  
4:    storageKey: string;  
5:    get(): any;  
6:    set(newValue: any): any;  
7:  }  
8:    
9:  export interface AccessorOptions {  
10:    storagePrefix?: string;  
11:    factory?(propertyKey: string, storageKey: string): DelegatedPropertyAction;  
12:    preconditionsAssessor?(): boolean;  
13:    createToJsonOverride?: boolean;  
14:  }  
15:    
16:  export function LocalStorage(optionsOrPrefix: string | AccessorOptions) {  
17:    function ensureConfigured(opts: AccessorOptions): AccessorOptions {  
18:      opts.preconditionsAssessor =  
19:        opts.preconditionsAssessor ||  
20:        (() => window.localStorage && true);  
21:      opts.factory =  
22:        opts.factory ||  
23:        ((p, c) => new LocalStorageDelegatedPropertyAction(p, c));  
24:      return opts;  
25:    }  
26:    return AccessHandler(  
27:      ensureConfigured(  
28:        typeof optionsOrPrefix === "string" ?  
29:        <AccessorOptions>{  
30:          storagePrefix: optionsOrPrefix,  
31:          createToJsonOverride: true  
32:          }  
33:          : optionsOrPrefix  
34:      ));  
35:  }  
36:    
37:  export function PropertyInterceptor(options: AccessorOptions) {  
38:    return AccessHandler(options);  
39:  }  
40:    
41:  function AccessHandler(options: AccessorOptions) {  
42:    return (target: Object, key?: string): void => {  
43:    
44:      function makeKey(key: string) {  
45:        return (options.storagePrefix || '') + '/' + key;  
46:      }  
47:    
48:      if (!options.preconditionsAssessor || options.preconditionsAssessor()) {  
49:    
50:        let privateName = '$__' + key, storeKey = makeKey(key);  
51:    
52:        target[privateName] = options.factory(key, storeKey);  
53:    
54:        Object.defineProperty(target, key, {  
55:          get: function () {  
56:            return (<DelegatedPropertyAction>this[privateName]).get();  
57:          },  
58:          set: function (newVal: any) {  
59:            (<DelegatedPropertyAction>this[privateName]).set(newVal);  
60:          },  
61:          enumerable: true,  
62:          configurable: true  
63:        });  
64:    
65:        const notedKey = '_notedKeys', jsonOverride = 'toJSON';  
66:    
67:        target[notedKey] = target[notedKey] || [];  
68:        target[notedKey].push(key);  
69:    
70:        options.factory(notedKey, makeKey(notedKey)).set(target[notedKey]);  
71:    
72:        if (options.createToJsonOverride && !target.hasOwnProperty(jsonOverride)) {  
73:          target[jsonOverride] = function () {  
74:            let knownKeys = Array<string>(target[notedKey]);  
75:            let result = { _notedKeys: knownKeys };  
76:            knownKeys.forEach(x => result[x] = target[x]);  
77:            return result;  
78:          };  
79:        }  
80:      }  
81:    }  
82:  }  
83:    
84:    
85:  export class LocalStorageDelegatedPropertyAction implements DelegatedPropertyAction {  
86:    
87:    storageKey: string;  
88:    propertyKey: string;  
89:    private val: any;  
90:    
91:    constructor(propertyKey: string, canonicalKey: string) {  
92:      this.propertyKey = propertyKey;  
93:      this.storageKey = canonicalKey;  
94:      this.val = JSON.parse(this.read());  
95:    }  
96:    
97:    get(): any {  
98:      return this.val;  
99:    }  
100:    
101:    set(newValue: any) {  
102:      this.write(JSON.stringify(newValue));  
103:      this.val = newValue;  
104:    }  
105:    
106:    private read() {  
107:      return localStorage.getItem(this.storageKey) || null;  
108:    }  
109:    
110:    private write(val: any) {  
111:      localStorage.setItem(this.storageKey, val);  
112:    }  
113:  }  

So, a contrived re-writing of the very first example, which adds no real value, could be:

1:  @LocalStorage('ELTB') language: string;  
2:  @LocalStorage({   
3:     storagePrefix: 'ELTB',   
4:     factory: (p, c) =>   
5:       new LocalStorageDelegatedPropertyAction(p, c) })   
6:    sourceCode: string;  

The solution on GitHub is a trivial test one, an example from its use is below, showing local storage contents mirroring the page content:


Tuesday, July 19, 2016

Angular JS 2, RxJs, ASP.NET Core, .NETStandard, Typescript, Web sockets - new Github project

In essence
Having had my 'head down' in a rather pressing commercial engagement, I've had little time to experiment with some of the .NET and UI framework ecosystem changes that have been occurring.

So I decided to combine a whole truck load of them into one effort, creating an ASP.NET Core webapp esoteric language testbed (based on my esoteric interpreters GitHub project).

There are some screen shots at the end of this post showing an example in action. It's definitely a WIP, not quite ready to put on GitHub.

Implemented:
  • Communicate with a REST API to determine what languages are available for use (supported languages are determined using a simple plugin system written with the version of MEF 2)
  • Accept a language source program
  • Use web sockets to request that the web app start remote interpretation, and allow client side 'interrupt' when the remotely executing program requires some user input
  • Have the execution page be fully contextual in terms of what is, and is not, permitted at any point

ASP.NET Core webapp
This was reasonably straightforward to put together and get to work. Things that did bite:
  • To work with AngularJS 2 RC2, the version of npm had to be a version different to the one shipped with VS 2015, meaning I had to fiddle with the external web tools to set the path
  • Initial restore of bower and npm packages took a long time, and there was little in the way of progress indication sometimes
  • Adding references to PCL's or .net standard assemblies often blew up the project.json file, resulting in duplicate Microsoft.NetCore.Platforms and Microsoft.NetCore.Targets dependencies that defeated package resolution. Editing project.json by hand cured this, but was not a pleasant experience
  • Running under IIS; what with creating an app pool running no managed code (IIS reverse proxying out to a Kestrel instance running in a different process) and then having to use the publish feature of VS to get it to work - I spent most of my time working with IIS express instead
  • Using a PCL as a reference in the web app causes all sorts of conniptions; VS 2015 still refuses to recognise the interfaces defined in a PCL of my own creation, and sometimes the build would fail. However, building using the .NET core command line tool (dotnet.exe) would cure this. Frustrating. 
AngularJS 2 
I never used Angular prior to v2. Never really had the opportunity, always seemed to be working in shops that used KnockoutJS (which is still a tidy library it must be said) or Ext JS (with its attendant steep learning curve).

Using it for this exercise was a pleasure. Sure, lots of set up issues, churn in the space, changes to routing discovered half way through, using Typescript (I know that is not mandatory!) - but all in all, positive.

There are a fair few components in the solution right now, but the key one is TestBedComponent, which in turn has two child components, LanguageComponent and ExecutionComponent - the first allowing the selection of a language to use for interpretation, with the languages being derived from calling an injected service, the second being responsible for the 'real' work:
  • Allowing the entry of an esoteric program
  • Using an injected service to request remote execution
  • Responding to interrupts from the remote execution, meaning user input is required - showing a text box and button to allow the entry of user input that is then sent via the service to the remote server
The TestBedComponent has this form:

 import { Component, EventEmitter, Input, Output, ViewChild } from "@angular/core";  
 import { LanguageComponent } from './language.component';  
 import { ExecutionComponent } from './execution.component';  
 @Component({  
   selector: "testbed",  
   template: `  
       <languageSelector (onLanguageChange)="languageChanged($event)"></languageSelector>  
       <execution></execution>      
   `,  
   directives: [LanguageComponent, ExecutionComponent]  
 })  
 export class TestBedComponent {  
   @ViewChild(ExecutionComponent)  
   private _executionComponent: ExecutionComponent;  
   currentLanguage: string;  
   languageChanged(arg) {  
     console.log('(Parent) --> Language changed to ' + arg);  
     console.log(this._executionComponent);  
     this._executionComponent.changeLanguage(arg);  
   }  
 }  

I'm just embedding the two main components in the template, and using a reference to the execution component to communicate a change in the selected language, which is handled by the LanguageComponent, which exposes an event emitter which the test bed component listens to.

There are other ways of doing this, such as using a shared service, but I wanted to experiment with as many different parts of Angular 2 as possible, rather than be a purist :-)

The language component uses an iterated Bootstrap row; it's (too) simple at the moment, but uses an ngFor to present a list of languages discovered after consulting a service, template excerpt as below:

 <div class="row">  
   <div class="col-xs-3" *ngFor="let language of languages">  
    <button class="btn btn-primary" (click)="languageChanged($event)">  
      {{language.Name}}  
    </button>  
   </div>  
 </div>  

The execution component is a little more interesting, having a more involved template, as below:

 <form (ngSubmit)="run()" #executionForm="ngForm">  
       <div class="row">  
         <div class="col-xs-12">  
           <h4>Source code</h4>  
         </div>  
         <div class="col-xs-12">  
           <textarea cols="80" rows="10" [(ngModel)]="sourceCode" style="min-width: 100%;"   
            name="sourceCode" required [disabled]="running"></textarea>  
         </div>  
       </div>   
       <p></p>  
       <div class="row">  
         <div class="col-xs-6">  
           <button type="submit" class="btn btn-primary" [disabled]="!executionForm.form.valid || running">  
            Run  
           </button>&nbsp;    
           <button type="button" class="btn btn-danger" (click)="cancel()" [disabled]="!running">  
            Cancel  
           </button>    
         </div>  
       </div>   
       <div class="row" *ngIf="inputRequired">  
         <div class="col-xs-12">  
           <h4>Input</h4>  
         </div>  
         <div class="col-xs-12">  
           <input [(ngModel)]="programInput" name="programInput" required/>  
           <button type="button" class="btn btn-primary" (click)="send()"   
             [disabled]="!executionForm.form.valid">  
           Send  
           </button>  
         </div>  
       </div>  
       </form>  
       <div class="row">  
         <div class="col-xs-12">  
           <h4>Output</h4>  
         </div>  
         <div class="col-xs-12">  
           <textarea cols="80" rows="10" [value]="programOutput" disabled style="min-width: 100%;"></textarea>  
         </div>  
       </div>  

As you can see, it uses a form, and a range of one and two way bindings, and a few ngIf's to control visibility depending on context.

The actual implementation of this component is also quite simple:
1:  export class ExecutionComponent {  
2:    language: string;  
3:    sourceCode: string;  
4:    programOutput = '';  
5:    programInput = '';  
6:    running = false;   
7:    inputRequired = false;  
8:    constructor(private _esolangService: EsolangService) {  
9:      console.log('built EC');  
10:    }  
11:    changeLanguage(lang) {  
12:      this.language = lang;  
13:      console.log(this.sourceCode);  
14:    }  
15:    run() {  
16:      console.log('Run! --> ' + this.sourceCode);  
17:      this.running = true;  
18:      this.programOutput = '';  
19:      this._esolangService.execute(  
20:        this.sourceCode,  
21:        {  
22:          next: m => this.programOutput += m,  
23:          complete: () => this.cancel()  
24:        },  
25:        () => this.inputRequired = true  
26:      );  
27:    }   
28:    send() {  
29:      console.log('Sending ' + this.programInput);  
30:      this._esolangService.send(this.programInput);  
31:      this.inputRequired = false;  
32:    }  
33:    cancel() {  
34:      this.running = this.inputRequired = false;  
35:      this._esolangService.close();  
36:    }   
37:  }  

Lines of interest:

  • 8 - EsoLangService is injected as a private member
  • 11 - target language is changed
  • 19-26 - the eso lang service is asked to execute the supplied source code. A NextObserver<any> is supplied as argument 2, and is hooked up internally within the service to a web sockets RxJs Subject (using https://github.com/afrad/angular2-websocket as a base). The third argument is a lambda that is called when the service receives a web socket message that indicates that user input is required. On receipt of this, inputRequired changes, which in turn affects this part of the template, displaying the user input text box and Send button:
<div class="row" *ngIf="inputRequired">

Screen shots
Just a few, with WARP as the target, executing a program that derives prime numbers from some user entered upper bound.

Initial page


Source entered

Execution started, but input required interrupt received

Execution complete










Saturday, June 4, 2016

Knockout Validation and ASP.NET MVC view model integration

I came across this particular issue a while ago, where I was using Knockout validation and had some validation annotated c# view models that were delivered by a REST API. I didn't have time on the project where I encountered this to solve it in an elegant fashion - so decided to do that in my spare time.

The problem to solve is to somehow have the validation attributes that have been applied to the C# view models applied in the same manner to view models created in the (Knockout JS based) client.

Doing this by hand is obviously clumsy and error prone, so instead the solution I now have:
  • Exposes Web API end points that can be queried by the client to gather meta data
  • Has a simple Javascript module that can interpret the response from a meta data serving endpoint call, applying Knockout validation directives (extensions) to a view model
The VS 2015 solution lives in GitHub.

A simple example follows - consider the C# view model below:

 public class SimpleViewModel {  
     [Required]  
     [StringLength(10)]  
     public string FirstName { get; set; }  
     [Required]  
     [StringLength(20)]  
     public string Surname { get; set; }  
     [Required(ErrorMessage = "You must indicate your DOB")]  
     [Range(1906, 2016)]  
     public int YearOfBirth { get; set; }  
     [RegularExpression(@"^[a-z]\d{3}$")]  
     public string Pin { get; set; }  
 }  

A web API method that can serve meta data on demand (security considerations ignored). It's all interface driven and pluggable, so not limited to the standard MVC data annotations or Knockout validation translation. Server side view model traversal is recursive and collection aware, so arbitrarily complex view models can be interrogated.


 public class DynamicValidationController : ApiController {  
     [HttpGet]  
     public dynamic MetadataFor(string typeName) {  
       return new ValidationMetadataGenerator()  
               .ExamineType(Type.GetType(typeName))  
               .Generate();  
     }  
 }  

And finally a very simple client use of the Javascript module. This example HTTP Get's a method that includes the validation meta data along with the view model in a wrapped type, but this need not be the case. The call to vmi.decorate, is the key one, applying as it does the relevant metadata to the ko mapped view model using standard Knockout validation directives.

 $.getJSON("/api/ViewModelServing/WrappedSimpleViewModel",   
          null,   
         function (response) {  
          var obj = ko.mapping.fromJS(response.Model);  
          vmi.decorate({  
            model: obj,  
            parsedMetadata: response.ValidationMetadata,  
            enableLogging: true,  
            insertedValidatedObservableName: 'validation'   
          });  
          ko.validation.init({ insertMessages: false });  
          ko.applyBindings(obj, $('#koContainer')[0]);  
       }  
 );  

The object passed to decorate or decorateAsync also allows you to supply a property name (insertedValidatedObservableName) that will be set with a validatedObservable created during metadata interpretation - this is a convenience, meaning that after the example code above executes, calling obj.validation.isValid() will return true or false correctly for the entire view model.

Metadata on the wire looks like this:


Saturday, November 7, 2015

Quorum implementation

Having always been interested in distributed consensus/quorum/master slave systems, I decided to implement a form of quorum software (C# of course). It helped me solve an issue I had with a web farm deployment where a Windows service needed to execute on at least/most one machine (the 'master') at any time.

As the machines could be brought in and out of service at any time, the master had to be an elected or agreed active machine. So I wrote Quorum to avoid having a single point of failure.

It's a familiar take on replicated state machines, that does not aspire to the giddy heights of Paxos or Raft. But for all that, it is simple and thus far, reliable (enough :-).

Currently hosted on GitHub, here.

Has a simple MVC web app for quorum viewing, as below:


Tuesday, August 18, 2015

NHooked - a web hook provider framework

Always in need of a side project, I thought I'd create a web hook provider framework - a WIP for sure, but showing promise. I've hosted it on GitHub - repo here.

README content:

nhooked (en-hooked) is a C# framework designed to allow a flexible web hook provider to be created. By flexible, I mean:

  • Reliable
  • Scalable
  • Simple

There are a great number of 'how to's', blogs and the like which describe how to consume web hooks, but few that indicate how to create an implementation that can serve as a web hook provider i.e the source of the events that web hook consumers await.
nhooked tries to provide such a framework, making it as pluggable as possible and provding some base implementations.

Thursday, July 30, 2015

IIS 8.5 awful performance on first request to MVC site

My home dev machine is (currently) running Windows 8.1, with IIS 8.5 therefore, has 16GB RAM, a well proportioned SSD, 4 cores@3.5Ghz. When I develop my MVC applications, I normally run an MVC app itself as a web site under IIS, with its own app pool - mainly because, although IIS express is good, I don't find it good enough for my purposes.

Everything has been going swimmingly. After building any site, response to the first request has been < 5 seconds; sure, some compilation is going on, and I'm in full debug mode, but these times do not matter too much in the grand scheme of things.

Except when it spikes, and remains spiked.

This happened a few days ago. The site I was currently extending ballooned its first request response time from about 4 seconds to 2 minutes and finally to 3 minutes in next to no time at all. Now, I like the opportunity to think as much as the next person, but 3 minutes is beyond a joke.

Cue a Google search regarding such IIS performance issues. The list went on an on as to culprits; perhaps an unreachable database connection, slow DNS lookup, running as 32 bit (!),  all sorts of variations on IIS app pool settings (auto start, suspend and so on), secret Microsoft CRL queries - you get the idea.

A couple of the less whacky ones I tried, to no avail. Then I thought I'd give DebugDiag a go, so downloaded, installed, created some rules, captured some dumps. Nothing.

Back to basics seemed to be in order. So I installed procmon, recycled the app pool in question, set procmon going, filtering on just w3wp.exe.

I then issue the first request, and the response is, as expected, glacial. But this is where a blunt instrument like procmon sometimes wins out - because it highlighted immediately that w3wp.exe was issuing hundreds of thousands of requests to write files. Examining one of the files told me immediately that this was my fault - it was an assembly binding log file, as produced by the Fusion sub system. Fully 2 minutes 50+ was creating log files.

I'd forced Fusion logging on some months before, to debug an obscure issue I had with loading AForge.NET assemblies. So, open regedit, navigate to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion, and set ForceLog to 0.

Recycle app pool, issue first request. 4 second response time again!