Wednesday 25 December 2019

Tour Triangle

Warning: Please, notice that I consider France as my second country and I love it, so don't take the beginning of this post as an attack against France, I just criticise a common attitude in one part of the French population that, as someone that loves architecture, rather bothers me, and that for someone that has lived most of his life in a city (Xixón) where 15 stories buildings are just everywhere and people do not particularly complain about them, is pretty difficult to understand (notice that it goes far beyond the grand-ensemble trauma, and anyway, it's not HLM buildings that cause troubles, it's some of the people living there who do it.

The irrational hatred for High Rise Buildings could almost be considered as an essential part of the modern French identity. It's not that everyone hates them, indeed I guess part of the population does not care too much about them, but the percentage of people that vehemently hates any building higher than 50 meters and that is willing to create collectives, flood the media with lies about the "evils" of such buildings, go to court or whatever... in order to stop its construction is absolutely perplexing. Probably Marseille and Lyon are the 2 cities less affected by this redneck attitude, but unfortunately, Toulouse is right on the other side of the spectrum. This is the city where these collectives of "rednecks against the modern urban landscape" has an uncomprehensible power, furthermore, they even redefine the definition of high-rise, for these idiots which main interest in life is to hinder the development of the city, any building beyond 30 meters is a skyscrapper....

Things in Paris have been looking better in these last years. In 2018 Paris intra-muros saw the completion of the first sky-scrapper built in this century, the new TGI (notice of course that La Defense, that continues to thrive with interesting developments, is outside the limits of the "ville de Paris"), and the "Tours Duo" by Jean Nouvelle are well under construction (and there are plans for another skyscrapper in this same area). Furthermore, and this is what motivates this post, I've read recently that finally, the Tour Triangle has managed to overcome the last 2 (of many) appeals presented by some redneck association, and is now confirmed to become a new addition to the Parisian sky line. The images in in this article are just amazing, it looks massively beautiful!

Sunday 15 December 2019

IQueryable and Default Interface Methods

The discussion in the .Net world as to whether it's OK to have repositories returning IQueryable rather than IEnumerable has been rather present all these years. The common consensus is that it's not, and your repositories should not return an IQueryable. There are multiple reasons for this, but from an architecture point, probably this is one of the best I've read.

The point is that using IQueryable, you're asking for a query builder and not for a model. A query builder specifies how the query should be, how to get the data. Then why are we using a repository? Isn't the repo's job to know how to get the thing we want? We're using the repository because we want to specify what to get, not how to get it.

This goes along the idea of repositories having methods for "fat queries", so that the repository itself does the filtering, rather than returning a "collection" on which you apply filters. A similar approach is combining Repository and Specification pattern, your repository no longer have specific methods for each fat query, but you pass it over a specification with the query itself and it's the repository who performs the query.

While I agree with all the above, the idea of returning an IEnumerable and filtering it later, does not always seem like such a sin to me, after all we use Linq to Objects all the time. The big problem with returning an IEnumerable is that we would lose all the magic of IQueryable transforming our filters into a query and running it for us. The Linq methods for IEnumerable and IQueryable have been implemented as extension methods, and as we know this is a compiler trick, and method override and runtime resolution do not apply. If my IPersonRepository.GetItems returns and IEnumerable, my PersonSqlServerRepository.GetItems has to return an IEnumerable also in its signature (as C# lacks of Method return type covariance). We can respect that signature but return an IQueryable anyway, I mean:

IEnumerable GetItems()
{
 ...
 return dbContext.Persons; //returns and IQueryable
}

But the problem is that then, when doing myPersonsRepository.GetItems().Where(.....); the C# compiler would set a call to System.Linq.Enumerable.Where (rather than System.Linq.Queryable.Where), so we would be retrieving all the items from the Database, and then performing the filtering.

Now that C# 8 has added Default Interface Methods, if all the linq methods where added as default methods to IEnumerable and IQueryable the whole thing would change. As the method resolution would be done at runtime, calling Where in the above case would end up going to the IQueryable.Where, and generating the consequent sql query. This would be really sweet, but I've not heard so far about any plans of "copy-pasting" (you can not just move them due to backwards compatibility) the methods in System.Linq.Queryable into IQueryable as default interface methods.

Wednesday 4 December 2019

Promise.all with a Limit

A few months ago I wrote a post about how to limit the number of async operations that we run in parallel in JavaScript. Last week I came up with something related, but a bit different. What if we want to run n async operations and wait for all of them to complete, but we want to limit how many of them we run in parallel. A good example of this is if we want to do several http requests and combine their results, but we don't want to flood the server with all the requests at the same time (indeed browsers manage this themselves limiting how many requests to the same server they open in parallel, so we won't be overloading the server, but at JavaScript level the requests are already launched, and the timeout starts to count...). Waiting for all the async operations to complete is what we get with Promise.all, but it does not provide a limit option.

Well, the idea seems simple to implement, here it goes my take on it:

class PromiseAllWithLimit{
    //tasks: Array of functions that return a Promise
    constructor(tasks, maxItems){
        this.allTasks = tasks;
        this.maxItems = maxItems;
        this.taskResults = [];
        this.nextTaskId = 0;
        this.resolveAll = null; //points to the resolve function to invoke when all tasks are complete
        this.completedCounter = 0;
    }

    //tasks: Array of functions that return a Promise
    //returns a Promise that gets resolved when all tasks are done
    run(){
         while(this.nextTaskId < this.maxItems){
            this._runNextTask();
        }
        return new Promise((res) => this.resolveAll = res);
    }

    _runNextTask(){
        //we need this var to get it trapped in the closure to run in the task.then()
        let curTaskId = this.nextTaskId
        let nextTask = this.allTasks[this.nextTaskId];
        this.nextTaskId++;
        nextTask().then((result) => {
            this.completedCounter++;
            this.taskResults[curTaskId] = result;
            if (this.nextTaskId < this.allTasks.length){
                this._runNextTask();
            }
            else{
                //no more tasks to launch
                //if all tasks are complete, complete the All Promise
                if(this.completedCounter === this.allTasks.length){
                    this.resolveAll(this.taskResults);
                }
            }
        });
    }
}

That we can use like this:

function getRandomInt(max) {
    return Math.floor(Math.random() * Math.floor(max));
  }

  //returns Promise
function getPost(postId){
    console.log("getPost " + postId + " started");
    return new Promise(res => {
        setTimeout(() => {
            console.log("---> getPost " + postId + " finishing");
            res(`${postId} - content`)
        }, 2000 * (1 + getRandomInt(2)));
    });
}

(async () => {
    let tasks = [];
    for (let i=0; i<10; i++){
        tasks.push(() => getPost("postId_" + i));
    }
    let results = await new PromiseAllWithLimit(tasks, 5).run();
    console.log("all tasks are complete");
    console.log(results.join("\n"));
})();

There's an important point to notice. While Promise.all receives an array of promises, our PromiseAllWithLimit receives an array of functions that return a Promise. I'm calling these functions "tasks" in my code (that have little to do with .Net Tasks), let's think of them as "lazy-promises". I can not directly pass Promises, cause that would mean that we are already running all the functions, that is just what we want to limit. We return a Promise that will get resolved once all the "tasks" are complete (so we store its resolve "callback" for later invokation).

I've uploaded the code to this gist.